From 105517c56112aa2170c2b9903640ad2aaf870891 Mon Sep 17 00:00:00 2001 From: lewiatan Date: Fri, 16 Feb 2018 22:02:00 +0100 Subject: [PATCH 001/222] support rating tag from EXIF/XMP --- rtengine/imagedata.cc | 17 ++++++++++++++++- rtengine/imagedata.h | 5 ++++- rtengine/rtengine.h | 2 ++ rtexif/rtexif.cc | 6 ++++++ rtgui/cacheimagedata.cc | 2 +- rtgui/cacheimagedata.h | 2 ++ rtgui/thumbnail.cc | 1 + rtgui/thumbnail.h | 5 ++++- 8 files changed, 36 insertions(+), 4 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4e38c612a..a84d6423c 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -71,7 +71,7 @@ FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname, std::uniqu FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) : frameRootDir(frameRootDir_), iptc(nullptr), time(), timeStamp(), iso_speed(0), aperture(0.), focal_len(0.), focal_len35mm(0.), focus_dist(0.f), - shutter(0.), expcomp(0.), make("Unknown"), model("Unknown"), orientation("Unknown"), lens("Unknown"), + shutter(0.), expcomp(0.), make("Unknown"), model("Unknown"), orientation("Unknown"), rating(0), lens("Unknown"), sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), isHDR(false) { memset (&time, 0, sizeof(time)); @@ -97,6 +97,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* serial.clear(); orientation.clear(); lens.clear(); + rating = 0; tag = newFrameRootDir->findTag("Make"); if (!tag) { @@ -187,6 +188,11 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* orientation = tag->valueToString (); } + tag = newFrameRootDir->findTagUpward("Rating"); + if (tag) { + rating = tag->toInt(); + } + tag = newFrameRootDir->findTagUpward("MakerNote"); rtexif::TagDirectory* mnote = nullptr; if (tag) { @@ -876,6 +882,11 @@ std::string FrameData::getOrientation () const return orientation; } +int FrameData::getRating () const +{ + return rating; +} + void FramesData::setDCRawFrameCount (unsigned int frameCount) @@ -1168,6 +1179,10 @@ std::string FramesData::getOrientation(unsigned int frame) const } ); } +int FramesData::getRating (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0 : frames.at(frame)->getRating (); +} //------inherited functions--------------// diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index c6889e653..b65049e2d 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -49,6 +49,7 @@ protected: std::string make, model, serial; std::string orientation; std::string lens; + int rating; IIOSampleFormat sampleFormat; // each frame has the knowledge of "being an" @@ -84,6 +85,7 @@ public: std::string getLens () const; std::string getSerialNumber () const; std::string getOrientation () const; + int getRating () const; }; class FramesData : public FramesMetaData { @@ -125,7 +127,8 @@ public: std::string getModel (unsigned int frame = 0) const override; std::string getLens (unsigned int frame = 0) const override; std::string getSerialNumber (unsigned int frame = 0) const; - std::string getOrientation (unsigned int frame = 0) const override; + std::string getOrientation (unsigned int frame = 0) const; + int getRating (unsigned int frame = 0) const override; }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6264d43ae..8df6e9ef5 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -133,6 +133,8 @@ public: virtual std::string getLens (unsigned int frame = 0) const = 0; /** @return the orientation of the image */ virtual std::string getOrientation (unsigned int frame = 0) const = 0; + /** @return the rating of the image */ + virtual int getRating (unsigned int frame = 0) const = 0; /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */ virtual bool getPixelShift () const = 0; diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 571fd4e6b..312cbd1c7 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3037,6 +3037,12 @@ void ExifManager::parse (bool isRaw, bool skipIgnored) } } + if (!root->getTag ("Rating")) { + Tag *t = new Tag (root, root->getAttrib("Rating")); + t->initInt (0, LONG); + root->addTag (t); + } + // --- detecting image root IFD based on SubFileType, or if not provided, on PhotometricInterpretation bool frameRootDetected = false; diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 35aeb6c91..1c4ac83ea 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -27,7 +27,7 @@ CacheImageData::CacheImageData () : md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false), timeValid(false), year(0), month(0), day(0), hour(0), min(0), sec(0), exifValid(false), frameCount(1), - fnumber(0.0), shutter(0.0), focalLen(0.0), focalLen35mm(0.0), focusDist(0.f), iso(0), isHDR (false), + fnumber(0.0), shutter(0.0), focalLen(0.0), focalLen35mm(0.0), focusDist(0.f), iso(0), rating(0), isHDR (false), isPixelShift (false), sensortype(rtengine::ST_NONE), sampleFormat(rtengine::IIOSF_UNKNOWN), redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), rotate(0), thumbImgType(0) { diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index d3aea803b..9de9d186f 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -54,6 +54,7 @@ public: double focalLen, focalLen35mm; float focusDist; unsigned iso; + int rating; bool isHDR; bool isPixelShift; int sensortype; @@ -108,6 +109,7 @@ public: std::string getModel (unsigned int frame = 0) const override { return camModel; } std::string getLens (unsigned int frame = 0) const override { return lens; } std::string getOrientation (unsigned int frame = 0) const override { return ""; } // TODO + int getRating (unsigned int frame = 0) const override { return rating; } // FIXME-piotr : missing rating bool getPixelShift () const override { return isPixelShift; } bool getHDR (unsigned int frame = 0) const override { return isHDR; } std::string getImageType (unsigned int frame) const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 757708002..e0509f457 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -813,6 +813,7 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, std::unique_ptrgetLens(); cfs.camMake = idata->getMake(); cfs.camModel = idata->getModel(); + cfs.rating = idata->getRating(); if (idata->getOrientation() == "Rotate 90 CW") { deg = 90; diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 0bcdd470a..2c0cba2b0 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -164,7 +164,10 @@ public: return cfs.md5; } - int getRank () const; + int getRank () const + { + return cfs.rating; + } void setRank (int rank); int getColorLabel () const; From 7512093c205090608c316cd3e866af9feaa0ce66 Mon Sep 17 00:00:00 2001 From: lewiatan Date: Sat, 17 Feb 2018 22:08:25 +0100 Subject: [PATCH 002/222] support rating tag from EXIF/XMP- fixes --- rtgui/cacheimagedata.cc | 5 +++++ rtgui/thumbnail.h | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 1c4ac83ea..47318990d 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -66,6 +66,10 @@ int CacheImageData::load (const Glib::ustring& fname) rankOld = keyFile.get_integer ("General", "Rank"); } + if (keyFile.has_key ("General", "Rating")) { + rating = keyFile.get_integer ("General", "Rating"); + } + if (keyFile.has_key ("General", "InTrash")) { inTrashOld = keyFile.get_boolean ("General", "InTrash"); } @@ -227,6 +231,7 @@ int CacheImageData::save (const Glib::ustring& fname) keyFile.set_boolean ("General", "Supported", supported); keyFile.set_integer ("General", "Format", format); keyFile.set_boolean ("General", "RecentlySaved", recentlySaved); + keyFile.set_integer ("General", "Rating", rating); // remove the old implementation of Rank and InTrash from cache if (keyFile.has_key ("General", "Rank")) { diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 2c0cba2b0..75b1ecdd5 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -168,7 +168,13 @@ public: { return cfs.rating; } - void setRank (int rank); + void setRank (int rank) + { + if (cfs.rating != rank) { + cfs.rating = rank; + } + pparamsValid = true; // FIXME-piotr Is this the right way to refresh the cache? Probably not since pparams and cache should be 2 different things + } int getColorLabel () const; void setColorLabel (int colorlabel); From 820024972aaf9e3dc92e385bd13da2039a1a826a Mon Sep 17 00:00:00 2001 From: Eric Jiang Date: Thu, 16 May 2019 17:09:46 -0700 Subject: [PATCH 003/222] Use rating from EXIF/XMP where available --- rtengine/imagedata.cc | 10 +++++++++- rtengine/imagedata.h | 2 +- rtengine/procparams.cc | 5 ++++- rtgui/thumbnail.cc | 11 +++++++++-- rtgui/thumbnail.h | 13 ++----------- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index a84d6423c..b9720ec8a 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -188,10 +188,18 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* orientation = tag->valueToString (); } + // Look for Rating metadata in the following order: + // 1. EXIF + // 2. XMP + // 3. pp3 sidecar file tag = newFrameRootDir->findTagUpward("Rating"); - if (tag) { + if (tag && tag->toInt() != 0) { rating = tag->toInt(); } + char sXMPRating[64]; + if (newFrameRootDir->getXMPTagValue("xmp:Rating", sXMPRating)) { + rating = atoi(sXMPRating); + } tag = newFrameRootDir->findTagUpward("MakerNote"); rtexif::TagDirectory* mnote = nullptr; diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index b65049e2d..097a5cc80 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -48,8 +48,8 @@ protected: double expcomp; std::string make, model, serial; std::string orientation; - std::string lens; int rating; + std::string lens; IIOSampleFormat sampleFormat; // each frame has the knowledge of "being an" diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 6d914bb27..f492e5900 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2832,7 +2832,10 @@ void ProcParams::setDefaults() exif.clear(); iptc.clear(); - rank = 0; + // -1 means that there's no pp3 data with rank yet. In this case, the + // embedded Rating metadata should take precedence. -1 should never be + // written to pp3 on disk. + rank = -1; colorlabel = 0; inTrash = false; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index e0509f457..39f4ca093 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -1006,15 +1006,22 @@ void Thumbnail::setFileName (const Glib::ustring &fn) int Thumbnail::getRank () const { - return pparams->rank; + // prefer the user-set rank over the embedded Rating + // pparams->rank == -1 means that there is no saved rank yet, so we should + // next look for the embedded Rating metadata. + if (pparams->rank != -1) { + return pparams->rank; + } else { + return cfs.rating; + } } void Thumbnail::setRank (int rank) { if (pparams->rank != rank) { pparams->rank = rank; - pparamsValid = true; } + pparamsValid = true; } int Thumbnail::getColorLabel () const diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 75b1ecdd5..0bcdd470a 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -164,17 +164,8 @@ public: return cfs.md5; } - int getRank () const - { - return cfs.rating; - } - void setRank (int rank) - { - if (cfs.rating != rank) { - cfs.rating = rank; - } - pparamsValid = true; // FIXME-piotr Is this the right way to refresh the cache? Probably not since pparams and cache should be 2 different things - } + int getRank () const; + void setRank (int rank); int getColorLabel () const; void setColorLabel (int colorlabel); From a25655cafdd5f96cb11c4f0012ff2304095c0192 Mon Sep 17 00:00:00 2001 From: Eric Jiang Date: Thu, 16 May 2019 19:37:27 -0700 Subject: [PATCH 004/222] Check that metadata rating is between 0 and 5 Does not handle Rating=-1 meaning Rejected yet. --- rtengine/imagedata.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index b9720ec8a..26fe80f03 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -200,6 +200,16 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* if (newFrameRootDir->getXMPTagValue("xmp:Rating", sXMPRating)) { rating = atoi(sXMPRating); } + // guard against out-of-range values + if (rating > 5) { + rating = 5; + } + // Currently, Rating=-1 is not supported. A value of -1 should mean + // "Rejected" according to the specification. Maybe in the future, Rating=-1 + // sets InTrash=true? + if (rating < 0) { + rating = 0; + } tag = newFrameRootDir->findTagUpward("MakerNote"); rtexif::TagDirectory* mnote = nullptr; From 9df80089491f918df4b07ea8f82c01ed5a04b282 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 4 Jun 2019 21:31:03 +0200 Subject: [PATCH 005/222] Film negative processing: first usable version. Only supports bayer raw files, thumbnails don't work Added performance improvements suggested by heckflosse. Lowered median sampling step from 7 to 5 since calculation is now much faster. Added support for Fuji X-Trans raw files. Applied SSE2 patch provided by @heckflosse, improves performance in main processing loop. Moved film negative processing stuff in its own compilation unit. Code cleanup: removed redundant omp directives. Added check for dead pixels, going above threshold after inversion. ST_BAYER only for now. Reverted leftover hack in cropwindow.cc --- .gitignore | 1 + rtdata/languages/Catala | 9 + rtdata/languages/Chinese (Simplified) | 9 + rtdata/languages/Deutsch | 13 + rtdata/languages/English (UK) | 9 + rtdata/languages/English (US) | 9 + rtdata/languages/Italiano | 9 + rtdata/languages/Magyar | 9 + rtdata/languages/Nederlands | 9 + rtdata/languages/Polish | 9 + rtdata/languages/Portugues (Brasil) | 9 + rtdata/languages/Russian | 9 + rtdata/languages/Serbian (Cyrilic Characters) | 9 + rtdata/languages/Swedish | 9 + rtdata/languages/default | 9 + rtengine/CMakeLists.txt | 1 + rtengine/filmnegativeproc.cc | 321 ++++++++++++++++++ rtengine/imagesource.h | 3 + rtengine/improccoordinator.cc | 31 ++ rtengine/improccoordinator.h | 1 + rtengine/procparams.cc | 41 +++ rtengine/procparams.h | 19 ++ rtengine/rawimagesource.h | 4 + rtengine/rtengine.h | 1 + rtengine/simpleprocess.cc | 5 + rtgui/CMakeLists.txt | 1 + rtgui/filmnegative.cc | 320 +++++++++++++++++ rtgui/filmnegative.h | 91 +++++ rtgui/paramsedited.cc | 29 ++ rtgui/paramsedited.h | 10 + rtgui/toolpanelcoord.cc | 18 +- rtgui/toolpanelcoord.h | 8 +- 32 files changed, 1033 insertions(+), 2 deletions(-) create mode 100644 rtengine/filmnegativeproc.cc create mode 100644 rtgui/filmnegative.cc create mode 100644 rtgui/filmnegative.h diff --git a/.gitignore b/.gitignore index 21ebf986a..fc65c877c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .project .settings .directory +.vscode CMakeCache.txt CMakeFiles diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 73970424b..f9bcf25b2 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1314,6 +1314,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1851,6 +1853,13 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index fde2aab1b..78807ddd4 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1361,6 +1361,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1798,6 +1800,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 7f562d51c..fd2d0d07a 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -2360,3 +2360,16 @@ ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen.\nTaste: Alt + f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_GREEN;Green exponent +!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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index cda91f29a..24bffbb0a 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -838,6 +838,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1665,6 +1667,13 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 9affa9444..5dad9591a 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -748,6 +748,8 @@ !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1636,6 +1638,13 @@ !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index bedba34f6..98d86b69d 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -1539,6 +1539,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1903,6 +1905,13 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index d1947b893..7aa5b30c3 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1248,6 +1248,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1816,6 +1818,13 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index b8b30e64c..508f06384 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -2036,6 +2036,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -2230,6 +2232,13 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colors !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. +!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_GREEN;Green exponent +!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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_CUSTOM;Custom !TP_ICM_WORKING_TRC_GAMMA;Gamma diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 05f099ea6..e35f583ff 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1621,6 +1621,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1929,6 +1931,13 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. !TP_EXPOSURE_TCMODE_LUMINANCE;Luminance !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual +!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_GREEN;Green exponent +!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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index da9a620df..0bafe632f 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -2258,6 +2258,8 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !FILEBROWSER_EMPTYTRASHHINT;Permanently delete all files in trash. !HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset !HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !MAIN_FRAME_PLACES_DEL;Remove !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. @@ -2271,6 +2273,13 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_COLORTONING_LABREGION_OFFSET;Offset !TP_COLORTONING_LABREGION_POWER;Power !TP_CROP_PPI;PPI +!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_GREEN;Green exponent +!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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index c2b43033e..9e43f1098 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -1706,6 +1706,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type @@ -1974,6 +1976,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_DISTORTION_AUTO_TIP;Automatically corrects lens distortion in raw files by matching it against the embedded JPEG image if one exists and has had its lens disortion auto-corrected by the camera. !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 21a34119a..ce1452821 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1514,6 +1514,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1902,6 +1904,13 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !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_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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 14dc4069f..cd3b9b3fc 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -1863,6 +1863,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -2117,6 +2119,13 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colors !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. +!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_GREEN;Green exponent +!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_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. diff --git a/rtdata/languages/default b/rtdata/languages/default index 5ea726218..e6a546a7e 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -747,6 +747,8 @@ HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed HISTORY_MSG_HISTMATCHING;Auto-matched tone curve HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1635,6 +1637,13 @@ TP_EXPOSURE_TCMODE_STANDARD;Standard 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_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_PICK;Pick white and black spots +TP_FILMNEGATIVE_RED;Red exponent +TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots TP_FILMSIMULATION_LABEL;Film Simulation TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index a1037f5a3..dfa843fd0 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -132,6 +132,7 @@ set(RTENGINESOURCEFILES ipdehaze.cc iplabregions.cc lj92.c + filmnegativeproc.cc ) if(LENSFUN_HAS_LOAD_DIRECTORY) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc new file mode 100644 index 000000000..dba623ab4 --- /dev/null +++ b/rtengine/filmnegativeproc.cc @@ -0,0 +1,321 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#include + +#include "rtengine.h" +#include "rawimagesource.h" +#include "mytime.h" +#include "procparams.h" +#ifdef _OPENMP +#include +#endif +#include "opthelper.h" +#include "rt_algo.h" + +namespace rtengine +{ + +extern const Settings* settings; + +bool RawImageSource::channelsAvg(Coord spotPos, int spotSize, float avgs[3], const FilmNegativeParams ¶ms) +{ + avgs[0] = avgs[1] = avgs[2] = 0.f; // Channel averages + + if(ri->getSensorType() != ST_BAYER && ri->getSensorType() != ST_FUJI_XTRANS) + return false; + + if (settings->verbose) + printf("Spot coord: x=%d y=%d\n", spotPos.x, spotPos.y); + + int x1 = spotPos.x - spotSize / 2; + int x2 = spotPos.x + spotSize / 2; + int y1 = spotPos.y - spotSize / 2; + int y2 = spotPos.y + spotSize / 2; + + if(x1<0 || x2>W || y1<0 || y2>H) + return false; // Spot goes outside bounds, bail out. + + int pxCount[3] = {0}; // Per-channel sample counts + for(int c=spotPos.x-spotSize; cgetSensorType() == ST_BAYER) ? FC(r,c) : ri->XTRANSFC(r,c); + + pxCount[ch]++; + // If film negative is currently enabled, undo the effect by elevating to 1/exp, + // in order to sample the original, linear value + if(params.enabled) + avgs[ch] += powf(rawData[r][c], -1 / (ch==0 ? params.redExp : ch==1 ? params.greenExp : params.blueExp)); + else + avgs[ch] += rawData[r][c]; + } + } + + for(int ch=0; ch<3; ch++) + avgs[ch] = avgs[ch] / (pxCount[ch]); + + return true; +} + +// Calculate logarithms in arbitrary base +float logBase(float base, float num) { + return log(num) / log(base); +} + +bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, float newExps[3]) +{ + float clearVals[3], denseVals[3]; + + newExps[0] = currentParams.redExp; + newExps[1] = currentParams.greenExp; + newExps[2] = currentParams.blueExp; + + int spotSize = 32; // TODO : make this confugurable ? + Coord spot; + // Sample first spot + transformPosition (spotA.x, spotA.y, tran, spot.x, spot.y); + if(!channelsAvg(spot, spotSize, clearVals, currentParams)) + return false; + + // Sample second spot + transformPosition (spotB.x, spotB.y, tran, spot.x, spot.y); + if(!channelsAvg(spot, spotSize, denseVals, currentParams)) + return false; + + // Detect which one is the dense spot, based on green channel + if(clearVals[1] < denseVals[1]) + std::swap(clearVals, denseVals); + + if (settings->verbose) { + printf("Clear film values: R=%f G=%f B=%f\n", clearVals[0], clearVals[1], clearVals[2]); + printf("Dense film values: R=%f G=%f B=%f\n", denseVals[0], denseVals[1], denseVals[2]); + } + + float denseGreenRatio = clearVals[1] / denseVals[1]; + + // Calculate exponents for each channel, based on the ratio between the bright and dark values, + // compared to the ratio in the reference channel (green) + for(int ch=0; ch<3; ch++) + if(ch==1) + newExps[ch] = 1.f; // Green is the reference channel + else + newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 3.f); + + if (settings->verbose) + printf("New exponents: R=%f G=%f B=%f\n", newExps[0], newExps[1], newExps[2]); + + return true; +} + +void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams ¶ms) +{ + if(!params.enabled) + return; + + float exps[3] = { (float)params.redExp, (float)params.greenExp, (float)params.blueExp }; + + MyTime t1, t2, t3,t4, t5, t6; + t1.set(); + + if(ri->getSensorType() == ST_BAYER) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 0; row < H; row ++) { + int col = 0; + // Exponents are expressed as positive in the parameters, so negate them in order + // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. + const float exps0 = -exps[FC(row, col)]; + const float exps1 = -exps[FC(row, col + 1)]; +#ifdef __SSE2__ + const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1); + const vfloat onev = F2V(1.f); + for (; col < W - 3; col+=4) { + STVFU(rawData[row][col], pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv)); + } +#endif // __SSE2__ + for (; col < W - 1; col+=2) { + rawData[row][col] = pow_F(max(rawData[row][col], 1.f), exps0); + rawData[row][col + 1] = pow_F(max(rawData[row][col + 1], 1.f), exps1); + } + if (col < W) { + rawData[row][col] = pow_F(max(rawData[row][col], 1.f), exps0); + } + } + } else if(ri->getSensorType() == ST_FUJI_XTRANS) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 0; row < H; row ++) { + int col = 0; + // Exponents are expressed as positive in the parameters, so negate them in order + // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. + const float expsc[6] = {-exps[ri->XTRANSFC(row, 0)], -exps[ri->XTRANSFC(row, 1)], -exps[ri->XTRANSFC(row, 2)], -exps[ri->XTRANSFC(row, 3)], -exps[ri->XTRANSFC(row, 4)], -exps[ri->XTRANSFC(row, 5)]}; +#ifdef __SSE2__ + const vfloat expsv0 = _mm_setr_ps(expsc[0], expsc[1], expsc[2], expsc[3]); + const vfloat expsv1 = _mm_setr_ps(expsc[4], expsc[5], expsc[0], expsc[1]); + const vfloat expsv2 = _mm_setr_ps(expsc[2], expsc[3], expsc[4], expsc[5]); + const vfloat onev = F2V(1.f); + for (; col < W - 11; col+=12) { + STVFU(rawData[row][col], pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0)); + STVFU(rawData[row][col + 4], pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1)); + STVFU(rawData[row][col + 8], pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2)); + } +#endif // __SSE2__ + for (; col < W - 5; col+=6) { + for (int c = 0; c < 6; ++c) { + rawData[row][col + c] = pow_F(max(rawData[row][col + c], 1.f), expsc[c]); + } + } + for (int c = 0; col < W; col++, c++) { + rawData[row][col + c] = pow_F(max(rawData[row][col + c], 1.f), expsc[c]); + } + } + } + + + t2.set(); + if (settings->verbose) + printf("Pow loop time us: %d\n", t2.etime(t1)); + + // Channel vectors to calculate medians + std::vector cvs[3] = { + std::vector(), + std::vector(), + std::vector() + }; + + // Sample one every 5 pixels, and push the value in the appropriate channel vector. + // Chose an odd step, not 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) { + int c = FC(row, col); // three colors, 0=R, 1=G, 2=B + cvs[c].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) { + int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B + cvs[c].push_back(rawData[row][col]); + } + } + } + + const float MAX_OUT_VALUE = 65000.f; + + t3.set(); + if (settings->verbose) + printf("Median vector fill loop time us: %d\n", t3.etime(t2)); + + float medians[3]; // Channel median values + float mults[3] = { 1.f }; // Channel normalization multipliers + + for (int c=0; c<3; c++) { + // Find median values for each channel using a histogram search function + findMinMaxPercentile(&cvs[c][0], cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); + // Determine the channel multipler so that N times the median becomes 65k. This clips away + // the values in the dark border surrounding the negative (due to the film holder, for example), + // the reciprocal of which have blown up to stellar values. + mults[c] = MAX_OUT_VALUE / (medians[c] * 24); + } + + + t4.set(); + if (settings->verbose) { + printf("Sample count : %lu, %lu, %lu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); + printf("Medians : %f %f %f\n", medians[0], medians[1], medians[2] ); + printf("Computed multipliers : %f %f %f\n", mults[0], mults[1], mults[2] ); + printf("Median calc time us: %d\n", t4.etime(t3)); + } + + + if(ri->getSensorType() == ST_BAYER) { + +#ifdef _OPENMP + #pragma omp for nowait +#endif + for (int row = 0; row < H; row ++) { + for (int col = 0; col < W; col++) { + int c = FC(row, col); // three colors, 0=R, 1=G, 2=B + // Apply the multipliers + rawData[row][col] *= mults[c]; + } + } + + } else if(ri->getSensorType() == ST_FUJI_XTRANS) { + +#ifdef _OPENMP + #pragma omp for nowait +#endif + for (int row = 0; row < H; row ++) { + for (int col = 0; col < W; col++) { + int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B + // Apply the multipliers + rawData[row][col] *= mults[c]; + } + } + + } + + + t5.set(); + if (settings->verbose) + printf("Mult loop time us: %d\n", t5.etime(t4)); + + + PixelsMap bitmapBads(W, H); + + int totBP = 0; // Hold count of bad pixels to correct + + if(ri->getSensorType() == ST_BAYER) { + + +#ifdef _OPENMP + #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) +#endif + + for(int i = 0; i < H; i++) + for(int j = 0; j < W; j++) { + if (rawData[i][j] >= MAX_OUT_VALUE) { + bitmapBads.set(j, i); + totBP++; + } + } + + if (totBP > 0) { + interpolateBadPixelsBayer( bitmapBads, rawData ); + } + + } else if(ri->getSensorType() == ST_FUJI_XTRANS) { + + // TODO + + } + + t6.set(); + if (settings->verbose) { + printf("Bad pixels count: %d\n", totBP); + printf("Bad pixels interpolation time us: %d\n", t6.etime(t5)); + } +} + +} \ No newline at end of file diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index a18cca9d7..e3321b599 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -43,6 +43,7 @@ struct LensProfParams; struct RAWParams; struct RetinexParams; struct ToneCurveParams; +struct FilmNegativeParams; } @@ -77,6 +78,8 @@ public: ~ImageSource () override {} virtual int load (const Glib::ustring &fname) = 0; virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {}; + virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) {}; + virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, float newExps[3]) { return false; }; virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) {}; virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 01f9892bf..2d0d490ad 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -277,6 +277,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw); highDetailPreprocessComputed = highDetailNeeded; + + // After preprocess, run film negative processing if enabled + if((todo & M_RAW) && (imgsrc->getSensorType() == ST_BAYER || imgsrc->getSensorType() == ST_FUJI_XTRANS) && params->filmNegative.enabled) { + imgsrc->filmNegativeProcess (params->filmNegative); + } } /* @@ -1250,6 +1255,32 @@ void ImProcCoordinator::getSpotWB(int x, int y, int rect, double& temp, double& } } +bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB, float* newExps) +{ + + { + MyMutex::MyLock lock(mProcessing); + + auto xlate = [this](int x, int y) { + std::vector points, red, green, blue; + + points.push_back(Coord2D(x, y)); + ipf.transCoord(fw, fh, points, red, green, blue); + return green[0]; + }; + + int tr = getCoarseBitMask(params->coarse); + + Coord2D p1 = xlate(xA, yA); + Coord2D p2 = xlate(xB, yB); + + return imgsrc->getFilmNegativeExponents(p1, p2, tr, params->filmNegative, newExps); + + } // end of mutex locking + +} + + void ImProcCoordinator::getAutoCrop(double ratio, int &x, int &y, int &w, int &h) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index c293f0c16..d10db8d70 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -269,6 +269,7 @@ public: bool getAutoWB (double& temp, double& green, double equal, double tempBias) override; void getCamWB (double& temp, double& green) override; void getSpotWB (int x, int y, int rectSize, double& temp, double& green) override; + bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, float* newExps) override; void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) override; bool getHighQualComputed() override; void setHighQualComputed() override; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index c24ee0049..9780255da 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2735,6 +2735,32 @@ bool MetaDataParams::operator!=(const MetaDataParams &other) const } +FilmNegativeParams::FilmNegativeParams() : + enabled(false), + redExp(1.36), + greenExp(1.0), + blueExp(0.86) +{ +} + +bool FilmNegativeParams::operator ==(const FilmNegativeParams& other) const +{ + return + enabled == other.enabled + && redExp == other.redExp + && greenExp == other.greenExp + && blueExp == other.blueExp; +} + +bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const +{ + return !(*this == other); +} + + + + + ProcParams::ProcParams() { setDefaults(); @@ -3566,6 +3592,13 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // MetaData saveToKeyfile(!pedited || pedited->metadata.mode, "MetaData", "Mode", metadata.mode, keyFile); +// Film negative + saveToKeyfile(!pedited || pedited->filmNegative.enabled, "Film Negative", "Enabled", filmNegative.enabled, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.redExp, "Film Negative", "RedExponent", filmNegative.redExp, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.greenExp, "Film Negative", "GreenExponent", filmNegative.greenExp, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.blueExp, "Film Negative", "BlueExponent", filmNegative.blueExp, keyFile); + + // EXIF change list if (!pedited || pedited->exif) { for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) { @@ -5109,6 +5142,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackBlue", pedited, raw.xtranssensor.blackblue, pedited->raw.xtranssensor.exBlackBlue); } + if (keyFile.has_group("Film Negative")) { + assignFromKeyfile(keyFile, "Film Negative", "Enabled", pedited, filmNegative.enabled, pedited->filmNegative.enabled); + assignFromKeyfile(keyFile, "Film Negative", "RedExponent", pedited, filmNegative.redExp, pedited->filmNegative.redExp); + assignFromKeyfile(keyFile, "Film Negative", "GreenExponent", pedited, filmNegative.greenExp, pedited->filmNegative.greenExp); + assignFromKeyfile(keyFile, "Film Negative", "BlueExponent", pedited, filmNegative.blueExp, pedited->filmNegative.blueExp); + } + + if (keyFile.has_group("MetaData")) { int mode = int(MetaDataParams::TUNNEL); assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0982fda48..3f9ff0342 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1501,6 +1501,23 @@ struct RAWParams { static Glib::ustring getFlatFieldBlurTypeString(FlatFieldBlurType type); }; + +/** + * Parameters of film negative + */ +struct FilmNegativeParams { + bool enabled; + double redExp; + double greenExp; + double blueExp; + + FilmNegativeParams(); + + bool operator ==(const FilmNegativeParams& other) const; + bool operator !=(const FilmNegativeParams& other) const; +}; + + /** * This class holds all the processing parameters applied on the images */ @@ -1559,6 +1576,8 @@ public: ExifPairs exif; ///< List of modifications appplied on the exif tags of the input image IPTCPairs iptc; ///< The IPTC tags and values to be saved to the output image + FilmNegativeParams filmNegative; ///< Film negative parameters + /** * The constructor only sets the hand-wired defaults. */ diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 530211715..56fec7146 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -44,6 +44,8 @@ private: static LUTf initInvGrad (); static void colorSpaceConversion_ (Imagefloat* im, const procparams::ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName); int defTransform (int tran); + bool channelsAvg(Coord spotPos, int spotSize, float avgs[3], const FilmNegativeParams ¶ms); + protected: MyMutex getImageMutex; // locks getImage @@ -116,6 +118,8 @@ public: int load(const Glib::ustring &fname) override { return load(fname, false); } int load(const Glib::ustring &fname, bool firstFrameOnly); void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override; + void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) override; + bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, float newExps[3]) override; void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) override; void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override; void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6264d43ae..cc46cfca8 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -499,6 +499,7 @@ public: virtual bool getAutoWB (double& temp, double& green, double equal, double tempBias) = 0; virtual void getCamWB (double& temp, double& green) = 0; virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) = 0; + virtual bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, float* newExps) = 0; virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) = 0; virtual void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) = 0; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 8b9bee738..e270f093f 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -209,6 +209,11 @@ private: imgsrc->setCurrentFrame (params.raw.bayersensor.imageNum); imgsrc->preprocess ( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); + // After preprocess, run film negative processing if enabled + if(imgsrc->getSensorType() == ST_BAYER && params.filmNegative.enabled) { + imgsrc->filmNegativeProcess (params.filmNegative); + } + if (pl) { pl->setProgress (0.20); } diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 3af955be8..4c775bdcc 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -161,6 +161,7 @@ set(NONCLISOURCEFILES labgrid.cc softlight.cc dehaze.cc + filmnegative.cc ) include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc new file mode 100644 index 000000000..bf4c22837 --- /dev/null +++ b/rtgui/filmnegative.cc @@ -0,0 +1,320 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include "filmnegative.h" + +#include + +#include "rtimage.h" +#include "options.h" +#include "editwidgets.h" +#include "eventmapper.h" + + +using namespace rtengine; +using namespace rtengine::procparams; + + +FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FILMNEGATIVE_LABEL"), false, true), EditSubscriber(ET_OBJECTS) +{ + + auto mkExponentAdjuster = [this](Glib::ustring label, double defaultVal) { + Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 3, 0.01, defaultVal)); //exponent + adj->setAdjusterListener (this); + + if (adj->delay < options.adjusterMaxDelay) { + adj->delay = options.adjusterMaxDelay; + } + + adj->show(); + return adj; + }; + + redExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_RED"), 1.36); + greenExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_GREEN"), 1.0); + blueExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_BLUE"), 0.86); + + auto m = ProcEventMapper::getInstance(); + EvFilmNegativeEnabled = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_ENABLED"); + EvFilmNegativeExponents = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS"); + + + spotgrid = Gtk::manage(new Gtk::Grid()); + spotgrid->get_style_context()->add_class("grid-spacing"); + setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + spotbutton = Gtk::manage (new Gtk::ToggleButton (M("TP_FILMNEGATIVE_PICK"))); + setExpandAlignProperties(spotbutton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + spotbutton->get_style_context()->add_class("independent"); + spotbutton->set_tooltip_text(M("TP_FILMNEGATIVE_GUESS_TOOLTIP")); + spotbutton->set_image (*Gtk::manage (new RTImage ("color-picker-small.png"))); + + // TODO make spot size configurable ? + + // Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_SIZE"))); + // setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + // Gtk::Grid* wbsizehelper = Gtk::manage(new Gtk::Grid()); + // wbsizehelper->set_name("WB-Size-Helper"); + // setExpandAlignProperties(wbsizehelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + // spotsize = Gtk::manage (new MyComboBoxText ()); + // setExpandAlignProperties(spotsize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + // spotsize->append ("2"); + // spotsize->set_active(0); + // spotsize->append ("4"); + + spotgrid->attach (*spotbutton, 0, 1, 1, 1); +// spotgrid->attach (*slab, 1, 0, 1, 1); + // spotgrid->attach (*wbsizehelper, 2, 0, 1, 1); + + 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 ); + + spotbutton->signal_toggled().connect( sigc::mem_fun(*this, &FilmNegative::editToggled) ); +// spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); + + + // Editing geometry; create the spot rectangle + Rectangle *spotRect = new Rectangle(); + spotRect->filled = false; + + EditSubscriber::visibleGeometry.push_back( spotRect ); + + // 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(); + imgRect->filled = true; + + EditSubscriber::mouseOverGeometry.push_back( imgRect ); + +} + +FilmNegative::~FilmNegative() +{ +// idle_register.destroy(); + + for (std::vector::const_iterator i = visibleGeometry.begin(); i != visibleGeometry.end(); ++i) { + delete *i; + } + + for (std::vector::const_iterator i = mouseOverGeometry.begin(); i != mouseOverGeometry.end(); ++i) { + delete *i; + } + +} + + + +void FilmNegative::enabledChanged() +{ + if (listener) { + if (get_inconsistent()) { + listener->panelChanged(EvFilmNegativeEnabled, M("GENERAL_UNCHANGED")); + } else if (getEnabled()) { + listener->panelChanged(EvFilmNegativeEnabled, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvFilmNegativeEnabled, M("GENERAL_DISABLED")); + } + } +} + + +void FilmNegative::adjusterChanged(Adjuster* a, double newval) +{ + if (listener && getEnabled()) { + if(a == redExp || a == greenExp || a == blueExp) { + listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( + "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); + } + } +} + +void FilmNegative::adjusterAutoToggled(Adjuster* a, bool newval) +{ +} + +void FilmNegative::setEditProvider (EditDataProvider* provider) +{ + EditSubscriber::setEditProvider(provider); +} + +void FilmNegative::editToggled () +{ + if (spotbutton->get_active()) { + subscribe(); + + int w, h; + getEditProvider()->getImageSize(w, h); + + // Stick a dummy rectangle over the whole image in mouseOverGeometry. + // This is to make sure the getCursor call is fired everywhere. + const auto imgRect = static_cast(mouseOverGeometry.at(0)); + imgRect->setXYWH(0, 0, w, h); + + } else { + this->refSpotCoords.clear(); + unsubscribe(); + } +} + + +void FilmNegative::read (const ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if(pedited) { + redExp->setEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); + greenExp->setEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); + blueExp->setEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); + set_inconsistent(multiImage && !pedited->filmNegative.enabled); + } + + setEnabled(pp->filmNegative.enabled); + redExp->setValue(pp->filmNegative.redExp); + greenExp->setValue(pp->filmNegative.greenExp); + blueExp->setValue(pp->filmNegative.blueExp); + + enableListener (); +} + +void FilmNegative::write (ProcParams* pp, ParamsEdited* pedited) +{ + pp->filmNegative.redExp = redExp->getValue(); + pp->filmNegative.greenExp = greenExp->getValue(); + pp->filmNegative.blueExp = blueExp->getValue(); + pp->filmNegative.enabled = getEnabled(); + + if (pedited) { + pedited->filmNegative.redExp = redExp->getEditedState(); + pedited->filmNegative.greenExp = greenExp->getEditedState(); + pedited->filmNegative.blueExp = blueExp->getEditedState(); + pedited->filmNegative.enabled = !get_inconsistent(); + } +} + +void FilmNegative::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +{ + redExp->setValue(defParams->filmNegative.redExp); + greenExp->setValue(defParams->filmNegative.greenExp); + blueExp->setValue(defParams->filmNegative.blueExp); + + if (pedited) { + redExp->setDefaultEditedState (pedited->filmNegative.redExp ? Edited : UnEdited); + greenExp->setDefaultEditedState (pedited->filmNegative.greenExp ? Edited : UnEdited); + blueExp->setDefaultEditedState (pedited->filmNegative.blueExp ? Edited : UnEdited); + } else { + redExp->setDefaultEditedState (Irrelevant); + greenExp->setDefaultEditedState (Irrelevant); + blueExp->setDefaultEditedState (Irrelevant); + } +} + +void FilmNegative::setBatchMode (bool batchMode) +{ + spotConn.disconnect(); + removeIfThere(this, spotgrid, false); + ToolPanel::setBatchMode (batchMode); + redExp->showEditedCB (); + greenExp->showEditedCB (); + blueExp->showEditedCB (); +} + +bool FilmNegative::mouseOver(int modifierKey) +{ + EditDataProvider *provider = getEditProvider(); + const auto spotRect = static_cast(visibleGeometry.at(0)); + spotRect->setXYWH(provider->posImage.x - 16, provider->posImage.y - 16, 32, 32); + + return true; +} + +bool FilmNegative::button1Pressed(int modifierKey) +{ + EditDataProvider *provider = getEditProvider(); + + if(provider) { // debug. remove me + printf("x=%d y=%d pv1=%f pv2=%f pv3=%f\n", provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); + } + + EditSubscriber::action = EditSubscriber::Action::NONE; + + if (listener) { + + refSpotCoords.push_back(provider->posImage); + + if(refSpotCoords.size() == 2) { + + // User has selected 2 reference gray spots. Calculating new exponents + // from channel values and updating parameters. + + float newExps[3]; + if(fnp->getFilmNegativeExponents(refSpotCoords[0], refSpotCoords[1], newExps)) { + disableListener(); + redExp->setValue(newExps[0]); + greenExp->setValue(newExps[1]); + blueExp->setValue(newExps[2]); + enableListener(); + + if (listener && getEnabled()) { + listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( + "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); + } + } + + switchOffEditMode(); + } + } + + return true; +} + +bool FilmNegative::button1Released () +{ + EditDataProvider *provider = getEditProvider(); + + if(provider) { // debug. remove me + printf("x=%d y=%d pv1=%f pv2=%f pv3=%f\n", provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); + } + + EditSubscriber::action = EditSubscriber::Action::NONE; + return true; +} + +// TODO remove me ; couldn't make Action::PICKING work +bool FilmNegative::pick1 (bool picked) { + EditDataProvider *provider = getEditProvider(); + if(provider) { // debug. remove me + printf("Picked pick=%d x=%d y=%d pv1=%f pv2=%f pv3=%f\n", picked, provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); + } + return true; +} + +CursorShape FilmNegative::getCursor(int objectID) const +{ + return CSSpotWB; +} + +void FilmNegative::switchOffEditMode () +{ + refSpotCoords.clear(); + unsubscribe(); + spotbutton->set_active(false); +} \ No newline at end of file diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h new file mode 100644 index 000000000..614e60fb5 --- /dev/null +++ b/rtgui/filmnegative.h @@ -0,0 +1,91 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _NEG_H_ +#define _NEG_H_ + +#include +#include "toolpanel.h" +#include "adjuster.h" +#include "guiutils.h" +#include "wbprovider.h" +#include "editcallbacks.h" +#include "../rtengine/procparams.h" + + +class FilmNegProvider +{ +public: + virtual ~FilmNegProvider() = default; + virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, float* newExps) = 0; +}; + +class FilmNegative : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public EditSubscriber +{ + +private: + rtengine::ProcEvent EvFilmNegativeExponents; + rtengine::ProcEvent EvFilmNegativeEnabled; + + std::vector refSpotCoords; + + FilmNegProvider *fnp; + + Adjuster* redExp; + Adjuster* greenExp; + Adjuster* blueExp; + + Gtk::Grid* spotgrid; + Gtk::ToggleButton* spotbutton; + sigc::connection spotConn; + + void editToggled (); + +public: + + FilmNegative (); + ~FilmNegative () override; + + void setFilmNegProvider(FilmNegProvider* p) + { + fnp = p; + }; + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void setBatchMode (bool batchMode) override; + + void adjusterChanged (Adjuster* a, double newval) override; + void adjusterAutoToggled(Adjuster* a, bool newval) override; + void spotPressed (); + void enabledChanged() override; + + void setEditProvider (EditDataProvider* provider) override; + + // EditSubscriber interface + CursorShape getCursor(int objectID) const override; + bool mouseOver(int modifierKey) override; + bool button1Pressed(int modifierKey) override; + bool button1Released() override; + void switchOffEditMode () override; + bool pick1(bool picked) override; + +}; + +#endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 2c29b4f5b..3a5ab041a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -580,6 +580,10 @@ void ParamsEdited::set(bool v) dehaze.showDepthMap = v; dehaze.depth = v; metadata.mode = v; + filmNegative.enabled = v; + filmNegative.redExp = v; + filmNegative.greenExp = v; + filmNegative.blueExp = v; exif = v; iptc = v; @@ -1142,6 +1146,10 @@ void ParamsEdited::initFrom(const std::vector& dehaze.showDepthMap = dehaze.showDepthMap && p.dehaze.showDepthMap == other.dehaze.showDepthMap; dehaze.depth = dehaze.depth && p.dehaze.depth == other.dehaze.depth; metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode; + filmNegative.enabled = filmNegative.enabled && p.filmNegative.enabled == other.filmNegative.enabled; + filmNegative.redExp = filmNegative.redExp && p.filmNegative.redExp == other.filmNegative.redExp; + filmNegative.greenExp = filmNegative.greenExp && p.filmNegative.greenExp == other.filmNegative.greenExp; + filmNegative.blueExp = filmNegative.blueExp && p.filmNegative.blueExp == other.filmNegative.blueExp; // How the hell can we handle that??? // exif = exif && p.exif==other.exif @@ -3175,6 +3183,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.metadata.mode = mods.metadata.mode; } + if (filmNegative.enabled) { + toEdit.filmNegative.enabled = mods.filmNegative.enabled; + } + + if (filmNegative.redExp) { + toEdit.filmNegative.redExp = mods.filmNegative.redExp; + } + + if (filmNegative.greenExp) { + toEdit.filmNegative.greenExp = mods.filmNegative.greenExp; + } + + if (filmNegative.blueExp) { + toEdit.filmNegative.blueExp = mods.filmNegative.blueExp; + } + // Exif changes are added to the existing ones if (exif) for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { @@ -3216,3 +3240,8 @@ bool RetinexParamsEdited::isUnchanged() const { return enabled && retinexcolorspace && gammaretinex && gam && slope; } + +bool FilmNegativeParamsEdited::isUnchanged() const +{ + return enabled && redExp && greenExp && blueExp; +} \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 95701e01a..57e6f2cdd 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -666,6 +666,15 @@ struct MetaDataParamsEdited { bool mode; }; +struct FilmNegativeParamsEdited { + bool enabled; + bool redExp; + bool greenExp; + bool blueExp; + + bool isUnchanged() const; +}; + struct ParamsEdited { GeneralParamsEdited general; ToneCurveParamsEdited toneCurve; @@ -710,6 +719,7 @@ struct ParamsEdited { SoftLightParamsEdited softlight; DehazeParamsEdited dehaze; MetaDataParamsEdited metadata; + FilmNegativeParamsEdited filmNegative; bool exif; bool iptc; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 41e25387e..bd9720dfd 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -92,6 +92,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit bayerrawexposure = Gtk::manage (new BayerRAWExposure ()); xtransrawexposure = Gtk::manage (new XTransRAWExposure ()); fattal = Gtk::manage (new FattalToneMapping ()); + filmNegative = Gtk::manage (new FilmNegative ()); // So Demosaic, Line noise filter, Green Equilibration, Ca-Correction (garder le nom de section identique!) and Black-Level will be moved in a "Bayer sensor" tool, // and a separate Demosaic and Black Level tool will be created in an "X-Trans sensor" tool @@ -154,6 +155,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit addfavoritePanel (rawPanel, preprocess); addfavoritePanel (rawPanel, darkframe); addfavoritePanel (rawPanel, flatfield); + addfavoritePanel (rawPanel, filmNegative); int favoriteCount = 0; for(auto it = favorites.begin(); it != favorites.end(); ++it) { @@ -255,6 +257,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit distortion->setLensGeomListener (this); crop->setCropPanelListener (this); icm->setICMPanelListener (this); + filmNegative->setFilmNegProvider (this); toolBar = new ToolBar (); toolBar->setToolBarListener (this); @@ -305,6 +308,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorbayer->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); + filmNegative->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -320,6 +324,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorbayer->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); + filmNegative->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -335,6 +340,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorxtrans->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::show(); + filmNegative->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -349,6 +355,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorxtrans->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::hide(); + filmNegative->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -360,6 +367,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt [this]() -> bool { rawPanelSW->set_sensitive(false); + filmNegative->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(true); return false; @@ -476,7 +484,7 @@ void ToolPanelCoordinator::profileChange( lParams[1] = *mergedParams; pe.initFrom (lParams); - filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged() && pe.retinex.isUnchanged(); + filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged() && pe.retinex.isUnchanged() && pe.filmNegative.isUnchanged(); } *params = *mergedParams; @@ -1014,3 +1022,11 @@ void ToolPanelCoordinator::setEditProvider (EditDataProvider *provider) toolPanels.at (i)->setEditProvider (provider); } } + +bool ToolPanelCoordinator::getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, float* newExps) +{ + if(!ipc) + return false; + + return ipc->getFilmNegativeExponents(spotA.x, spotA.y, spotB.x, spotB.y, newExps); +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 1ac74871a..9910f9757 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -82,6 +82,7 @@ #include "softlight.h" #include "dehaze.h" #include "guiutils.h" +#include "filmnegative.h" class ImageEditorCoordinator; @@ -97,7 +98,8 @@ class ToolPanelCoordinator : public CropPanelListener, public ICMPanelListener, public ImageAreaToolListener, - public rtengine::ImageTypeListener + public rtengine::ImageTypeListener, + public FilmNegProvider { protected: WhiteBalance* whitebalance; @@ -152,6 +154,7 @@ protected: XTransRAWExposure* xtransrawexposure; FattalToneMapping *fattal; MetaDataPanel* metadata; + FilmNegative* filmNegative; std::vector paramcListeners; @@ -288,6 +291,9 @@ public: rtengine::RawImage* getFF() override; Glib::ustring GetCurrentImageFilePath() override; + // FilmNegProvider interface + bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, float* newExps) override; + // rotatelistener interface void straightenRequested () override; void autoCropRequested () override; From b990b898754e05648b8ee88c87c1ab9e82c19805 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 8 Jun 2019 15:13:44 +0200 Subject: [PATCH 006/222] interpolateBadPixelsXtrans() : fix oob access --- rtengine/rawimagesource.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 0f0d31c40..b8c422545 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1298,6 +1298,7 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads ) for(dx = -2, dy = 0; dx <= 2 && !distance2PixelFound; dx += 4) if(ri->XTRANSFC(row, col + dx) == pixelColor) { distance2PixelFound = true; + break; } if(!distance2PixelFound) @@ -1306,6 +1307,7 @@ int RawImageSource::interpolateBadPixelsXtrans( PixelsMap &bitmapBads ) for(dx = 0, dy = -2; dy <= 2 && !distance2PixelFound; dy += 4) if(ri->XTRANSFC(row + dy, col) == pixelColor) { distance2PixelFound = true; + break; } // calculate the value of its virtual counterpart (marked with a V in above examples) From d2366e633c61792fc1d5ae2d7caf76de5a2a0005 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Sun, 9 Jun 2019 13:09:29 +0200 Subject: [PATCH 007/222] Enabled bad pixels interpolation for ST_XTRANS after upstream fix c0a033e --- rtengine/filmnegativeproc.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index dba623ab4..d2a798abe 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -307,7 +307,21 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p } else if(ri->getSensorType() == ST_FUJI_XTRANS) { - // TODO +#ifdef _OPENMP + #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) +#endif + + for(int i = 0; i < H; i++) + for(int j = 0; j < W; j++) { + if (rawData[i][j] >= MAX_OUT_VALUE) { + bitmapBads.set(j, i); + totBP++; + } + } + + if (totBP > 0) { + interpolateBadPixelsXtrans( bitmapBads ); + } } From df4513f5956f884d8a4e25a89cc0322aa59e0ee3 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 9 Jun 2019 14:36:38 +0200 Subject: [PATCH 008/222] Avoid integer overflow when accessing luts with very large values --- rtengine/LUT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/LUT.h b/rtengine/LUT.h index de668cca8..9f16995d0 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -444,7 +444,7 @@ public: } idx = 0; - } else if (idx > maxs) { + } else if (index > maxsf) { if (clip & LUT_CLIP_ABOVE) { return data[upperBound]; } From 91565728e50ab2eefe743c6a13295ba50f54522d Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Sun, 9 Jun 2019 19:25:15 +0200 Subject: [PATCH 009/222] Clamped output values to a max of 65535.f after applying multipliers, to avoid trouble further down the processing pipeline. --- rtengine/filmnegativeproc.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index d2a798abe..64f7a697b 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -255,9 +255,10 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p #endif for (int row = 0; row < H; row ++) { for (int col = 0; col < W; col++) { - int c = FC(row, col); // three colors, 0=R, 1=G, 2=B - // Apply the multipliers - rawData[row][col] *= mults[c]; + int c = FC(row, col); // three colors, 0=R, 1=G, 2=B + // Apply the multipliers, clamp max output value to 65535 + float out = rawData[row][col] * mults[c]; + rawData[row][col] = out > 65535.f ? 65535.f : out; } } @@ -268,9 +269,10 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p #endif for (int row = 0; row < H; row ++) { for (int col = 0; col < W; col++) { - int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B - // Apply the multipliers - rawData[row][col] *= mults[c]; + int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B + // Apply the multipliers, clamp max output value to 65535 + float out = rawData[row][col] * mults[c]; + rawData[row][col] = out > 65535.f ? 65535.f : out; } } From b95bdb1aea7ef0de3378b06ca46da6b3c2d0e8be Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Mon, 10 Jun 2019 22:05:54 +0200 Subject: [PATCH 010/222] Linked red and blue exponent adjuster to the green adjuster, in order to maintain the ratio between exponents if the user moves the green adjuster (master). Switched back to vector sort for median calculations: the results of the histogram search function diverge more and more from the simple median calculation as the exponents increase. At 2.0 the test picture is already impossible to WB as the multipliers are too far off (2.78226e+08 histo vs 9.7927e+11 sort), and the normal WB sliders can't compensate for those huge factors. --- rtengine/filmnegativeproc.cc | 25 ++++++++++++++----------- rtgui/filmnegative.cc | 24 ++++++++++++++++++++---- rtgui/filmnegative.h | 2 ++ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 64f7a697b..948e86957 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -104,8 +104,8 @@ bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int std::swap(clearVals, denseVals); if (settings->verbose) { - printf("Clear film values: R=%f G=%f B=%f\n", clearVals[0], clearVals[1], clearVals[2]); - printf("Dense film values: R=%f G=%f B=%f\n", denseVals[0], denseVals[1], denseVals[2]); + printf("Clear film values: R=%g G=%g B=%g\n", clearVals[0], clearVals[1], clearVals[2]); + printf("Dense film values: R=%g G=%g B=%g\n", denseVals[0], denseVals[1], denseVals[2]); } float denseGreenRatio = clearVals[1] / denseVals[1]; @@ -119,7 +119,7 @@ bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 3.f); if (settings->verbose) - printf("New exponents: R=%f G=%f B=%f\n", newExps[0], newExps[1], newExps[2]); + printf("New exponents: R=%g G=%g B=%g\n", newExps[0], newExps[1], newExps[2]); return true; } @@ -230,20 +230,23 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p float mults[3] = { 1.f }; // Channel normalization multipliers for (int c=0; c<3; c++) { - // Find median values for each channel using a histogram search function - findMinMaxPercentile(&cvs[c][0], cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); - // Determine the channel multipler so that N times the median becomes 65k. This clips away - // the values in the dark border surrounding the negative (due to the film holder, for example), - // the reciprocal of which have blown up to stellar values. - mults[c] = MAX_OUT_VALUE / (medians[c] * 24); + // Find median values for each channel + if(cvs[c].size() > 0) { + std::sort(cvs[c].begin(), cvs[c].end()); + medians[c] = cvs[c].at(cvs[c].size() / 2); + // Determine the channel multipler so that N times the median becomes 65k. This clips away + // the values in the dark border surrounding the negative (due to the film holder, for example), + // the reciprocal of which have blown up to stellar values. + mults[c] = MAX_OUT_VALUE / (medians[c] * 24); + } } t4.set(); if (settings->verbose) { printf("Sample count : %lu, %lu, %lu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); - printf("Medians : %f %f %f\n", medians[0], medians[1], medians[2] ); - printf("Computed multipliers : %f %f %f\n", mults[0], mults[1], mults[2] ); + printf("Medians : %g %g %g\n", medians[0], medians[1], medians[2] ); + printf("Computed multipliers : %g %g %g\n", mults[0], mults[1], mults[2] ); printf("Median calc time us: %d\n", t4.etime(t3)); } diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index bf4c22837..94c6db4dd 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -34,7 +34,7 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI { auto mkExponentAdjuster = [this](Glib::ustring label, double defaultVal) { - Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 3, 0.01, defaultVal)); //exponent + Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 5, 0.001, defaultVal)); //exponent adj->setAdjusterListener (this); if (adj->delay < options.adjusterMaxDelay) { @@ -49,6 +49,9 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI greenExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_GREEN"), 1.0); blueExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_BLUE"), 0.86); + redRatio = redExp->getValue() / greenExp->getValue(); + blueRatio = blueExp->getValue() / greenExp->getValue(); + auto m = ProcEventMapper::getInstance(); EvFilmNegativeEnabled = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_ENABLED"); EvFilmNegativeExponents = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS"); @@ -139,10 +142,23 @@ void FilmNegative::enabledChanged() void FilmNegative::adjusterChanged(Adjuster* a, double newval) { - if (listener && getEnabled()) { + if (listener) { if(a == redExp || a == greenExp || a == blueExp) { - listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( - "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); + disableListener(); + if(a == greenExp) { + redExp->setValue(a->getValue() * redRatio); + blueExp->setValue(a->getValue() * blueRatio); + } else if(a == redExp) { + redRatio = newval / greenExp->getValue(); + } else if(a == blueExp) { + blueRatio = newval / greenExp->getValue(); + } + enableListener(); + + if(getEnabled()) { + listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( + "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); + } } } } diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 614e60fb5..5d6c8ce03 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -54,6 +54,8 @@ private: Gtk::ToggleButton* spotbutton; sigc::connection spotConn; + double redRatio, blueRatio; + void editToggled (); public: From 223ae8abcee359c2f807ef272443c606aa471621 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 11 Jun 2019 00:19:18 +0200 Subject: [PATCH 011/222] Bugfix: exponent adjusters were not following the master (green) slider after exponents auto-calc via dual spot picking; updated redRatio/blueRatio after calculation. --- rtgui/filmnegative.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 94c6db4dd..b4fdc895c 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -154,7 +154,7 @@ void FilmNegative::adjusterChanged(Adjuster* a, double newval) blueRatio = newval / greenExp->getValue(); } enableListener(); - + if(getEnabled()) { listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); @@ -287,6 +287,8 @@ bool FilmNegative::button1Pressed(int modifierKey) redExp->setValue(newExps[0]); greenExp->setValue(newExps[1]); blueExp->setValue(newExps[2]); + redRatio = redExp->getValue() / greenExp->getValue(); + blueRatio = blueExp->getValue() / greenExp->getValue(); enableListener(); if (listener && getEnabled()) { From e1c9197ed5b547bb114a87fa7bb8789218323326 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 11 Jun 2019 20:08:46 +0200 Subject: [PATCH 012/222] Moved median calculation block before exponentiation. This way findMinMaxPercentile() can be used again because it works on the original raw file values (which are in a much more reasonable range). Patch kindly provided by @heckflosse ;-) --- rtengine/filmnegativeproc.cc | 115 +++++++++++++++++------------------ 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 948e86957..e00891b1a 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -134,6 +134,61 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p MyTime t1, t2, t3,t4, t5, t6; t1.set(); + // Channel vectors to calculate medians + std::vector cvs[3] = { + std::vector(), + std::vector(), + std::vector() + }; + + // Sample one every 5 pixels, and push the value in the appropriate channel vector. + // Chose an odd step, not 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) { + int c = FC(row, col); // three colors, 0=R, 1=G, 2=B + cvs[c].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) { + int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B + cvs[c].push_back(rawData[row][col]); + } + } + } + + const float MAX_OUT_VALUE = 65000.f; + + t2.set(); + if (settings->verbose) + printf("Median vector fill loop time us: %d\n", t2.etime(t1)); + + float medians[3]; // Channel median values + float mults[3] = { 1.f }; // Channel normalization multipliers + + for (int c=0; c<3; c++) { + // Find median values for each channel + if(cvs[c].size() > 0) { + findMinMaxPercentile(&cvs[c][0], cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); + medians[c] = pow_F(max(medians[c], 1.f), -exps[c]); + // Determine the channel multipler so that N times the median becomes 65k. This clips away + // the values in the dark border surrounding the negative (due to the film holder, for example), + // the reciprocal of which have blown up to stellar values. + mults[c] = MAX_OUT_VALUE / (medians[c] * 24); + } + } + + t3.set(); + if (settings->verbose) { + printf("Sample count : %lu, %lu, %lu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); + printf("Medians : %g %g %g\n", medians[0], medians[1], medians[2] ); + printf("Computed multipliers : %g %g %g\n", mults[0], mults[1], mults[2] ); + printf("Median calc time us: %d\n", t3.etime(t2)); + } + + if(ri->getSensorType() == ST_BAYER) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) @@ -191,65 +246,9 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p } - t2.set(); - if (settings->verbose) - printf("Pow loop time us: %d\n", t2.etime(t1)); - - // Channel vectors to calculate medians - std::vector cvs[3] = { - std::vector(), - std::vector(), - std::vector() - }; - - // Sample one every 5 pixels, and push the value in the appropriate channel vector. - // Chose an odd step, not 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) { - int c = FC(row, col); // three colors, 0=R, 1=G, 2=B - cvs[c].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) { - int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B - cvs[c].push_back(rawData[row][col]); - } - } - } - - const float MAX_OUT_VALUE = 65000.f; - - t3.set(); - if (settings->verbose) - printf("Median vector fill loop time us: %d\n", t3.etime(t2)); - - float medians[3]; // Channel median values - float mults[3] = { 1.f }; // Channel normalization multipliers - - for (int c=0; c<3; c++) { - // Find median values for each channel - if(cvs[c].size() > 0) { - std::sort(cvs[c].begin(), cvs[c].end()); - medians[c] = cvs[c].at(cvs[c].size() / 2); - // Determine the channel multipler so that N times the median becomes 65k. This clips away - // the values in the dark border surrounding the negative (due to the film holder, for example), - // the reciprocal of which have blown up to stellar values. - mults[c] = MAX_OUT_VALUE / (medians[c] * 24); - } - } - - t4.set(); - if (settings->verbose) { - printf("Sample count : %lu, %lu, %lu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); - printf("Medians : %g %g %g\n", medians[0], medians[1], medians[2] ); - printf("Computed multipliers : %g %g %g\n", mults[0], mults[1], mults[2] ); - printf("Median calc time us: %d\n", t4.etime(t3)); - } - + if (settings->verbose) + printf("Pow loop time us: %d\n", t4.etime(t3)); if(ri->getSensorType() == ST_BAYER) { From 2bbf8bd864fa65092b96c3db917ed38e0e6e9f60 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 11 Jun 2019 20:26:13 +0200 Subject: [PATCH 013/222] Changed events action from ALL to FIRST , this way the histogram is updated after enabling/disabling or moving the adjusters. --- rtgui/filmnegative.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index b4fdc895c..2af69677f 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -53,8 +53,8 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI blueRatio = blueExp->getValue() / greenExp->getValue(); auto m = ProcEventMapper::getInstance(); - EvFilmNegativeEnabled = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_ENABLED"); - EvFilmNegativeExponents = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS"); + EvFilmNegativeEnabled = m->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED"); + EvFilmNegativeExponents = m->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS"); spotgrid = Gtk::manage(new Gtk::Grid()); From 8fa30d496d334312fa58e5c5e8d364f9cba9848c Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 11 Jun 2019 21:02:16 +0200 Subject: [PATCH 014/222] Now that medians are known *before* processing, moved multiplication step inside the same loop as exponentiation for further optimization. Patch kindly provided by @heckflosse ;-) --- rtengine/filmnegativeproc.cc | 65 +++++++++++++----------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index e00891b1a..5766fbf1e 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -29,6 +29,9 @@ #include "opthelper.h" #include "rt_algo.h" +//#define BENCHMARK +#include "StopWatch.h" + namespace rtengine { @@ -126,6 +129,8 @@ bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams ¶ms) { +// BENCHFUNMICRO + if(!params.enabled) return; @@ -199,19 +204,23 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. const float exps0 = -exps[FC(row, col)]; const float exps1 = -exps[FC(row, col + 1)]; + const float mult0 = mults[FC(row, col)]; + const float mult1 = mults[FC(row, col + 1)]; #ifdef __SSE2__ const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1); + const vfloat multsv = _mm_setr_ps(mult0, mult1, mult0, mult1); const vfloat onev = F2V(1.f); + const vfloat c65535v = F2V(65535.f); for (; col < W - 3; col+=4) { - STVFU(rawData[row][col], pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv)); + STVFU(rawData[row][col], vminf(multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv), c65535v)); } #endif // __SSE2__ for (; col < W - 1; col+=2) { - rawData[row][col] = pow_F(max(rawData[row][col], 1.f), exps0); - rawData[row][col + 1] = pow_F(max(rawData[row][col + 1], 1.f), exps1); + rawData[row][col] = rtengine::min(mult0 * pow_F(max(rawData[row][col], 1.f), exps0), 65535.f); + rawData[row][col + 1] = rtengine::min(mult1 * pow_F(max(rawData[row][col + 1], 1.f), exps1), 65535.f); } if (col < W) { - rawData[row][col] = pow_F(max(rawData[row][col], 1.f), exps0); + rawData[row][col] = rtengine::min(mult0 * pow_F(max(rawData[row][col], 1.f), exps0), 65535.f); } } } else if(ri->getSensorType() == ST_FUJI_XTRANS) { @@ -223,24 +232,29 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p // Exponents are expressed as positive in the parameters, so negate them in order // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. const float expsc[6] = {-exps[ri->XTRANSFC(row, 0)], -exps[ri->XTRANSFC(row, 1)], -exps[ri->XTRANSFC(row, 2)], -exps[ri->XTRANSFC(row, 3)], -exps[ri->XTRANSFC(row, 4)], -exps[ri->XTRANSFC(row, 5)]}; + const float multsc[6] = {mults[ri->XTRANSFC(row, 0)], mults[ri->XTRANSFC(row, 1)], mults[ri->XTRANSFC(row, 2)], mults[ri->XTRANSFC(row, 3)], mults[ri->XTRANSFC(row, 4)], mults[ri->XTRANSFC(row, 5)]}; #ifdef __SSE2__ const vfloat expsv0 = _mm_setr_ps(expsc[0], expsc[1], expsc[2], expsc[3]); const vfloat expsv1 = _mm_setr_ps(expsc[4], expsc[5], expsc[0], expsc[1]); const vfloat expsv2 = _mm_setr_ps(expsc[2], expsc[3], expsc[4], expsc[5]); + const vfloat multsv0 = _mm_setr_ps(multsc[0], multsc[1], multsc[2], multsc[3]); + const vfloat multsv1 = _mm_setr_ps(multsc[4], multsc[5], multsc[0], multsc[1]); + const vfloat multsv2 = _mm_setr_ps(multsc[2], multsc[3], multsc[4], multsc[5]); const vfloat onev = F2V(1.f); + const vfloat c65535v = F2V(65535.f); for (; col < W - 11; col+=12) { - STVFU(rawData[row][col], pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0)); - STVFU(rawData[row][col + 4], pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1)); - STVFU(rawData[row][col + 8], pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2)); + STVFU(rawData[row][col], vminf(multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0), c65535v)); + STVFU(rawData[row][col + 4], vminf(multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1), c65535v)); + STVFU(rawData[row][col + 8], vminf(multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2), c65535v)); } #endif // __SSE2__ for (; col < W - 5; col+=6) { for (int c = 0; c < 6; ++c) { - rawData[row][col + c] = pow_F(max(rawData[row][col + c], 1.f), expsc[c]); + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); } } for (int c = 0; col < W; col++, c++) { - rawData[row][col + c] = pow_F(max(rawData[row][col + c], 1.f), expsc[c]); + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); } } } @@ -250,41 +264,8 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p if (settings->verbose) printf("Pow loop time us: %d\n", t4.etime(t3)); - if(ri->getSensorType() == ST_BAYER) { - -#ifdef _OPENMP - #pragma omp for nowait -#endif - for (int row = 0; row < H; row ++) { - for (int col = 0; col < W; col++) { - int c = FC(row, col); // three colors, 0=R, 1=G, 2=B - // Apply the multipliers, clamp max output value to 65535 - float out = rawData[row][col] * mults[c]; - rawData[row][col] = out > 65535.f ? 65535.f : out; - } - } - - } else if(ri->getSensorType() == ST_FUJI_XTRANS) { - -#ifdef _OPENMP - #pragma omp for nowait -#endif - for (int row = 0; row < H; row ++) { - for (int col = 0; col < W; col++) { - int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B - // Apply the multipliers, clamp max output value to 65535 - float out = rawData[row][col] * mults[c]; - rawData[row][col] = out > 65535.f ? 65535.f : out; - } - } - - } - t5.set(); - if (settings->verbose) - printf("Mult loop time us: %d\n", t5.etime(t4)); - PixelsMap bitmapBads(W, H); From 5ddc4a3e0ee3f63ec684f05b175e1215111659f9 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 11 Jun 2019 22:13:16 +0200 Subject: [PATCH 015/222] Added missing checkbox for film negative feature in partial apply / partial paste dialogs. --- rtdata/languages/default | 1 + rtgui/partialpastedlg.cc | 18 ++++++++++++++++++ rtgui/partialpastedlg.h | 3 +++ 3 files changed, 22 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index e6a546a7e..1c6a1acba 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -985,6 +985,7 @@ PARTIALPASTE_EVERYTHING;Everything PARTIALPASTE_EXIFCHANGES;Exif PARTIALPASTE_EXPOSURE;Exposure PARTIALPASTE_FILMSIMULATION;Film simulation +PARTIALPASTE_FILMNEGATIVE;Film Negative PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 734f7c29b..ef18e2953 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -134,6 +134,9 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO"))); raw_caredblue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CAREDBLUE"))); raw_ca_avoid_colourshift = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT"))); + //--- + filmNegative = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FILMNEGATIVE")) ); + Gtk::VBox* vboxes[8]; Gtk::HSeparator* hseps[8]; @@ -249,6 +252,9 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[7]->pack_start (*raw_ca_autocorrect, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*raw_caredblue, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*raw_ca_avoid_colourshift, Gtk::PACK_SHRINK, 2); + vboxes[7]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); + vboxes[7]->pack_start (*filmNegative, Gtk::PACK_SHRINK, 2); + Gtk::VBox* vbCol1 = Gtk::manage (new Gtk::VBox ()); Gtk::VBox* vbCol2 = Gtk::manage (new Gtk::VBox ()); @@ -396,6 +402,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_ca_autocorrectConn = raw_ca_autocorrect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_caredblueConn = raw_caredblue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_ca_avoid_colourshiftconn = raw_ca_avoid_colourshift->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + //--- + filmNegativeConn = filmNegative->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); add_button (M("GENERAL_OK"), Gtk::RESPONSE_OK); add_button (M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); @@ -467,6 +475,7 @@ void PartialPasteDlg::rawToggled () ConnectionBlocker raw_ca_autocorrectBlocker(raw_ca_autocorrectConn); ConnectionBlocker raw_caredblueBlocker(raw_caredblueConn); ConnectionBlocker raw_ca_avoid_colourshiftBlocker(raw_ca_avoid_colourshiftconn); + ConnectionBlocker filmNegativeBlocker(filmNegativeConn); raw->set_inconsistent (false); @@ -495,6 +504,7 @@ void PartialPasteDlg::rawToggled () raw_ca_autocorrect->set_active (raw->get_active ()); raw_caredblue->set_active (raw->get_active ()); raw_ca_avoid_colourshift->set_active (raw->get_active ()); + filmNegative->set_active (raw->get_active()); } void PartialPasteDlg::basicToggled () @@ -966,6 +976,14 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.raw.ff_AutoClipControl = falsePE.raw.ff_AutoClipControl; } + if (!filmNegative->get_active ()) { + filterPE.filmNegative.enabled = falsePE.filmNegative.enabled; + filterPE.filmNegative.redExp = falsePE.filmNegative.redExp; + filterPE.filmNegative.greenExp = falsePE.filmNegative.greenExp; + filterPE.filmNegative.blueExp = falsePE.filmNegative.blueExp; + } + + if (dstPE) { *dstPE = filterPE; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 0325fa063..b5b93b11a 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -130,6 +130,8 @@ public: Gtk::CheckButton* ff_BlurType; Gtk::CheckButton* ff_ClipControl; + Gtk::CheckButton* filmNegative; + sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, advancedConn; sigc::connection wbConn, exposureConn, localcontrastConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn; @@ -140,6 +142,7 @@ public: sigc::connection metadataConn, exifchConn, iptcConn, icmConn; sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; sigc::connection raw_caredblueConn, raw_ca_autocorrectConn, raw_ca_avoid_colourshiftconn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_pdaf_lines_filterConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_borderConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_blackConn; + sigc::connection filmNegativeConn; public: PartialPasteDlg (const Glib::ustring &title, Gtk::Window* parent); From 8d0755eddc6d3aa02de4b39154ca40edde7865c9 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 11 Jun 2019 22:50:36 +0200 Subject: [PATCH 016/222] Raised default master exponent from 1.0 to 2.0, to get a reasonable contrast right from the start. --- rtengine/filmnegativeproc.cc | 4 ++-- rtengine/procparams.cc | 6 +++--- rtgui/filmnegative.cc | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 5766fbf1e..db98fdf02 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -117,9 +117,9 @@ bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int // compared to the ratio in the reference channel (green) for(int ch=0; ch<3; ch++) if(ch==1) - newExps[ch] = 1.f; // Green is the reference channel + newExps[ch] = 2.f; // Green is the reference channel else - newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 3.f); + newExps[ch] = CLAMP(2.f * logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 6.f); if (settings->verbose) printf("New exponents: R=%g G=%g B=%g\n", newExps[0], newExps[1], newExps[2]); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9780255da..bb5c86494 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2737,9 +2737,9 @@ bool MetaDataParams::operator!=(const MetaDataParams &other) const FilmNegativeParams::FilmNegativeParams() : enabled(false), - redExp(1.36), - greenExp(1.0), - blueExp(0.86) + redExp(2.72), + greenExp(2.0), + blueExp(1.72) { } diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 2af69677f..8f1fb5610 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -34,7 +34,7 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI { auto mkExponentAdjuster = [this](Glib::ustring label, double defaultVal) { - Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 5, 0.001, defaultVal)); //exponent + Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 6, 0.001, defaultVal)); //exponent adj->setAdjusterListener (this); if (adj->delay < options.adjusterMaxDelay) { @@ -45,9 +45,9 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI return adj; }; - redExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_RED"), 1.36); - greenExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_GREEN"), 1.0); - blueExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_BLUE"), 0.86); + redExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_RED"), 2.72); + greenExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_GREEN"), 2.0); + blueExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_BLUE"), 1.72); redRatio = redExp->getValue() / greenExp->getValue(); blueRatio = blueExp->getValue() / greenExp->getValue(); From c819cb63a253b7ee1e884c43063537317e610b42 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Wed, 12 Jun 2019 22:11:34 +0200 Subject: [PATCH 017/222] Speed boost in the median vectors fill via loop unrolling --- rtengine/filmnegativeproc.cc | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index db98fdf02..7c7103dc6 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -150,16 +150,28 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p // Chose an odd step, not 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) { - int c = FC(row, col); // three colors, 0=R, 1=G, 2=B - cvs[c].push_back(rawData[row][col]); + int col = 0; + int c0 = FC(row, col); + int c1 = FC(row, col + 5); + 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) { - int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B - cvs[c].push_back(rawData[row][col]); + int col = 0; + const unsigned int cs[6] = {ri->XTRANSFC(row, 0), ri->XTRANSFC(row, 5), ri->XTRANSFC(row, 10), ri->XTRANSFC(row, 15), ri->XTRANSFC(row, 20), ri->XTRANSFC(row, 25)}; + 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]); } } } From 015cffc73ab416d9d8788938dceb78e08ec127e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Thu, 13 Jun 2019 09:52:13 +0200 Subject: [PATCH 018/222] Peripheral cleanups and a fix - Whitespace, braces, sorting - Fixed missing filmnegative in `ProcParams::operator ==(ProcParams)` --- rtengine/CMakeLists.txt | 42 +- rtengine/imagesource.h | 20 +- rtengine/improccoordinator.cc | 38 +- rtengine/procparams.cc | 10 +- rtengine/procparams.h | 10 +- rtengine/rawimagesource.h | 3 - rtengine/simpleprocess.cc | 2 +- rtgui/CMakeLists.txt | 22 +- rtgui/paramsedited.cc | 772 +++++++++++++++++----------------- rtgui/partialpastedlg.cc | 4 - rtgui/toolpanelcoord.cc | 5 +- 11 files changed, 457 insertions(+), 471 deletions(-) diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index dfa843fd0..385ba921e 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -30,18 +30,15 @@ link_directories("${PROJECT_SOURCE_DIR}/rtexif" set(CAMCONSTSFILE "camconst.json") set(RTENGINESOURCEFILES - CA_correct_RT.cc - EdgePreservingDecomposition.cc - FTblockDN.cc - PF_correct_RT.cc ahd_demosaic_RT.cc amaze_demosaic_RT.cc - cJSON.c + CA_correct_RT.cc calc_distort.cc camconst.cc cfa_linedn_RT.cc ciecam02.cc cieimage.cc + cJSON.c clutstore.cc color.cc colortemp.cc @@ -58,12 +55,18 @@ set(RTENGINESOURCEFILES dual_demosaic_RT.cc dynamicprofile.cc eahd_demosaic.cc + EdgePreservingDecomposition.cc fast_demo.cc ffmanager.cc + filmnegativeproc.cc flatcurves.cc + FTblockDN.cc + gamutwarning.cc gauss.cc green_equil_RT.cc + guidedfilter.cc hilite_recon.cc + histmatching.cc hphd_demosaic_RT.cc iccjpeg.cc iccstore.cc @@ -78,10 +81,15 @@ set(RTENGINESOURCEFILES improcfun.cc impulse_denoise.cc init.cc + ipdehaze.cc iplab2rgb.cc + iplabregions.cc + iplocalcontrast.cc ipresize.cc ipretinex.cc + ipshadowshighlights.cc ipsharpen.cc + ipsoftlight.cc iptransform.cc ipvibrance.cc ipwavelet.cc @@ -89,8 +97,8 @@ set(RTENGINESOURCEFILES jpeg_ijg/jpeg_memsrc.cc klt/convolve.cc klt/error.cc - klt/klt.cc klt/klt_util.cc + klt/klt.cc klt/pnmio.cc klt/pyramid.cc klt/selectGoodFeatures.cc @@ -99,8 +107,11 @@ set(RTENGINESOURCEFILES klt/writeFeatures.cc labimage.cc lcp.cc + lj92.c loadinitial.cc myfile.cc + pdaflinesfilter.cc + PF_correct_RT.cc pipettebuffer.cc pixelshift.cc previewimage.cc @@ -112,28 +123,17 @@ set(RTENGINESOURCEFILES rcd_demosaic.cc refreshmap.cc rt_algo.cc + rtlensfun.cc rtthumbnail.cc shmap.cc simpleprocess.cc slicer.cc stdimagesource.cc - utils.cc - rtlensfun.cc tmo_fattal02.cc - iplocalcontrast.cc - histmatching.cc - pdaflinesfilter.cc - gamutwarning.cc - ipshadowshighlights.cc - xtrans_demosaic.cc + utils.cc vng4_demosaic_RT.cc - ipsoftlight.cc - guidedfilter.cc - ipdehaze.cc - iplabregions.cc - lj92.c - filmnegativeproc.cc - ) + xtrans_demosaic.cc +) if(LENSFUN_HAS_LOAD_DIRECTORY) set_source_files_properties(rtlensfun.cc PROPERTIES COMPILE_DEFINITIONS RT_LENSFUN_HAS_LOAD_DIRECTORY) diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index e3321b599..0a34b6bc8 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -16,20 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMAGESOURCE_ -#define _IMAGESOURCE_ +#pragma once + +#include #include -#include -#include "rtengine.h" + #include "colortemp.h" #include "coord2d.h" #include "dcp.h" -#include "LUT.h" -#include "imagedata.h" -#include "image8.h" #include "image16.h" +#include "image8.h" +#include "imagedata.h" #include "imagefloat.h" +#include "LUT.h" +#include "rtengine.h" namespace rtengine { @@ -39,11 +40,11 @@ namespace procparams struct CoarseTransformParams; struct ColorManagementParams; +struct FilmNegativeParams; struct LensProfParams; struct RAWParams; struct RetinexParams; struct ToneCurveParams; -struct FilmNegativeParams; } @@ -57,6 +58,7 @@ public: double cam_xyz[3][3] = {}; }; +// TODO: Move implementation to .cc (Flössie) class ImageSource : public InitialImage { @@ -180,5 +182,5 @@ public: } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; }; + } -#endif diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 2d0d490ad..fb6250183 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -279,8 +279,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) highDetailPreprocessComputed = highDetailNeeded; // After preprocess, run film negative processing if enabled - if((todo & M_RAW) && (imgsrc->getSensorType() == ST_BAYER || imgsrc->getSensorType() == ST_FUJI_XTRANS) && params->filmNegative.enabled) { - imgsrc->filmNegativeProcess (params->filmNegative); + if ( + (todo & M_RAW) + && ( + imgsrc->getSensorType() == ST_BAYER + || imgsrc->getSensorType() == ST_FUJI_XTRANS + ) + && params->filmNegative.enabled + ) { + imgsrc->filmNegativeProcess(params->filmNegative); } } @@ -1257,30 +1264,29 @@ void ImProcCoordinator::getSpotWB(int x, int y, int rect, double& temp, double& bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB, float* newExps) { + MyMutex::MyLock lock(mProcessing); - { - MyMutex::MyLock lock(mProcessing); + const auto xlate = + [this](int x, int y) -> Coord2D + { + const std::vector points = {Coord2D(x, y)}; - auto xlate = [this](int x, int y) { - std::vector points, red, green, blue; - - points.push_back(Coord2D(x, y)); + std::vector red; + std::vector green; + std::vector blue; ipf.transCoord(fw, fh, points, red, green, blue); + return green[0]; }; - int tr = getCoarseBitMask(params->coarse); + const int tr = getCoarseBitMask(params->coarse); - Coord2D p1 = xlate(xA, yA); - Coord2D p2 = xlate(xB, yB); - - return imgsrc->getFilmNegativeExponents(p1, p2, tr, params->filmNegative, newExps); - - } // end of mutex locking + const Coord2D p1 = xlate(xA, yA); + const Coord2D p2 = xlate(xB, yB); + return imgsrc->getFilmNegativeExponents(p1, p2, tr, params->filmNegative, newExps); } - void ImProcCoordinator::getAutoCrop(double ratio, int &x, int &y, int &w, int &h) { diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index bb5c86494..ade3b0581 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2734,7 +2734,6 @@ bool MetaDataParams::operator!=(const MetaDataParams &other) const return !(*this == other); } - FilmNegativeParams::FilmNegativeParams() : enabled(false), redExp(2.72), @@ -2757,10 +2756,6 @@ bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const return !(*this == other); } - - - - ProcParams::ProcParams() { setDefaults(); @@ -3598,7 +3593,6 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->filmNegative.greenExp, "Film Negative", "GreenExponent", filmNegative.greenExp, keyFile); saveToKeyfile(!pedited || pedited->filmNegative.blueExp, "Film Negative", "BlueExponent", filmNegative.blueExp, keyFile); - // EXIF change list if (!pedited || pedited->exif) { for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) { @@ -5149,7 +5143,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Film Negative", "BlueExponent", pedited, filmNegative.blueExp, pedited->filmNegative.blueExp); } - if (keyFile.has_group("MetaData")) { int mode = int(MetaDataParams::TUNNEL); assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode); @@ -5272,7 +5265,8 @@ bool ProcParams::operator ==(const ProcParams& other) const && metadata == other.metadata && exif == other.exif && iptc == other.iptc - && dehaze == other.dehaze; + && dehaze == other.dehaze + && filmNegative == other.filmNegative; } bool ProcParams::operator !=(const ProcParams& other) const diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 3f9ff0342..2af018035 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -728,7 +728,6 @@ struct DirPyrDenoiseParams { bool operator !=(const DirPyrDenoiseParams& other) const; void getCurves(NoiseCurve& lCurve, NoiseCurve& cCurve) const; - }; // EPD related parameters. @@ -1056,7 +1055,6 @@ struct ColorManagementParams { bool operator !=(const ColorManagementParams& other) const; }; - /** * Parameters for metadata handling */ @@ -1295,7 +1293,6 @@ struct HSVEqualizerParams { bool operator !=(const HSVEqualizerParams& other) const; }; - /** * Film simualtion params */ @@ -1310,7 +1307,6 @@ struct FilmSimulationParams { bool operator !=(const FilmSimulationParams& other) const; }; - struct SoftLightParams { bool enabled; int strength; @@ -1334,7 +1330,6 @@ struct DehazeParams { bool operator!=(const DehazeParams &other) const; }; - /** * Parameters for RAW demosaicing, common to all sensor type */ @@ -1501,7 +1496,6 @@ struct RAWParams { static Glib::ustring getFlatFieldBlurTypeString(FlatFieldBlurType type); }; - /** * Parameters of film negative */ @@ -1517,7 +1511,6 @@ struct FilmNegativeParams { bool operator !=(const FilmNegativeParams& other) const; }; - /** * This class holds all the processing parameters applied on the images */ @@ -1566,6 +1559,7 @@ public: FilmSimulationParams filmSimulation; ///< film simulation parameters SoftLightParams softlight; ///< softlight parameters DehazeParams dehaze; ///< dehaze parameters + FilmNegativeParams filmNegative; ///< Film negative parameters int rank; ///< Custom image quality ranking int colorlabel; ///< Custom color label bool inTrash; ///< Marks deleted image @@ -1576,8 +1570,6 @@ public: ExifPairs exif; ///< List of modifications appplied on the exif tags of the input image IPTCPairs iptc; ///< The IPTC tags and values to be saved to the output image - FilmNegativeParams filmNegative; ///< Film negative parameters - /** * The constructor only sets the hand-wired defaults. */ diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 56fec7146..6e039e7f8 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -36,7 +36,6 @@ namespace rtengine class RawImageSource : public ImageSource { - private: static DiagonalCurve *phaseOneIccCurve; static DiagonalCurve *phaseOneIccCurveInv; @@ -46,7 +45,6 @@ private: int defTransform (int tran); bool channelsAvg(Coord spotPos, int spotSize, float avgs[3], const FilmNegativeParams ¶ms); - protected: MyMutex getImageMutex; // locks getImage @@ -110,7 +108,6 @@ protected: inline void getRowStartEnd (int x, int &start, int &end); static void getProfilePreprocParams(cmsHPROFILE in, float& gammafac, float& lineFac, float& lineSum); - public: RawImageSource (); ~RawImageSource () override; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index e270f093f..4bdaa6ff1 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -210,7 +210,7 @@ private: imgsrc->preprocess ( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); // After preprocess, run film negative processing if enabled - if(imgsrc->getSensorType() == ST_BAYER && params.filmNegative.enabled) { + if (imgsrc->getSensorType() == ST_BAYER && params.filmNegative.enabled) { imgsrc->filmNegativeProcess (params.filmNegative); } diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 4c775bdcc..bdd166938 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -8,7 +8,7 @@ set(CLISOURCEFILES paramsedited.cc pathutils.cc threadutils.cc - ) +) set(NONCLISOURCEFILES adjuster.cc @@ -43,6 +43,7 @@ set(NONCLISOURCEFILES curveeditorgroup.cc darkframe.cc defringe.cc + dehaze.cc diagonalcurveeditorsubgroup.cc dirbrowser.cc dirpyrdenoise.cc @@ -55,15 +56,18 @@ set(NONCLISOURCEFILES editwidgets.cc editwindow.cc epd.cc + eventmapper.cc exiffiltersettings.cc exifpanel.cc exportpanel.cc extprog.cc + fattaltonemap.cc filebrowser.cc filebrowserentry.cc filecatalog.cc filepanel.cc filethumbnailbuttonset.cc + filmnegative.cc filmsimulation.cc filterpanel.cc flatcurveeditorsubgroup.cc @@ -83,12 +87,15 @@ set(NONCLISOURCEFILES inspector.cc iptcpanel.cc labcurve.cc + labgrid.cc lensgeom.cc lensprofile.cc + localcontrast.cc lockablecolorpicker.cc lwbutton.cc lwbuttonset.cc main.cc + metadatapanel.cc multilangmgr.cc mycurve.cc mydiagonalcurve.cc @@ -122,8 +129,8 @@ set(NONCLISOURCEFILES rgbcurves.cc rotate.cc rtimage.cc - rtsurface.cc rtscalable.cc + rtsurface.cc rtwindow.cc saveasdlg.cc saveformatpanel.cc @@ -134,6 +141,7 @@ set(NONCLISOURCEFILES sharpening.cc sharpenmicro.cc shcselector.cc + softlight.cc soundman.cc splash.cc threadutils.cc @@ -154,15 +162,7 @@ set(NONCLISOURCEFILES xtransprocess.cc xtransrawexposure.cc zoompanel.cc - fattaltonemap.cc - localcontrast.cc - eventmapper.cc - metadatapanel.cc - labgrid.cc - softlight.cc - dehaze.cc - filmnegative.cc - ) +) include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 3a5ab041a..7d52d309a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1163,15 +1163,15 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng bool dontforceSet = !forceSet; if (toneCurve.curve) { - toEdit.toneCurve.curve = mods.toneCurve.curve; + toEdit.toneCurve.curve = mods.toneCurve.curve; } if (toneCurve.curve2) { - toEdit.toneCurve.curve2 = mods.toneCurve.curve2; + toEdit.toneCurve.curve2 = mods.toneCurve.curve2; } if (toneCurve.curveMode) { - toEdit.toneCurve.curveMode = mods.toneCurve.curveMode; + toEdit.toneCurve.curveMode = mods.toneCurve.curveMode; } if (toneCurve.curveMode2) { @@ -1183,11 +1183,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (toneCurve.black) { - toEdit.toneCurve.black = dontforceSet && options.baBehav[ADDSET_TC_BLACKLEVEL] ? toEdit.toneCurve.black + mods.toneCurve.black : mods.toneCurve.black; + toEdit.toneCurve.black = dontforceSet && options.baBehav[ADDSET_TC_BLACKLEVEL] ? toEdit.toneCurve.black + mods.toneCurve.black : mods.toneCurve.black; } if (toneCurve.contrast) { - toEdit.toneCurve.contrast = dontforceSet && options.baBehav[ADDSET_TC_CONTRAST] ? toEdit.toneCurve.contrast + mods.toneCurve.contrast : mods.toneCurve.contrast; + toEdit.toneCurve.contrast = dontforceSet && options.baBehav[ADDSET_TC_CONTRAST] ? toEdit.toneCurve.contrast + mods.toneCurve.contrast : mods.toneCurve.contrast; } if (toneCurve.saturation) { @@ -1195,43 +1195,43 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (toneCurve.shcompr) { - toEdit.toneCurve.shcompr = dontforceSet && options.baBehav[ADDSET_TC_SHCOMP] ? toEdit.toneCurve.shcompr + mods.toneCurve.shcompr : mods.toneCurve.shcompr; + toEdit.toneCurve.shcompr = dontforceSet && options.baBehav[ADDSET_TC_SHCOMP] ? toEdit.toneCurve.shcompr + mods.toneCurve.shcompr : mods.toneCurve.shcompr; } if (toneCurve.autoexp) { - toEdit.toneCurve.autoexp = mods.toneCurve.autoexp; + toEdit.toneCurve.autoexp = mods.toneCurve.autoexp; } if (toneCurve.clip) { - toEdit.toneCurve.clip = mods.toneCurve.clip; + toEdit.toneCurve.clip = mods.toneCurve.clip; } if (toneCurve.expcomp) { - toEdit.toneCurve.expcomp = dontforceSet && options.baBehav[ADDSET_TC_EXPCOMP] ? toEdit.toneCurve.expcomp + mods.toneCurve.expcomp : mods.toneCurve.expcomp; + toEdit.toneCurve.expcomp = dontforceSet && options.baBehav[ADDSET_TC_EXPCOMP] ? toEdit.toneCurve.expcomp + mods.toneCurve.expcomp : mods.toneCurve.expcomp; } if (toneCurve.hlcompr) { - toEdit.toneCurve.hlcompr = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPAMOUNT] ? toEdit.toneCurve.hlcompr + mods.toneCurve.hlcompr : mods.toneCurve.hlcompr; + toEdit.toneCurve.hlcompr = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPAMOUNT] ? toEdit.toneCurve.hlcompr + mods.toneCurve.hlcompr : mods.toneCurve.hlcompr; } if (toneCurve.hlcomprthresh) { - toEdit.toneCurve.hlcomprthresh = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPTHRESH] ? toEdit.toneCurve.hlcomprthresh + mods.toneCurve.hlcomprthresh : mods.toneCurve.hlcomprthresh; + toEdit.toneCurve.hlcomprthresh = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPTHRESH] ? toEdit.toneCurve.hlcomprthresh + mods.toneCurve.hlcomprthresh : mods.toneCurve.hlcomprthresh; } if (toneCurve.hrenabled) { - toEdit.toneCurve.hrenabled = mods.toneCurve.hrenabled; + toEdit.toneCurve.hrenabled = mods.toneCurve.hrenabled; } if (toneCurve.method) { - toEdit.toneCurve.method = mods.toneCurve.method; + toEdit.toneCurve.method = mods.toneCurve.method; } if (toneCurve.histmatching) { - toEdit.toneCurve.histmatching = mods.toneCurve.histmatching; + toEdit.toneCurve.histmatching = mods.toneCurve.histmatching; } if (toneCurve.fromHistMatching) { - toEdit.toneCurve.fromHistMatching = mods.toneCurve.fromHistMatching; + toEdit.toneCurve.fromHistMatching = mods.toneCurve.fromHistMatching; } if (toneCurve.clampOOG) { @@ -1239,132 +1239,132 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (retinex.enabled) { - toEdit.retinex.enabled = mods.retinex.enabled; + toEdit.retinex.enabled = mods.retinex.enabled; } if (retinex.cdcurve) { - toEdit.retinex.cdcurve = mods.retinex.cdcurve; + toEdit.retinex.cdcurve = mods.retinex.cdcurve; } if (retinex.mapcurve) { - toEdit.retinex.mapcurve = mods.retinex.mapcurve; + toEdit.retinex.mapcurve = mods.retinex.mapcurve; } if (retinex.cdHcurve) { - toEdit.retinex.cdHcurve = mods.retinex.cdHcurve; + toEdit.retinex.cdHcurve = mods.retinex.cdHcurve; } if (retinex.lhcurve) { - toEdit.retinex.lhcurve = mods.retinex.lhcurve; + toEdit.retinex.lhcurve = mods.retinex.lhcurve; } if (retinex.transmissionCurve) { - toEdit.retinex.transmissionCurve = mods.retinex.transmissionCurve; + toEdit.retinex.transmissionCurve = mods.retinex.transmissionCurve; } if (retinex.gaintransmissionCurve) { - toEdit.retinex.gaintransmissionCurve = mods.retinex.gaintransmissionCurve; + toEdit.retinex.gaintransmissionCurve = mods.retinex.gaintransmissionCurve; } if (retinex.retinexMethod) { - toEdit.retinex.retinexMethod = mods.retinex.retinexMethod; + toEdit.retinex.retinexMethod = mods.retinex.retinexMethod; } if (retinex.mapMethod) { - toEdit.retinex.mapMethod = mods.retinex.mapMethod; + toEdit.retinex.mapMethod = mods.retinex.mapMethod; } if (retinex.viewMethod) { - toEdit.retinex.viewMethod = mods.retinex.viewMethod; + toEdit.retinex.viewMethod = mods.retinex.viewMethod; } if (retinex.retinexcolorspace) { - toEdit.retinex.retinexcolorspace = mods.retinex.retinexcolorspace; + toEdit.retinex.retinexcolorspace = mods.retinex.retinexcolorspace; } if (retinex.gammaretinex) { - toEdit.retinex.gammaretinex = mods.retinex.gammaretinex; + toEdit.retinex.gammaretinex = mods.retinex.gammaretinex; } if (retinex.gam) { - toEdit.retinex.gam = dontforceSet && options.baBehav[ADDSET_RETI_GAM] ? toEdit.retinex.gam + mods.retinex.gam : mods.retinex.gam; + toEdit.retinex.gam = dontforceSet && options.baBehav[ADDSET_RETI_GAM] ? toEdit.retinex.gam + mods.retinex.gam : mods.retinex.gam; } if (retinex.slope) { - toEdit.retinex.slope = dontforceSet && options.baBehav[ADDSET_RETI_SLO] ? toEdit.retinex.slope + mods.retinex.slope : mods.retinex.slope; + toEdit.retinex.slope = dontforceSet && options.baBehav[ADDSET_RETI_SLO] ? toEdit.retinex.slope + mods.retinex.slope : mods.retinex.slope; } if (retinex.str) { - toEdit.retinex.str = dontforceSet && options.baBehav[ADDSET_RETI_STR] ? toEdit.retinex.str + mods.retinex.str : mods.retinex.str; + toEdit.retinex.str = dontforceSet && options.baBehav[ADDSET_RETI_STR] ? toEdit.retinex.str + mods.retinex.str : mods.retinex.str; } if (retinex.scal) { - toEdit.retinex.scal = mods.retinex.scal; + toEdit.retinex.scal = mods.retinex.scal; } if (retinex.iter) { - toEdit.retinex.iter = mods.retinex.iter; + toEdit.retinex.iter = mods.retinex.iter; } if (retinex.grad) { - toEdit.retinex.grad = mods.retinex.grad; + toEdit.retinex.grad = mods.retinex.grad; } if (retinex.grads) { - toEdit.retinex.grads = mods.retinex.grads; + toEdit.retinex.grads = mods.retinex.grads; } // if (retinex.scal) { -// toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal; +// toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal; // } if (retinex.medianmap) { - toEdit.retinex.medianmap = mods.retinex.medianmap; + toEdit.retinex.medianmap = mods.retinex.medianmap; } if (retinex.neigh) { - toEdit.retinex.neigh = dontforceSet && options.baBehav[ADDSET_RETI_NEIGH] ? toEdit.retinex.neigh + mods.retinex.neigh : mods.retinex.neigh; + toEdit.retinex.neigh = dontforceSet && options.baBehav[ADDSET_RETI_NEIGH] ? toEdit.retinex.neigh + mods.retinex.neigh : mods.retinex.neigh; } if (retinex.limd) { - toEdit.retinex.limd = dontforceSet && options.baBehav[ADDSET_RETI_LIMD] ? toEdit.retinex.limd + mods.retinex.limd : mods.retinex.limd; + toEdit.retinex.limd = dontforceSet && options.baBehav[ADDSET_RETI_LIMD] ? toEdit.retinex.limd + mods.retinex.limd : mods.retinex.limd; } if (retinex.highl) { - toEdit.retinex.highl = mods.retinex.highl; + toEdit.retinex.highl = mods.retinex.highl; } if (retinex.skal) { - toEdit.retinex.skal = mods.retinex.skal; + toEdit.retinex.skal = mods.retinex.skal; } if (retinex.offs) { - toEdit.retinex.offs = dontforceSet && options.baBehav[ADDSET_RETI_OFFS] ? toEdit.retinex.offs + mods.retinex.offs : mods.retinex.offs; + toEdit.retinex.offs = dontforceSet && options.baBehav[ADDSET_RETI_OFFS] ? toEdit.retinex.offs + mods.retinex.offs : mods.retinex.offs; } if (retinex.vart) { - toEdit.retinex.vart = dontforceSet && options.baBehav[ADDSET_RETI_VART] ? toEdit.retinex.vart + mods.retinex.vart : mods.retinex.vart; + toEdit.retinex.vart = dontforceSet && options.baBehav[ADDSET_RETI_VART] ? toEdit.retinex.vart + mods.retinex.vart : mods.retinex.vart; } if (retinex.highlights) { - toEdit.retinex.highlights = mods.retinex.highlights; + toEdit.retinex.highlights = mods.retinex.highlights; } if (retinex.htonalwidth) { - toEdit.retinex.htonalwidth = mods.retinex.htonalwidth; + toEdit.retinex.htonalwidth = mods.retinex.htonalwidth; } if (retinex.shadows) { - toEdit.retinex.shadows = mods.retinex.shadows; + toEdit.retinex.shadows = mods.retinex.shadows; } if (retinex.stonalwidth) { - toEdit.retinex.stonalwidth = mods.retinex.stonalwidth; + toEdit.retinex.stonalwidth = mods.retinex.stonalwidth; } if (retinex.radius) { - toEdit.retinex.radius = mods.retinex.radius; + toEdit.retinex.radius = mods.retinex.radius; } @@ -1373,47 +1373,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (labCurve.lcurve) { - toEdit.labCurve.lcurve = mods.labCurve.lcurve; + toEdit.labCurve.lcurve = mods.labCurve.lcurve; } if (labCurve.acurve) { - toEdit.labCurve.acurve = mods.labCurve.acurve; + toEdit.labCurve.acurve = mods.labCurve.acurve; } if (labCurve.bcurve) { - toEdit.labCurve.bcurve = mods.labCurve.bcurve; + toEdit.labCurve.bcurve = mods.labCurve.bcurve; } if (labCurve.cccurve) { - toEdit.labCurve.cccurve = mods.labCurve.cccurve; + toEdit.labCurve.cccurve = mods.labCurve.cccurve; } if (labCurve.chcurve) { - toEdit.labCurve.chcurve = mods.labCurve.chcurve; + toEdit.labCurve.chcurve = mods.labCurve.chcurve; } if (labCurve.lhcurve) { - toEdit.labCurve.lhcurve = mods.labCurve.lhcurve; + toEdit.labCurve.lhcurve = mods.labCurve.lhcurve; } if (labCurve.hhcurve) { - toEdit.labCurve.hhcurve = mods.labCurve.hhcurve; + toEdit.labCurve.hhcurve = mods.labCurve.hhcurve; } if (labCurve.lccurve) { - toEdit.labCurve.lccurve = mods.labCurve.lccurve; + toEdit.labCurve.lccurve = mods.labCurve.lccurve; } if (labCurve.clcurve) { - toEdit.labCurve.clcurve = mods.labCurve.clcurve; + toEdit.labCurve.clcurve = mods.labCurve.clcurve; } if (labCurve.brightness) { - toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness; + toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness; } if (labCurve.contrast) { - toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; + toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; } if (labCurve.chromaticity) { @@ -1429,7 +1429,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (labCurve.lcredsk) { - toEdit.labCurve.lcredsk = mods.labCurve.lcredsk; + toEdit.labCurve.lcredsk = mods.labCurve.lcredsk; } if (localContrast.enabled) { @@ -1454,23 +1454,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (rgbCurves.lumamode) { - toEdit.rgbCurves.lumamode = mods.rgbCurves.lumamode; + toEdit.rgbCurves.lumamode = mods.rgbCurves.lumamode; } if (rgbCurves.rcurve) { - toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve; + toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve; } if (rgbCurves.gcurve) { - toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve; + toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve; } if (rgbCurves.bcurve) { - toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve; + toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve; } if (colorToning.enabled) { - toEdit.colorToning.enabled = mods.colorToning.enabled; + toEdit.colorToning.enabled = mods.colorToning.enabled; } if (colorToning.twocolor) { @@ -1478,7 +1478,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.opacityCurve) { - toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; + toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; } if (colorToning.colorCurve) { @@ -1486,11 +1486,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.enabled) { - toEdit.colorToning.enabled = mods.colorToning.enabled; + toEdit.colorToning.enabled = mods.colorToning.enabled; } if (colorToning.opacityCurve) { - toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; + toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; } if (colorToning.satprotectionthreshold) { @@ -1498,7 +1498,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.autosat) { - toEdit.colorToning.autosat = mods.colorToning.autosat; + toEdit.colorToning.autosat = mods.colorToning.autosat; } if (colorToning.saturatedopacity) { @@ -1506,23 +1506,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.strength) { - toEdit.colorToning.strength = dontforceSet && options.baBehav[ADDSET_COLORTONING_STRENGTH] ? toEdit.colorToning.strength + mods.colorToning.strength : mods.colorToning.strength; + toEdit.colorToning.strength = dontforceSet && options.baBehav[ADDSET_COLORTONING_STRENGTH] ? toEdit.colorToning.strength + mods.colorToning.strength : mods.colorToning.strength; } if (colorToning.shadowsColSat) { - toEdit.colorToning.shadowsColSat = mods.colorToning.shadowsColSat; + toEdit.colorToning.shadowsColSat = mods.colorToning.shadowsColSat; } if (colorToning.hlColSat) { - toEdit.colorToning.hlColSat = mods.colorToning.hlColSat; + toEdit.colorToning.hlColSat = mods.colorToning.hlColSat; } if (colorToning.balance) { - toEdit.colorToning.balance = dontforceSet && options.baBehav[ADDSET_COLORTONING_BALANCE] ? toEdit.colorToning.balance + mods.colorToning.balance : mods.colorToning.balance; + toEdit.colorToning.balance = dontforceSet && options.baBehav[ADDSET_COLORTONING_BALANCE] ? toEdit.colorToning.balance + mods.colorToning.balance : mods.colorToning.balance; } if (colorToning.clcurve) { - toEdit.colorToning.clcurve = mods.colorToning.clcurve; + toEdit.colorToning.clcurve = mods.colorToning.clcurve; } if (colorToning.method) { @@ -1530,11 +1530,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.cl2curve) { - toEdit.colorToning.cl2curve = mods.colorToning.cl2curve; + toEdit.colorToning.cl2curve = mods.colorToning.cl2curve; } if (colorToning.lumamode) { - toEdit.colorToning.lumamode = mods.colorToning.lumamode; + toEdit.colorToning.lumamode = mods.colorToning.lumamode; } if (colorToning.satlow) { @@ -1542,7 +1542,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.sathigh) { - toEdit.colorToning.sathigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.sathigh + mods.colorToning.sathigh : mods.colorToning.sathigh; + toEdit.colorToning.sathigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.sathigh + mods.colorToning.sathigh : mods.colorToning.sathigh; } if (colorToning.redlow) { @@ -1550,11 +1550,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.greenlow) { - toEdit.colorToning.greenlow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenlow + mods.colorToning.greenlow : mods.colorToning.greenlow; + toEdit.colorToning.greenlow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenlow + mods.colorToning.greenlow : mods.colorToning.greenlow; } if (colorToning.bluelow) { - toEdit.colorToning.bluelow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluelow + mods.colorToning.bluelow : mods.colorToning.bluelow; + toEdit.colorToning.bluelow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluelow + mods.colorToning.bluelow : mods.colorToning.bluelow; } if (colorToning.redmed) { @@ -1562,15 +1562,15 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.greenmed) { - toEdit.colorToning.greenmed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenmed + mods.colorToning.greenmed : mods.colorToning.greenmed; + toEdit.colorToning.greenmed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenmed + mods.colorToning.greenmed : mods.colorToning.greenmed; } if (colorToning.bluemed) { - toEdit.colorToning.bluemed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluemed + mods.colorToning.bluemed : mods.colorToning.bluemed; + toEdit.colorToning.bluemed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluemed + mods.colorToning.bluemed : mods.colorToning.bluemed; } if (colorToning.redhigh) { - toEdit.colorToning.redhigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.redhigh + mods.colorToning.redhigh : mods.colorToning.redhigh; + toEdit.colorToning.redhigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.redhigh + mods.colorToning.redhigh : mods.colorToning.redhigh; } if (colorToning.greenhigh) { @@ -1578,7 +1578,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.bluehigh) { - toEdit.colorToning.bluehigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluehigh + mods.colorToning.bluehigh : mods.colorToning.bluehigh; + toEdit.colorToning.bluehigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluehigh + mods.colorToning.bluehigh : mods.colorToning.bluehigh; } if (colorToning.labgridALow) { @@ -1606,7 +1606,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpenEdge.enabled) { - toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; + toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; } if (sharpenEdge.passes) { @@ -1618,47 +1618,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpenEdge.threechannels) { - toEdit.sharpenEdge.threechannels = mods.sharpenEdge.threechannels; + toEdit.sharpenEdge.threechannels = mods.sharpenEdge.threechannels; } if (sharpenMicro.enabled) { - toEdit.sharpenMicro.enabled = mods.sharpenMicro.enabled; + toEdit.sharpenMicro.enabled = mods.sharpenMicro.enabled; } if (sharpenMicro.matrix) { - toEdit.sharpenMicro.matrix = mods.sharpenMicro.matrix; + toEdit.sharpenMicro.matrix = mods.sharpenMicro.matrix; } if (sharpenMicro.amount) { - toEdit.sharpenMicro.amount = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_AMOUNT] ? toEdit.sharpenMicro.amount + mods.sharpenMicro.amount : mods.sharpenMicro.amount; + toEdit.sharpenMicro.amount = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_AMOUNT] ? toEdit.sharpenMicro.amount + mods.sharpenMicro.amount : mods.sharpenMicro.amount; } if (sharpenMicro.contrast) { - toEdit.sharpenMicro.contrast = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_CONTRAST] ? toEdit.sharpenMicro.contrast + mods.sharpenMicro.contrast : mods.sharpenMicro.contrast; + toEdit.sharpenMicro.contrast = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_CONTRAST] ? toEdit.sharpenMicro.contrast + mods.sharpenMicro.contrast : mods.sharpenMicro.contrast; } if (sharpenMicro.uniformity) { - toEdit.sharpenMicro.uniformity = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY] ? toEdit.sharpenMicro.uniformity + mods.sharpenMicro.uniformity : mods.sharpenMicro.uniformity; + toEdit.sharpenMicro.uniformity = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY] ? toEdit.sharpenMicro.uniformity + mods.sharpenMicro.uniformity : mods.sharpenMicro.uniformity; } if (sharpening.enabled) { - toEdit.sharpening.enabled = mods.sharpening.enabled; + toEdit.sharpening.enabled = mods.sharpening.enabled; } if (sharpening.contrast) { - toEdit.sharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.sharpening.contrast + mods.sharpening.contrast : mods.sharpening.contrast; + toEdit.sharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.sharpening.contrast + mods.sharpening.contrast : mods.sharpening.contrast; } if (sharpening.radius) { - toEdit.sharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.radius + mods.sharpening.radius : mods.sharpening.radius; + 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; + 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; + toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount; } if (sharpening.threshold) { @@ -1666,7 +1666,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpening.edgesonly) { - toEdit.sharpening.edgesonly = mods.sharpening.edgesonly; + toEdit.sharpening.edgesonly = mods.sharpening.edgesonly; } if (sharpening.edges_radius) { @@ -1686,19 +1686,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpening.method) { - toEdit.sharpening.method = mods.sharpening.method; + toEdit.sharpening.method = mods.sharpening.method; } if (sharpening.deconvamount) { - toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount; + toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount; } if (sharpening.deconvradius) { - toEdit.sharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.deconvradius + mods.sharpening.deconvradius : mods.sharpening.deconvradius; + toEdit.sharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.deconvradius + mods.sharpening.deconvradius : mods.sharpening.deconvradius; } if (sharpening.deconviter) { - toEdit.sharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.sharpening.deconviter + mods.sharpening.deconviter : mods.sharpening.deconviter; + toEdit.sharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.sharpening.deconviter + mods.sharpening.deconviter : mods.sharpening.deconviter; } if (sharpening.deconvdamping) { @@ -1706,19 +1706,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.enabled) { - toEdit.prsharpening.enabled = mods.prsharpening.enabled; + toEdit.prsharpening.enabled = mods.prsharpening.enabled; } if (prsharpening.contrast) { - toEdit.prsharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.prsharpening.contrast + mods.prsharpening.contrast : mods.prsharpening.contrast; + toEdit.prsharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.prsharpening.contrast + mods.prsharpening.contrast : mods.prsharpening.contrast; } if (prsharpening.radius) { - toEdit.prsharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.radius + mods.prsharpening.radius : mods.prsharpening.radius; + toEdit.prsharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.radius + mods.prsharpening.radius : mods.prsharpening.radius; } if (prsharpening.amount) { - toEdit.prsharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.amount + mods.prsharpening.amount : mods.prsharpening.amount; + toEdit.prsharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.amount + mods.prsharpening.amount : mods.prsharpening.amount; } if (prsharpening.threshold) { @@ -1726,11 +1726,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.edgesonly) { - toEdit.prsharpening.edgesonly = mods.prsharpening.edgesonly; + toEdit.prsharpening.edgesonly = mods.prsharpening.edgesonly; } if (prsharpening.edges_radius) { - toEdit.prsharpening.edges_radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.edges_radius + mods.prsharpening.edges_radius : mods.prsharpening.edges_radius; + toEdit.prsharpening.edges_radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.edges_radius + mods.prsharpening.edges_radius : mods.prsharpening.edges_radius; } if (prsharpening.edges_tolerance) { @@ -1738,7 +1738,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.halocontrol) { - toEdit.prsharpening.halocontrol = mods.prsharpening.halocontrol; + toEdit.prsharpening.halocontrol = mods.prsharpening.halocontrol; } if (prsharpening.halocontrol_amount) { @@ -1746,19 +1746,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.method) { - toEdit.prsharpening.method = mods.prsharpening.method; + toEdit.prsharpening.method = mods.prsharpening.method; } if (prsharpening.deconvamount) { - toEdit.prsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.deconvamount + mods.prsharpening.deconvamount : mods.prsharpening.deconvamount; + toEdit.prsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.deconvamount + mods.prsharpening.deconvamount : mods.prsharpening.deconvamount; } if (prsharpening.deconvradius) { - toEdit.prsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.deconvradius + mods.prsharpening.deconvradius : mods.prsharpening.deconvradius; + toEdit.prsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.deconvradius + mods.prsharpening.deconvradius : mods.prsharpening.deconvradius; } if (prsharpening.deconviter) { - toEdit.prsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.prsharpening.deconviter + mods.prsharpening.deconviter : mods.prsharpening.deconviter; + toEdit.prsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.prsharpening.deconviter + mods.prsharpening.deconviter : mods.prsharpening.deconviter; } if (prsharpening.deconvdamping) { @@ -1766,79 +1766,79 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (vibrance.enabled) { - toEdit.vibrance.enabled = mods.vibrance.enabled; + toEdit.vibrance.enabled = mods.vibrance.enabled; } if (vibrance.pastels) { - toEdit.vibrance.pastels = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PASTELS] ? toEdit.vibrance.pastels + mods.vibrance.pastels : mods.vibrance.pastels; + toEdit.vibrance.pastels = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PASTELS] ? toEdit.vibrance.pastels + mods.vibrance.pastels : mods.vibrance.pastels; } if (vibrance.saturated) { - toEdit.vibrance.saturated = dontforceSet && options.baBehav[ADDSET_VIBRANCE_SATURATED] ? toEdit.vibrance.saturated + mods.vibrance.saturated : mods.vibrance.saturated; + toEdit.vibrance.saturated = dontforceSet && options.baBehav[ADDSET_VIBRANCE_SATURATED] ? toEdit.vibrance.saturated + mods.vibrance.saturated : mods.vibrance.saturated; } if (vibrance.psthreshold) { - toEdit.vibrance.psthreshold = mods.vibrance.psthreshold; + toEdit.vibrance.psthreshold = mods.vibrance.psthreshold; } if (vibrance.protectskins) { - toEdit.vibrance.protectskins = mods.vibrance.protectskins; + toEdit.vibrance.protectskins = mods.vibrance.protectskins; } if (vibrance.avoidcolorshift) { - toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift; + toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift; } if (vibrance.pastsattog) { - toEdit.vibrance.pastsattog = mods.vibrance.pastsattog; + toEdit.vibrance.pastsattog = mods.vibrance.pastsattog; } if (vibrance.skintonescurve) { - toEdit.vibrance.skintonescurve = mods.vibrance.skintonescurve; + toEdit.vibrance.skintonescurve = mods.vibrance.skintonescurve; } - //if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount; - //if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip; - //if (colorBoost.enable_saturationlimiter)toEdit.colorBoost.enable_saturationlimiter = mods.colorBoost.enable_saturationlimiter; - //if (colorBoost.saturationlimit) toEdit.colorBoost.saturationlimit = mods.colorBoost.saturationlimit; + //if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount; + //if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip; + //if (colorBoost.enable_saturationlimiter)toEdit.colorBoost.enable_saturationlimiter = mods.colorBoost.enable_saturationlimiter; + //if (colorBoost.saturationlimit) toEdit.colorBoost.saturationlimit = mods.colorBoost.saturationlimit; if (wb.enabled) { toEdit.wb.enabled = mods.wb.enabled; } if (wb.method) { - toEdit.wb.method = mods.wb.method; + toEdit.wb.method = mods.wb.method; } if (wb.equal) { - toEdit.wb.equal = dontforceSet && options.baBehav[ADDSET_WB_EQUAL] ? toEdit.wb.equal + mods.wb.equal : mods.wb.equal; + toEdit.wb.equal = dontforceSet && options.baBehav[ADDSET_WB_EQUAL] ? toEdit.wb.equal + mods.wb.equal : mods.wb.equal; } if (wb.tempBias) { - toEdit.wb.tempBias = dontforceSet && options.baBehav[ADDSET_WB_TEMPBIAS] ? toEdit.wb.tempBias + mods.wb.tempBias : mods.wb.tempBias; + toEdit.wb.tempBias = dontforceSet && options.baBehav[ADDSET_WB_TEMPBIAS] ? toEdit.wb.tempBias + mods.wb.tempBias : mods.wb.tempBias; } if (wb.green) { - toEdit.wb.green = dontforceSet && options.baBehav[ADDSET_WB_GREEN] ? toEdit.wb.green + mods.wb.green : mods.wb.green; + toEdit.wb.green = dontforceSet && options.baBehav[ADDSET_WB_GREEN] ? toEdit.wb.green + mods.wb.green : mods.wb.green; } if (wb.temperature) { - toEdit.wb.temperature = dontforceSet && options.baBehav[ADDSET_WB_TEMPERATURE] ? toEdit.wb.temperature + mods.wb.temperature : mods.wb.temperature; + toEdit.wb.temperature = dontforceSet && options.baBehav[ADDSET_WB_TEMPERATURE] ? toEdit.wb.temperature + mods.wb.temperature : mods.wb.temperature; } - //if (colorShift.a) toEdit.colorShift.a = dontforceSet && options.baBehav[ADDSET_CS_BLUEYELLOW] ? toEdit.colorShift.a + mods.colorShift.a : mods.colorShift.a; - //if (colorShift.b) toEdit.colorShift.b = dontforceSet && options.baBehav[ADDSET_CS_GREENMAGENTA] ? toEdit.colorShift.b + mods.colorShift.b : mods.colorShift.b; - //if (lumaDenoise.enabled) toEdit.lumaDenoise.enabled = mods.lumaDenoise.enabled; - //if (lumaDenoise.radius) toEdit.lumaDenoise.radius = mods.lumaDenoise.radius; - //if (lumaDenoise.edgetolerance) toEdit.lumaDenoise.edgetolerance = dontforceSet && options.baBehav[ADDSET_LD_EDGETOLERANCE] ? toEdit.lumaDenoise.edgetolerance + mods.lumaDenoise.edgetolerance : mods.lumaDenoise.edgetolerance; - //if (colorDenoise.enabled) toEdit.colorDenoise.enabled = mods.colorDenoise.enabled; - //if (colorDenoise.amount) toEdit.colorDenoise.amount = mods.colorDenoise.amount; + //if (colorShift.a) toEdit.colorShift.a = dontforceSet && options.baBehav[ADDSET_CS_BLUEYELLOW] ? toEdit.colorShift.a + mods.colorShift.a : mods.colorShift.a; + //if (colorShift.b) toEdit.colorShift.b = dontforceSet && options.baBehav[ADDSET_CS_GREENMAGENTA] ? toEdit.colorShift.b + mods.colorShift.b : mods.colorShift.b; + //if (lumaDenoise.enabled) toEdit.lumaDenoise.enabled = mods.lumaDenoise.enabled; + //if (lumaDenoise.radius) toEdit.lumaDenoise.radius = mods.lumaDenoise.radius; + //if (lumaDenoise.edgetolerance) toEdit.lumaDenoise.edgetolerance = dontforceSet && options.baBehav[ADDSET_LD_EDGETOLERANCE] ? toEdit.lumaDenoise.edgetolerance + mods.lumaDenoise.edgetolerance : mods.lumaDenoise.edgetolerance; + //if (colorDenoise.enabled) toEdit.colorDenoise.enabled = mods.colorDenoise.enabled; + //if (colorDenoise.amount) toEdit.colorDenoise.amount = mods.colorDenoise.amount; if (defringe.enabled) { - toEdit.defringe.enabled = mods.defringe.enabled; + toEdit.defringe.enabled = mods.defringe.enabled; } if (defringe.radius) { - toEdit.defringe.radius = mods.defringe.radius; + toEdit.defringe.radius = mods.defringe.radius; } if (defringe.threshold) { @@ -1846,23 +1846,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (defringe.huecurve) { - toEdit.defringe.huecurve = mods.defringe.huecurve; + toEdit.defringe.huecurve = mods.defringe.huecurve; } if (colorappearance.curve) { - toEdit.colorappearance.curve = mods.colorappearance.curve; + toEdit.colorappearance.curve = mods.colorappearance.curve; } if (colorappearance.curve2) { - toEdit.colorappearance.curve2 = mods.colorappearance.curve2; + toEdit.colorappearance.curve2 = mods.colorappearance.curve2; } if (colorappearance.curve3) { - toEdit.colorappearance.curve3 = mods.colorappearance.curve3; + toEdit.colorappearance.curve3 = mods.colorappearance.curve3; } if (colorappearance.curveMode) { - toEdit.colorappearance.curveMode = mods.colorappearance.curveMode; + toEdit.colorappearance.curveMode = mods.colorappearance.curveMode; } if (colorappearance.curveMode2) { @@ -1874,11 +1874,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.enabled) { - toEdit.colorappearance.enabled = mods.colorappearance.enabled; + toEdit.colorappearance.enabled = mods.colorappearance.enabled; } if (colorappearance.degree) { - toEdit.colorappearance.degree = dontforceSet && options.baBehav[ADDSET_CAT_DEGREE] ? toEdit.colorappearance.degree + mods.colorappearance.degree : mods.colorappearance.degree; + toEdit.colorappearance.degree = dontforceSet && options.baBehav[ADDSET_CAT_DEGREE] ? toEdit.colorappearance.degree + mods.colorappearance.degree : mods.colorappearance.degree; } if (colorappearance.autodegree) { @@ -1886,7 +1886,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.degreeout) { - toEdit.colorappearance.degreeout = mods.colorappearance.degreeout; + toEdit.colorappearance.degreeout = mods.colorappearance.degreeout; } if (colorappearance.autodegreeout) { @@ -1894,95 +1894,95 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.surround) { - toEdit.colorappearance.surround = mods.colorappearance.surround; + toEdit.colorappearance.surround = mods.colorappearance.surround; } if (colorappearance.surrsrc) { - toEdit.colorappearance.surrsrc = mods.colorappearance.surrsrc; + toEdit.colorappearance.surrsrc = mods.colorappearance.surrsrc; } if (colorappearance.autoadapscen) { - toEdit.colorappearance.autoadapscen = mods.colorappearance.autoadapscen; + toEdit.colorappearance.autoadapscen = mods.colorappearance.autoadapscen; } if (colorappearance.adapscen) { - toEdit.colorappearance.adapscen = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTSCENE] ? toEdit.colorappearance.adapscen + mods.colorappearance.adapscen : mods.colorappearance.adapscen; + toEdit.colorappearance.adapscen = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTSCENE] ? toEdit.colorappearance.adapscen + mods.colorappearance.adapscen : mods.colorappearance.adapscen; } if (colorappearance.autoybscen) { - toEdit.colorappearance.autoybscen = mods.colorappearance.autoybscen; + toEdit.colorappearance.autoybscen = mods.colorappearance.autoybscen; } if (colorappearance.ybscen) { - toEdit.colorappearance.ybscen = mods.colorappearance.ybscen; + toEdit.colorappearance.ybscen = mods.colorappearance.ybscen; } if (colorappearance.adaplum) { - toEdit.colorappearance.adaplum = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTVIEWING] ? toEdit.colorappearance.adaplum + mods.colorappearance.adaplum : mods.colorappearance.adaplum; + toEdit.colorappearance.adaplum = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTVIEWING] ? toEdit.colorappearance.adaplum + mods.colorappearance.adaplum : mods.colorappearance.adaplum; } if (colorappearance.badpixsl) { - toEdit.colorappearance.badpixsl = dontforceSet && options.baBehav[ADDSET_CAT_BADPIX] ? toEdit.colorappearance.badpixsl + mods.colorappearance.badpixsl : mods.colorappearance.badpixsl; + toEdit.colorappearance.badpixsl = dontforceSet && options.baBehav[ADDSET_CAT_BADPIX] ? toEdit.colorappearance.badpixsl + mods.colorappearance.badpixsl : mods.colorappearance.badpixsl; } if (colorappearance.wbmodel) { - toEdit.colorappearance.wbmodel = mods.colorappearance.wbmodel; + toEdit.colorappearance.wbmodel = mods.colorappearance.wbmodel; } if (colorappearance.algo) { - toEdit.colorappearance.algo = mods.colorappearance.algo; + toEdit.colorappearance.algo = mods.colorappearance.algo; } if (colorappearance.tempout) { - toEdit.colorappearance.tempout = mods.colorappearance.tempout; + toEdit.colorappearance.tempout = mods.colorappearance.tempout; } if (colorappearance.greenout) { - toEdit.colorappearance.greenout = mods.colorappearance.greenout; + toEdit.colorappearance.greenout = mods.colorappearance.greenout; } if (colorappearance.tempsc) { - toEdit.colorappearance.tempsc = mods.colorappearance.tempsc; + toEdit.colorappearance.tempsc = mods.colorappearance.tempsc; } if (colorappearance.greensc) { - toEdit.colorappearance.greensc = mods.colorappearance.greensc; + toEdit.colorappearance.greensc = mods.colorappearance.greensc; } if (colorappearance.ybout) { - toEdit.colorappearance.ybout = mods.colorappearance.ybout; + toEdit.colorappearance.ybout = mods.colorappearance.ybout; } if (colorappearance.jlight) { - toEdit.colorappearance.jlight = dontforceSet && options.baBehav[ADDSET_CAT_LIGHT] ? toEdit.colorappearance.jlight + mods.colorappearance.jlight : mods.colorappearance.jlight; + toEdit.colorappearance.jlight = dontforceSet && options.baBehav[ADDSET_CAT_LIGHT] ? toEdit.colorappearance.jlight + mods.colorappearance.jlight : mods.colorappearance.jlight; } if (colorappearance.qbright) { - toEdit.colorappearance.qbright = dontforceSet && options.baBehav[ADDSET_CAT_BRIGHT] ? toEdit.colorappearance.qbright + mods.colorappearance.qbright : mods.colorappearance.qbright; + toEdit.colorappearance.qbright = dontforceSet && options.baBehav[ADDSET_CAT_BRIGHT] ? toEdit.colorappearance.qbright + mods.colorappearance.qbright : mods.colorappearance.qbright; } if (colorappearance.chroma) { - toEdit.colorappearance.chroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA] ? toEdit.colorappearance.chroma + mods.colorappearance.chroma : mods.colorappearance.chroma; + toEdit.colorappearance.chroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA] ? toEdit.colorappearance.chroma + mods.colorappearance.chroma : mods.colorappearance.chroma; } if (colorappearance.schroma) { - toEdit.colorappearance.schroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_S] ? toEdit.colorappearance.schroma + mods.colorappearance.schroma : mods.colorappearance.schroma; + toEdit.colorappearance.schroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_S] ? toEdit.colorappearance.schroma + mods.colorappearance.schroma : mods.colorappearance.schroma; } if (colorappearance.mchroma) { - toEdit.colorappearance.mchroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_M] ? toEdit.colorappearance.mchroma + mods.colorappearance.mchroma : mods.colorappearance.mchroma; + toEdit.colorappearance.mchroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_M] ? toEdit.colorappearance.mchroma + mods.colorappearance.mchroma : mods.colorappearance.mchroma; } if (colorappearance.contrast) { - toEdit.colorappearance.contrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST] ? toEdit.colorappearance.contrast + mods.colorappearance.contrast : mods.colorappearance.contrast; + toEdit.colorappearance.contrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST] ? toEdit.colorappearance.contrast + mods.colorappearance.contrast : mods.colorappearance.contrast; } if (colorappearance.qcontrast) { - toEdit.colorappearance.qcontrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST_Q] ? toEdit.colorappearance.qcontrast + mods.colorappearance.qcontrast : mods.colorappearance.qcontrast; + toEdit.colorappearance.qcontrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST_Q] ? toEdit.colorappearance.qcontrast + mods.colorappearance.qcontrast : mods.colorappearance.qcontrast; } if (colorappearance.colorh) { - toEdit.colorappearance.colorh = dontforceSet && options.baBehav[ADDSET_CAT_HUE] ? toEdit.colorappearance.colorh + mods.colorappearance.colorh : mods.colorappearance.colorh; + toEdit.colorappearance.colorh = dontforceSet && options.baBehav[ADDSET_CAT_HUE] ? toEdit.colorappearance.colorh + mods.colorappearance.colorh : mods.colorappearance.colorh; } if (colorappearance.rstprotection) { @@ -2008,47 +2008,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng // if (colorappearance.sharpcie) toEdit.colorappearance.sharpcie = mods.colorappearance.sharpcie; if (impulseDenoise.enabled) { - toEdit.impulseDenoise.enabled = mods.impulseDenoise.enabled; + toEdit.impulseDenoise.enabled = mods.impulseDenoise.enabled; } if (impulseDenoise.thresh) { - toEdit.impulseDenoise.thresh = mods.impulseDenoise.thresh; + toEdit.impulseDenoise.thresh = mods.impulseDenoise.thresh; } if (dirpyrDenoise.enabled) { - toEdit.dirpyrDenoise.enabled = mods.dirpyrDenoise.enabled; + toEdit.dirpyrDenoise.enabled = mods.dirpyrDenoise.enabled; } if (dirpyrDenoise.enhance) { - toEdit.dirpyrDenoise.enhance = mods.dirpyrDenoise.enhance; + toEdit.dirpyrDenoise.enhance = mods.dirpyrDenoise.enhance; } if (dirpyrDenoise.median) { - toEdit.dirpyrDenoise.median = mods.dirpyrDenoise.median; + toEdit.dirpyrDenoise.median = mods.dirpyrDenoise.median; } if (dirpyrDenoise.luma) { - toEdit.dirpyrDenoise.luma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMA] ? toEdit.dirpyrDenoise.luma + mods.dirpyrDenoise.luma : mods.dirpyrDenoise.luma; + toEdit.dirpyrDenoise.luma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMA] ? toEdit.dirpyrDenoise.luma + mods.dirpyrDenoise.luma : mods.dirpyrDenoise.luma; } if (dirpyrDenoise.lcurve) { - toEdit.dirpyrDenoise.lcurve = mods.dirpyrDenoise.lcurve; + toEdit.dirpyrDenoise.lcurve = mods.dirpyrDenoise.lcurve; } if (dirpyrDenoise.cccurve) { - toEdit.dirpyrDenoise.cccurve = mods.dirpyrDenoise.cccurve; + toEdit.dirpyrDenoise.cccurve = mods.dirpyrDenoise.cccurve; } if (dirpyrDenoise.Ldetail) { - toEdit.dirpyrDenoise.Ldetail = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMDET] ? toEdit.dirpyrDenoise.Ldetail + mods.dirpyrDenoise.Ldetail : mods.dirpyrDenoise.Ldetail; + toEdit.dirpyrDenoise.Ldetail = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMDET] ? toEdit.dirpyrDenoise.Ldetail + mods.dirpyrDenoise.Ldetail : mods.dirpyrDenoise.Ldetail; } if (dirpyrDenoise.chroma) { - toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMA] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma; + toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMA] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma; } if (dirpyrDenoise.redchro) { - toEdit.dirpyrDenoise.redchro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMARED] ? toEdit.dirpyrDenoise.redchro + mods.dirpyrDenoise.redchro : mods.dirpyrDenoise.redchro; + toEdit.dirpyrDenoise.redchro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMARED] ? toEdit.dirpyrDenoise.redchro + mods.dirpyrDenoise.redchro : mods.dirpyrDenoise.redchro; } if (dirpyrDenoise.bluechro) { @@ -2056,68 +2056,68 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (dirpyrDenoise.gamma) { - toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; + toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; } if (dirpyrDenoise.passes) { - toEdit.dirpyrDenoise.passes = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_PASSES] ? toEdit.dirpyrDenoise.passes + mods.dirpyrDenoise.passes : mods.dirpyrDenoise.passes; + toEdit.dirpyrDenoise.passes = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_PASSES] ? toEdit.dirpyrDenoise.passes + mods.dirpyrDenoise.passes : mods.dirpyrDenoise.passes; } -// if (dirpyrDenoise.perform) toEdit.dirpyrDenoise.perform = mods.dirpyrDenoise.perform; +// if (dirpyrDenoise.perform) toEdit.dirpyrDenoise.perform = mods.dirpyrDenoise.perform; if (dirpyrDenoise.dmethod) { - toEdit.dirpyrDenoise.dmethod = mods.dirpyrDenoise.dmethod; + toEdit.dirpyrDenoise.dmethod = mods.dirpyrDenoise.dmethod; } if (dirpyrDenoise.Lmethod) { - toEdit.dirpyrDenoise.Lmethod = mods.dirpyrDenoise.Lmethod; + toEdit.dirpyrDenoise.Lmethod = mods.dirpyrDenoise.Lmethod; } if (dirpyrDenoise.Cmethod) { - toEdit.dirpyrDenoise.Cmethod = mods.dirpyrDenoise.Cmethod; + toEdit.dirpyrDenoise.Cmethod = mods.dirpyrDenoise.Cmethod; } if (dirpyrDenoise.C2method) { - toEdit.dirpyrDenoise.C2method = mods.dirpyrDenoise.C2method; + toEdit.dirpyrDenoise.C2method = mods.dirpyrDenoise.C2method; } if (dirpyrDenoise.smethod) { - toEdit.dirpyrDenoise.smethod = mods.dirpyrDenoise.smethod; + toEdit.dirpyrDenoise.smethod = mods.dirpyrDenoise.smethod; } if (dirpyrDenoise.medmethod) { - toEdit.dirpyrDenoise.medmethod = mods.dirpyrDenoise.medmethod; + toEdit.dirpyrDenoise.medmethod = mods.dirpyrDenoise.medmethod; } if (dirpyrDenoise.methodmed) { - toEdit.dirpyrDenoise.methodmed = mods.dirpyrDenoise.methodmed; + toEdit.dirpyrDenoise.methodmed = mods.dirpyrDenoise.methodmed; } if (dirpyrDenoise.rgbmethod) { - toEdit.dirpyrDenoise.rgbmethod = mods.dirpyrDenoise.rgbmethod; + toEdit.dirpyrDenoise.rgbmethod = mods.dirpyrDenoise.rgbmethod; } if (epd.enabled) { - toEdit.epd.enabled = mods.epd.enabled; + toEdit.epd.enabled = mods.epd.enabled; } if (epd.strength) { - toEdit.epd.strength = mods.epd.strength; + toEdit.epd.strength = mods.epd.strength; } if (epd.gamma) { - toEdit.epd.gamma = mods.epd.gamma; + toEdit.epd.gamma = mods.epd.gamma; } if (epd.edgeStopping) { - toEdit.epd.edgeStopping = mods.epd.edgeStopping; + toEdit.epd.edgeStopping = mods.epd.edgeStopping; } if (epd.scale) { - toEdit.epd.scale = mods.epd.scale; + toEdit.epd.scale = mods.epd.scale; } if (epd.reweightingIterates) { - toEdit.epd.reweightingIterates = mods.epd.reweightingIterates; + toEdit.epd.reweightingIterates = mods.epd.reweightingIterates; } if (fattal.enabled) { @@ -2137,31 +2137,31 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sh.enabled) { - toEdit.sh.enabled = mods.sh.enabled; + toEdit.sh.enabled = mods.sh.enabled; } if (sh.highlights) { - toEdit.sh.highlights = dontforceSet && options.baBehav[ADDSET_SH_HIGHLIGHTS] ? toEdit.sh.highlights + mods.sh.highlights : mods.sh.highlights; + toEdit.sh.highlights = dontforceSet && options.baBehav[ADDSET_SH_HIGHLIGHTS] ? toEdit.sh.highlights + mods.sh.highlights : mods.sh.highlights; } if (sh.htonalwidth) { - toEdit.sh.htonalwidth = mods.sh.htonalwidth; + toEdit.sh.htonalwidth = mods.sh.htonalwidth; } if (sh.shadows) { - toEdit.sh.shadows = dontforceSet && options.baBehav[ADDSET_SH_SHADOWS] ? toEdit.sh.shadows + mods.sh.shadows : mods.sh.shadows; + toEdit.sh.shadows = dontforceSet && options.baBehav[ADDSET_SH_SHADOWS] ? toEdit.sh.shadows + mods.sh.shadows : mods.sh.shadows; } if (sh.stonalwidth) { - toEdit.sh.stonalwidth = mods.sh.stonalwidth; + toEdit.sh.stonalwidth = mods.sh.stonalwidth; } if (sh.radius) { - toEdit.sh.radius = mods.sh.radius; + toEdit.sh.radius = mods.sh.radius; } if (sh.lab) { - toEdit.sh.lab = mods.sh.lab; + toEdit.sh.lab = mods.sh.lab; } if (crop.enabled) { @@ -2169,27 +2169,27 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (crop.x) { - toEdit.crop.x = mods.crop.x; + toEdit.crop.x = mods.crop.x; } if (crop.y) { - toEdit.crop.y = mods.crop.y; + toEdit.crop.y = mods.crop.y; } if (crop.w) { - toEdit.crop.w = mods.crop.w; + toEdit.crop.w = mods.crop.w; } if (crop.h) { - toEdit.crop.h = mods.crop.h; + toEdit.crop.h = mods.crop.h; } if (crop.fixratio) { - toEdit.crop.fixratio = mods.crop.fixratio; + toEdit.crop.fixratio = mods.crop.fixratio; } if (crop.ratio) { - toEdit.crop.ratio = mods.crop.ratio; + toEdit.crop.ratio = mods.crop.ratio; } if (crop.orientation) { @@ -2197,51 +2197,51 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (crop.guide) { - toEdit.crop.guide = mods.crop.guide; + toEdit.crop.guide = mods.crop.guide; } if (coarse.rotate) { - toEdit.coarse.rotate = mods.coarse.rotate; + toEdit.coarse.rotate = mods.coarse.rotate; } if (coarse.hflip) { - toEdit.coarse.hflip = mods.coarse.hflip; + toEdit.coarse.hflip = mods.coarse.hflip; } if (coarse.vflip) { - toEdit.coarse.vflip = mods.coarse.vflip; + toEdit.coarse.vflip = mods.coarse.vflip; } if (commonTrans.autofill) { - toEdit.commonTrans.autofill = mods.commonTrans.autofill; + toEdit.commonTrans.autofill = mods.commonTrans.autofill; } if (rotate.degree) { - toEdit.rotate.degree = dontforceSet && options.baBehav[ADDSET_ROTATE_DEGREE] ? toEdit.rotate.degree + mods.rotate.degree : mods.rotate.degree; + toEdit.rotate.degree = dontforceSet && options.baBehav[ADDSET_ROTATE_DEGREE] ? toEdit.rotate.degree + mods.rotate.degree : mods.rotate.degree; } if (distortion.amount) { - toEdit.distortion.amount = dontforceSet && options.baBehav[ADDSET_DIST_AMOUNT] ? toEdit.distortion.amount + mods.distortion.amount : mods.distortion.amount; + toEdit.distortion.amount = dontforceSet && options.baBehav[ADDSET_DIST_AMOUNT] ? toEdit.distortion.amount + mods.distortion.amount : mods.distortion.amount; } if (lensProf.lcMode) { - toEdit.lensProf.lcMode = mods.lensProf.lcMode; + toEdit.lensProf.lcMode = mods.lensProf.lcMode; } if (lensProf.lcpFile) { - toEdit.lensProf.lcpFile = mods.lensProf.lcpFile; + toEdit.lensProf.lcpFile = mods.lensProf.lcpFile; } if (lensProf.useDist) { - toEdit.lensProf.useDist = mods.lensProf.useDist; + toEdit.lensProf.useDist = mods.lensProf.useDist; } if (lensProf.useVign) { - toEdit.lensProf.useVign = mods.lensProf.useVign; + toEdit.lensProf.useVign = mods.lensProf.useVign; } if (lensProf.useCA) { - toEdit.lensProf.useCA = mods.lensProf.useCA; + toEdit.lensProf.useCA = mods.lensProf.useCA; } if (lensProf.lfCameraMake) { @@ -2257,47 +2257,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (perspective.horizontal) { - toEdit.perspective.horizontal = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.horizontal + mods.perspective.horizontal : mods.perspective.horizontal; + toEdit.perspective.horizontal = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.horizontal + mods.perspective.horizontal : mods.perspective.horizontal; } if (perspective.vertical) { - toEdit.perspective.vertical = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.vertical + mods.perspective.vertical : mods.perspective.vertical; + toEdit.perspective.vertical = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.vertical + mods.perspective.vertical : mods.perspective.vertical; } if (gradient.enabled) { - toEdit.gradient.enabled = mods.gradient.enabled; + toEdit.gradient.enabled = mods.gradient.enabled; } if (gradient.degree) { - toEdit.gradient.degree = dontforceSet && options.baBehav[ADDSET_GRADIENT_DEGREE] ? toEdit.gradient.degree + mods.gradient.degree : mods.gradient.degree; + toEdit.gradient.degree = dontforceSet && options.baBehav[ADDSET_GRADIENT_DEGREE] ? toEdit.gradient.degree + mods.gradient.degree : mods.gradient.degree; } if (gradient.feather) { - toEdit.gradient.feather = dontforceSet && options.baBehav[ADDSET_GRADIENT_FEATHER] ? toEdit.gradient.feather + mods.gradient.feather : mods.gradient.feather; + toEdit.gradient.feather = dontforceSet && options.baBehav[ADDSET_GRADIENT_FEATHER] ? toEdit.gradient.feather + mods.gradient.feather : mods.gradient.feather; } if (gradient.strength) { - toEdit.gradient.strength = dontforceSet && options.baBehav[ADDSET_GRADIENT_STRENGTH] ? toEdit.gradient.strength + mods.gradient.strength : mods.gradient.strength; + toEdit.gradient.strength = dontforceSet && options.baBehav[ADDSET_GRADIENT_STRENGTH] ? toEdit.gradient.strength + mods.gradient.strength : mods.gradient.strength; } if (gradient.centerX) { - toEdit.gradient.centerX = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerX + mods.gradient.centerX : mods.gradient.centerX; + toEdit.gradient.centerX = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerX + mods.gradient.centerX : mods.gradient.centerX; } if (gradient.centerY) { - toEdit.gradient.centerY = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerY + mods.gradient.centerY : mods.gradient.centerY; + toEdit.gradient.centerY = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerY + mods.gradient.centerY : mods.gradient.centerY; } if (pcvignette.enabled) { - toEdit.pcvignette.enabled = mods.pcvignette.enabled; + toEdit.pcvignette.enabled = mods.pcvignette.enabled; } if (pcvignette.strength) { - toEdit.pcvignette.strength = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_STRENGTH] ? toEdit.pcvignette.strength + mods.pcvignette.strength : mods.pcvignette.strength; + toEdit.pcvignette.strength = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_STRENGTH] ? toEdit.pcvignette.strength + mods.pcvignette.strength : mods.pcvignette.strength; } if (pcvignette.feather) { - toEdit.pcvignette.feather = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_FEATHER] ? toEdit.pcvignette.feather + mods.pcvignette.feather : mods.pcvignette.feather; + toEdit.pcvignette.feather = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_FEATHER] ? toEdit.pcvignette.feather + mods.pcvignette.feather : mods.pcvignette.feather; } if (pcvignette.roundness) { @@ -2305,19 +2305,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (cacorrection.red) { - toEdit.cacorrection.red = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.red + mods.cacorrection.red : mods.cacorrection.red; + toEdit.cacorrection.red = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.red + mods.cacorrection.red : mods.cacorrection.red; } if (cacorrection.blue) { - toEdit.cacorrection.blue = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.blue + mods.cacorrection.blue : mods.cacorrection.blue; + toEdit.cacorrection.blue = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.blue + mods.cacorrection.blue : mods.cacorrection.blue; } if (vignetting.amount) { - toEdit.vignetting.amount = dontforceSet && options.baBehav[ADDSET_VIGN_AMOUNT] ? toEdit.vignetting.amount + mods.vignetting.amount : mods.vignetting.amount; + toEdit.vignetting.amount = dontforceSet && options.baBehav[ADDSET_VIGN_AMOUNT] ? toEdit.vignetting.amount + mods.vignetting.amount : mods.vignetting.amount; } if (vignetting.radius) { - toEdit.vignetting.radius = dontforceSet && options.baBehav[ADDSET_VIGN_RADIUS] ? toEdit.vignetting.radius + mods.vignetting.radius : mods.vignetting.radius; + toEdit.vignetting.radius = dontforceSet && options.baBehav[ADDSET_VIGN_RADIUS] ? toEdit.vignetting.radius + mods.vignetting.radius : mods.vignetting.radius; } if (vignetting.strength) { @@ -2338,92 +2338,92 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng for (int i = 0; i < 3; i++) { if (chmixer.red[i]) { - toEdit.chmixer.red[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.red[i] + mods.chmixer.red[i] : mods.chmixer.red[i]; + toEdit.chmixer.red[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.red[i] + mods.chmixer.red[i] : mods.chmixer.red[i]; } if (chmixer.green[i]) { - toEdit.chmixer.green[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.green[i] + mods.chmixer.green[i] : mods.chmixer.green[i]; + toEdit.chmixer.green[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.green[i] + mods.chmixer.green[i] : mods.chmixer.green[i]; } if (chmixer.blue[i]) { - toEdit.chmixer.blue[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.blue[i] + mods.chmixer.blue[i] : mods.chmixer.blue[i]; + toEdit.chmixer.blue[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.blue[i] + mods.chmixer.blue[i] : mods.chmixer.blue[i]; } } if (blackwhite.enabled) { - toEdit.blackwhite.enabled = mods.blackwhite.enabled; + toEdit.blackwhite.enabled = mods.blackwhite.enabled; } if (blackwhite.method) { - toEdit.blackwhite.method = mods.blackwhite.method; + toEdit.blackwhite.method = mods.blackwhite.method; } if (blackwhite.luminanceCurve) { - toEdit.blackwhite.luminanceCurve = mods.blackwhite.luminanceCurve; + toEdit.blackwhite.luminanceCurve = mods.blackwhite.luminanceCurve; } if (blackwhite.autoc) { - toEdit.blackwhite.autoc = mods.blackwhite.autoc; + toEdit.blackwhite.autoc = mods.blackwhite.autoc; } if (blackwhite.setting) { - toEdit.blackwhite.setting = mods.blackwhite.setting; + toEdit.blackwhite.setting = mods.blackwhite.setting; } if (blackwhite.enabledcc) { - toEdit.blackwhite.enabledcc = mods.blackwhite.enabledcc; + toEdit.blackwhite.enabledcc = mods.blackwhite.enabledcc; } if (blackwhite.filter) { - toEdit.blackwhite.filter = mods.blackwhite.filter; + toEdit.blackwhite.filter = mods.blackwhite.filter; } if (blackwhite.mixerRed) { - toEdit.blackwhite.mixerRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerRed + mods.blackwhite.mixerRed : mods.blackwhite.mixerRed; + toEdit.blackwhite.mixerRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerRed + mods.blackwhite.mixerRed : mods.blackwhite.mixerRed; } if (blackwhite.mixerOrange) { - toEdit.blackwhite.mixerOrange = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerOrange + mods.blackwhite.mixerOrange : mods.blackwhite.mixerOrange; + toEdit.blackwhite.mixerOrange = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerOrange + mods.blackwhite.mixerOrange : mods.blackwhite.mixerOrange; } if (blackwhite.mixerYellow) { - toEdit.blackwhite.mixerYellow = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerYellow + mods.blackwhite.mixerYellow : mods.blackwhite.mixerYellow; + toEdit.blackwhite.mixerYellow = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerYellow + mods.blackwhite.mixerYellow : mods.blackwhite.mixerYellow; } if (blackwhite.mixerGreen) { - toEdit.blackwhite.mixerGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerGreen + mods.blackwhite.mixerGreen : mods.blackwhite.mixerGreen; + toEdit.blackwhite.mixerGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerGreen + mods.blackwhite.mixerGreen : mods.blackwhite.mixerGreen; } if (blackwhite.mixerCyan) { - toEdit.blackwhite.mixerCyan = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerCyan + mods.blackwhite.mixerCyan : mods.blackwhite.mixerCyan; + toEdit.blackwhite.mixerCyan = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerCyan + mods.blackwhite.mixerCyan : mods.blackwhite.mixerCyan; } if (blackwhite.mixerBlue) { - toEdit.blackwhite.mixerBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerBlue + mods.blackwhite.mixerBlue : mods.blackwhite.mixerBlue; + toEdit.blackwhite.mixerBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerBlue + mods.blackwhite.mixerBlue : mods.blackwhite.mixerBlue; } if (blackwhite.mixerMagenta) { - toEdit.blackwhite.mixerMagenta = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerMagenta + mods.blackwhite.mixerMagenta : mods.blackwhite.mixerMagenta; + toEdit.blackwhite.mixerMagenta = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerMagenta + mods.blackwhite.mixerMagenta : mods.blackwhite.mixerMagenta; } if (blackwhite.mixerPurple) { - toEdit.blackwhite.mixerPurple = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerPurple + mods.blackwhite.mixerPurple : mods.blackwhite.mixerPurple; + toEdit.blackwhite.mixerPurple = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerPurple + mods.blackwhite.mixerPurple : mods.blackwhite.mixerPurple; } if (blackwhite.gammaRed) { - toEdit.blackwhite.gammaRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaRed + mods.blackwhite.gammaRed : mods.blackwhite.gammaRed; + toEdit.blackwhite.gammaRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaRed + mods.blackwhite.gammaRed : mods.blackwhite.gammaRed; } if (blackwhite.gammaGreen) { - toEdit.blackwhite.gammaGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaGreen + mods.blackwhite.gammaGreen : mods.blackwhite.gammaGreen; + toEdit.blackwhite.gammaGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaGreen + mods.blackwhite.gammaGreen : mods.blackwhite.gammaGreen; } if (blackwhite.gammaBlue) { - toEdit.blackwhite.gammaBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaBlue + mods.blackwhite.gammaBlue : mods.blackwhite.gammaBlue; + toEdit.blackwhite.gammaBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaBlue + mods.blackwhite.gammaBlue : mods.blackwhite.gammaBlue; } if (blackwhite.beforeCurve) { - toEdit.blackwhite.beforeCurve = mods.blackwhite.beforeCurve; + toEdit.blackwhite.beforeCurve = mods.blackwhite.beforeCurve; } if (blackwhite.beforeCurveMode) { @@ -2431,19 +2431,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (blackwhite.afterCurve) { - toEdit.blackwhite.afterCurve = mods.blackwhite.afterCurve; + toEdit.blackwhite.afterCurve = mods.blackwhite.afterCurve; } if (blackwhite.afterCurveMode) { - toEdit.blackwhite.afterCurveMode = mods.blackwhite.afterCurveMode; + toEdit.blackwhite.afterCurveMode = mods.blackwhite.afterCurveMode; } if (blackwhite.algo) { - toEdit.blackwhite.algo = mods.blackwhite.algo; + toEdit.blackwhite.algo = mods.blackwhite.algo; } if (resize.scale) { - toEdit.resize.scale = dontforceSet && options.baBehav[ADDSET_RESIZE_SCALE] ? toEdit.resize.scale + mods.resize.scale : mods.resize.scale; + toEdit.resize.scale = dontforceSet && options.baBehav[ADDSET_RESIZE_SCALE] ? toEdit.resize.scale + mods.resize.scale : mods.resize.scale; } if (resize.appliesTo) { @@ -2451,23 +2451,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (resize.method) { - toEdit.resize.method = mods.resize.method; + toEdit.resize.method = mods.resize.method; } if (resize.dataspec) { - toEdit.resize.dataspec = mods.resize.dataspec; + toEdit.resize.dataspec = mods.resize.dataspec; } if (resize.width) { - toEdit.resize.width = mods.resize.width; + toEdit.resize.width = mods.resize.width; } if (resize.height) { - toEdit.resize.height = mods.resize.height; + toEdit.resize.height = mods.resize.height; } if (resize.enabled) { - toEdit.resize.enabled = mods.resize.enabled; + toEdit.resize.enabled = mods.resize.enabled; } if (resize.allowUpscaling) { @@ -2527,47 +2527,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.bayersensor.method) { - toEdit.raw.bayersensor.method = mods.raw.bayersensor.method; + toEdit.raw.bayersensor.method = mods.raw.bayersensor.method; } if (raw.bayersensor.border) { - toEdit.raw.bayersensor.border = mods.raw.bayersensor.border; + toEdit.raw.bayersensor.border = mods.raw.bayersensor.border; } if (raw.bayersensor.imageNum) { - toEdit.raw.bayersensor.imageNum = mods.raw.bayersensor.imageNum; + toEdit.raw.bayersensor.imageNum = mods.raw.bayersensor.imageNum; } if (raw.bayersensor.ccSteps) { - toEdit.raw.bayersensor.ccSteps = mods.raw.bayersensor.ccSteps; + toEdit.raw.bayersensor.ccSteps = mods.raw.bayersensor.ccSteps; } if (raw.bayersensor.exBlack0) { - toEdit.raw.bayersensor.black0 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black0 + mods.raw.bayersensor.black0 : mods.raw.bayersensor.black0; + toEdit.raw.bayersensor.black0 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black0 + mods.raw.bayersensor.black0 : mods.raw.bayersensor.black0; } if (raw.bayersensor.exBlack1) { - toEdit.raw.bayersensor.black1 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black1 + mods.raw.bayersensor.black1 : mods.raw.bayersensor.black1; + toEdit.raw.bayersensor.black1 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black1 + mods.raw.bayersensor.black1 : mods.raw.bayersensor.black1; } if (raw.bayersensor.exBlack2) { - toEdit.raw.bayersensor.black2 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black2 + mods.raw.bayersensor.black2 : mods.raw.bayersensor.black2; + toEdit.raw.bayersensor.black2 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black2 + mods.raw.bayersensor.black2 : mods.raw.bayersensor.black2; } if (raw.bayersensor.exBlack3) { - toEdit.raw.bayersensor.black3 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black3 + mods.raw.bayersensor.black3 : mods.raw.bayersensor.black3; + toEdit.raw.bayersensor.black3 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black3 + mods.raw.bayersensor.black3 : mods.raw.bayersensor.black3; } if (raw.bayersensor.exTwoGreen) { - toEdit.raw.bayersensor.twogreen = mods.raw.bayersensor.twogreen; + toEdit.raw.bayersensor.twogreen = mods.raw.bayersensor.twogreen; } if (raw.bayersensor.dcbIterations) { - toEdit.raw.bayersensor.dcb_iterations = mods.raw.bayersensor.dcb_iterations; + toEdit.raw.bayersensor.dcb_iterations = mods.raw.bayersensor.dcb_iterations; } if (raw.bayersensor.dcbEnhance) { - toEdit.raw.bayersensor.dcb_enhance = mods.raw.bayersensor.dcb_enhance; + toEdit.raw.bayersensor.dcb_enhance = mods.raw.bayersensor.dcb_enhance; } if (raw.bayersensor.lmmseIterations) { @@ -2639,11 +2639,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.bayersensor.greenEq) { - toEdit.raw.bayersensor.greenthresh = dontforceSet && options.baBehav[ADDSET_PREPROCESS_GREENEQUIL] ? toEdit.raw.bayersensor.greenthresh + mods.raw.bayersensor.greenthresh : mods.raw.bayersensor.greenthresh; + toEdit.raw.bayersensor.greenthresh = dontforceSet && options.baBehav[ADDSET_PREPROCESS_GREENEQUIL] ? toEdit.raw.bayersensor.greenthresh + mods.raw.bayersensor.greenthresh : mods.raw.bayersensor.greenthresh; } if (raw.bayersensor.linenoise) { - toEdit.raw.bayersensor.linenoise = dontforceSet && options.baBehav[ADDSET_PREPROCESS_LINEDENOISE] ? toEdit.raw.bayersensor.linenoise + mods.raw.bayersensor.linenoise : mods.raw.bayersensor.linenoise; + toEdit.raw.bayersensor.linenoise = dontforceSet && options.baBehav[ADDSET_PREPROCESS_LINEDENOISE] ? toEdit.raw.bayersensor.linenoise + mods.raw.bayersensor.linenoise : mods.raw.bayersensor.linenoise; } if (raw.bayersensor.linenoiseDirection) { @@ -2655,67 +2655,67 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.xtranssensor.method) { - toEdit.raw.xtranssensor.method = mods.raw.xtranssensor.method; + toEdit.raw.xtranssensor.method = mods.raw.xtranssensor.method; } if (raw.xtranssensor.dualDemosaicAutoContrast) { - toEdit.raw.xtranssensor.dualDemosaicAutoContrast = mods.raw.xtranssensor.dualDemosaicAutoContrast; + toEdit.raw.xtranssensor.dualDemosaicAutoContrast = mods.raw.xtranssensor.dualDemosaicAutoContrast; } if (raw.xtranssensor.dualDemosaicContrast) { - toEdit.raw.xtranssensor.dualDemosaicContrast = mods.raw.xtranssensor.dualDemosaicContrast; + toEdit.raw.xtranssensor.dualDemosaicContrast = mods.raw.xtranssensor.dualDemosaicContrast; } if (raw.xtranssensor.ccSteps) { - toEdit.raw.xtranssensor.ccSteps = mods.raw.xtranssensor.ccSteps; + toEdit.raw.xtranssensor.ccSteps = mods.raw.xtranssensor.ccSteps; } if (raw.xtranssensor.border) { - toEdit.raw.xtranssensor.border = mods.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; + toEdit.raw.xtranssensor.blackred = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackred + mods.raw.xtranssensor.blackred : mods.raw.xtranssensor.blackred; } if (raw.xtranssensor.exBlackGreen) { - toEdit.raw.xtranssensor.blackgreen = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackgreen + mods.raw.xtranssensor.blackgreen : mods.raw.xtranssensor.blackgreen; + toEdit.raw.xtranssensor.blackgreen = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackgreen + mods.raw.xtranssensor.blackgreen : mods.raw.xtranssensor.blackgreen; } if (raw.xtranssensor.exBlackBlue) { - toEdit.raw.xtranssensor.blackblue = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackblue + mods.raw.xtranssensor.blackblue : mods.raw.xtranssensor.blackblue; + toEdit.raw.xtranssensor.blackblue = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackblue + mods.raw.xtranssensor.blackblue : mods.raw.xtranssensor.blackblue; } if (raw.ca_autocorrect) { - toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect; + toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect; } if (raw.ca_avoidcolourshift) { - toEdit.raw.ca_avoidcolourshift = mods.raw.ca_avoidcolourshift; + toEdit.raw.ca_avoidcolourshift = mods.raw.ca_avoidcolourshift; } if (raw.caautoiterations) { - toEdit.raw.caautoiterations = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.caautoiterations + mods.raw.caautoiterations : mods.raw.caautoiterations; + toEdit.raw.caautoiterations = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.caautoiterations + mods.raw.caautoiterations : mods.raw.caautoiterations; } if (raw.cared) { - toEdit.raw.cared = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cared + mods.raw.cared : mods.raw.cared; + toEdit.raw.cared = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cared + mods.raw.cared : mods.raw.cared; } if (raw.cablue) { - toEdit.raw.cablue = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cablue + mods.raw.cablue : mods.raw.cablue; + toEdit.raw.cablue = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cablue + mods.raw.cablue : mods.raw.cablue; } if (raw.exPos) { - toEdit.raw.expos = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_LINEAR] ? toEdit.raw.expos + mods.raw.expos : mods.raw.expos; + toEdit.raw.expos = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_LINEAR] ? toEdit.raw.expos + mods.raw.expos : mods.raw.expos; } if (raw.hotPixelFilter) { - toEdit.raw.hotPixelFilter = mods.raw.hotPixelFilter; + toEdit.raw.hotPixelFilter = mods.raw.hotPixelFilter; } if (raw.deadPixelFilter) { - toEdit.raw.deadPixelFilter = mods.raw.deadPixelFilter; + toEdit.raw.deadPixelFilter = mods.raw.deadPixelFilter; } if (raw.hotdeadpix_thresh) { @@ -2723,27 +2723,27 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.darkFrame) { - toEdit.raw.dark_frame = mods.raw.dark_frame; + toEdit.raw.dark_frame = mods.raw.dark_frame; } if (raw.df_autoselect) { - toEdit.raw.df_autoselect = mods.raw.df_autoselect; + toEdit.raw.df_autoselect = mods.raw.df_autoselect; } if (raw.ff_file) { - toEdit.raw.ff_file = mods.raw.ff_file; + toEdit.raw.ff_file = mods.raw.ff_file; } if (raw.ff_AutoSelect) { - toEdit.raw.ff_AutoSelect = mods.raw.ff_AutoSelect; + toEdit.raw.ff_AutoSelect = mods.raw.ff_AutoSelect; } if (raw.ff_BlurRadius) { - toEdit.raw.ff_BlurRadius = mods.raw.ff_BlurRadius; + toEdit.raw.ff_BlurRadius = mods.raw.ff_BlurRadius; } if (raw.ff_BlurType) { - toEdit.raw.ff_BlurType = mods.raw.ff_BlurType; + toEdit.raw.ff_BlurType = mods.raw.ff_BlurType; } if (raw.ff_AutoClipControl) { @@ -2751,135 +2751,135 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.ff_clipControl) { - toEdit.raw.ff_clipControl = dontforceSet && options.baBehav[ADDSET_RAWFFCLIPCONTROL] ? toEdit.raw.ff_clipControl + mods.raw.ff_clipControl : mods.raw.ff_clipControl; + toEdit.raw.ff_clipControl = dontforceSet && options.baBehav[ADDSET_RAWFFCLIPCONTROL] ? toEdit.raw.ff_clipControl + mods.raw.ff_clipControl : mods.raw.ff_clipControl; } if (wavelet.enabled) { - toEdit.wavelet.enabled = mods.wavelet.enabled; + toEdit.wavelet.enabled = mods.wavelet.enabled; } if (wavelet.strength) { - toEdit.wavelet.strength = mods.wavelet.strength; + toEdit.wavelet.strength = mods.wavelet.strength; } if (wavelet.balance) { - toEdit.wavelet.balance = mods.wavelet.balance; + toEdit.wavelet.balance = mods.wavelet.balance; } if (wavelet.iter) { - toEdit.wavelet.iter = mods.wavelet.iter; + toEdit.wavelet.iter = mods.wavelet.iter; } if (wavelet.median) { - toEdit.wavelet.median = mods.wavelet.median; + toEdit.wavelet.median = mods.wavelet.median; } if (wavelet.medianlev) { - toEdit.wavelet.medianlev = mods.wavelet.medianlev; + toEdit.wavelet.medianlev = mods.wavelet.medianlev; } if (wavelet.linkedg) { - toEdit.wavelet.linkedg = mods.wavelet.linkedg; + toEdit.wavelet.linkedg = mods.wavelet.linkedg; } if (wavelet.cbenab) { - toEdit.wavelet.cbenab = mods.wavelet.cbenab; + toEdit.wavelet.cbenab = mods.wavelet.cbenab; } if (wavelet.greenhigh) { - toEdit.wavelet.greenhigh = mods.wavelet.greenhigh; + toEdit.wavelet.greenhigh = mods.wavelet.greenhigh; } if (wavelet.bluehigh) { - toEdit.wavelet.bluehigh = mods.wavelet.bluehigh; + toEdit.wavelet.bluehigh = mods.wavelet.bluehigh; } if (wavelet.greenmed) { - toEdit.wavelet.greenmed = mods.wavelet.greenmed; + toEdit.wavelet.greenmed = mods.wavelet.greenmed; } if (wavelet.bluemed) { - toEdit.wavelet.bluemed = mods.wavelet.bluemed; + toEdit.wavelet.bluemed = mods.wavelet.bluemed; } if (wavelet.greenlow) { - toEdit.wavelet.greenlow = mods.wavelet.greenlow; + toEdit.wavelet.greenlow = mods.wavelet.greenlow; } if (wavelet.bluelow) { - toEdit.wavelet.bluelow = mods.wavelet.bluelow; + toEdit.wavelet.bluelow = mods.wavelet.bluelow; } if (wavelet.lipst) { - toEdit.wavelet.lipst = mods.wavelet.lipst; + toEdit.wavelet.lipst = mods.wavelet.lipst; } if (wavelet.Medgreinf) { - toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf; + toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf; } if (wavelet.avoid) { - toEdit.wavelet.avoid = mods.wavelet.avoid; + toEdit.wavelet.avoid = mods.wavelet.avoid; } if (wavelet.tmr) { - toEdit.wavelet.tmr = mods.wavelet.tmr; + toEdit.wavelet.tmr = mods.wavelet.tmr; } if (wavelet.Lmethod) { - toEdit.wavelet.Lmethod = mods.wavelet.Lmethod; + toEdit.wavelet.Lmethod = mods.wavelet.Lmethod; } if (wavelet.CLmethod) { - toEdit.wavelet.CLmethod = mods.wavelet.CLmethod; + toEdit.wavelet.CLmethod = mods.wavelet.CLmethod; } if (wavelet.Backmethod) { - toEdit.wavelet.Backmethod = mods.wavelet.Backmethod; + toEdit.wavelet.Backmethod = mods.wavelet.Backmethod; } if (wavelet.Tilesmethod) { - toEdit.wavelet.Tilesmethod = mods.wavelet.Tilesmethod; + toEdit.wavelet.Tilesmethod = mods.wavelet.Tilesmethod; } if (wavelet.daubcoeffmethod) { - toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod; + toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod; } if (wavelet.CHmethod) { - toEdit.wavelet.CHmethod = mods.wavelet.CHmethod; + toEdit.wavelet.CHmethod = mods.wavelet.CHmethod; } if (wavelet.CHSLmethod) { - toEdit.wavelet.CHSLmethod = mods.wavelet.CHSLmethod; + toEdit.wavelet.CHSLmethod = mods.wavelet.CHSLmethod; } if (wavelet.EDmethod) { - toEdit.wavelet.EDmethod = mods.wavelet.EDmethod; + toEdit.wavelet.EDmethod = mods.wavelet.EDmethod; } if (wavelet.NPmethod) { - toEdit.wavelet.NPmethod = mods.wavelet.NPmethod; + toEdit.wavelet.NPmethod = mods.wavelet.NPmethod; } if (wavelet.BAmethod) { - toEdit.wavelet.BAmethod = mods.wavelet.BAmethod; + toEdit.wavelet.BAmethod = mods.wavelet.BAmethod; } if (wavelet.TMmethod) { - toEdit.wavelet.TMmethod = mods.wavelet.TMmethod; + toEdit.wavelet.TMmethod = mods.wavelet.TMmethod; } if (wavelet.HSmethod) { - toEdit.wavelet.HSmethod = mods.wavelet.HSmethod; + toEdit.wavelet.HSmethod = mods.wavelet.HSmethod; } if (wavelet.Dirmethod) { - toEdit.wavelet.Dirmethod = mods.wavelet.Dirmethod; + toEdit.wavelet.Dirmethod = mods.wavelet.Dirmethod; } if (wavelet.edgthresh) { - toEdit.wavelet.edgthresh = mods.wavelet.edgthresh; + toEdit.wavelet.edgthresh = mods.wavelet.edgthresh; } if (wavelet.sky) { @@ -2895,39 +2895,39 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.sup) { - toEdit.wavelet.sup = mods.wavelet.sup; + toEdit.wavelet.sup = mods.wavelet.sup; } if (wavelet.hllev) { - toEdit.wavelet.hllev = mods.wavelet.hllev; + toEdit.wavelet.hllev = mods.wavelet.hllev; } if (wavelet.bllev) { - toEdit.wavelet.bllev = mods.wavelet.bllev; + toEdit.wavelet.bllev = mods.wavelet.bllev; } if (wavelet.edgcont) { - toEdit.wavelet.edgcont = mods.wavelet.edgcont; + toEdit.wavelet.edgcont = mods.wavelet.edgcont; } if (wavelet.level0noise) { - toEdit.wavelet.level0noise = mods.wavelet.level0noise; + toEdit.wavelet.level0noise = mods.wavelet.level0noise; } if (wavelet.level1noise) { - toEdit.wavelet.level1noise = mods.wavelet.level1noise; + toEdit.wavelet.level1noise = mods.wavelet.level1noise; } if (wavelet.level2noise) { - toEdit.wavelet.level2noise = mods.wavelet.level2noise; + toEdit.wavelet.level2noise = mods.wavelet.level2noise; } if (wavelet.level3noise) { - toEdit.wavelet.level3noise = mods.wavelet.level3noise; + toEdit.wavelet.level3noise = mods.wavelet.level3noise; } if (wavelet.pastlev) { - toEdit.wavelet.pastlev = mods.wavelet.pastlev; + toEdit.wavelet.pastlev = mods.wavelet.pastlev; } if (wavelet.satlev) { @@ -2935,7 +2935,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.ccwcurve) { - toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; + toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; } if (wavelet.opacityCurveRG) { @@ -2947,7 +2947,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.opacityCurveW) { - toEdit.wavelet.opacityCurveW = mods.wavelet.opacityCurveW; + toEdit.wavelet.opacityCurveW = mods.wavelet.opacityCurveW; } if (wavelet.opacityCurveWL) { @@ -2955,44 +2955,44 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.hhcurve) { - toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; + toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; } if (wavelet.Chcurve) { - toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; + toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; } if (wavelet.wavclCurve) { toEdit.wavelet.wavclCurve = mods.wavelet.wavclCurve; } - //if (wavelet.enacont) toEdit.wavelet.enacont = mods.wavelet.enacont; + //if (wavelet.enacont) toEdit.wavelet.enacont = mods.wavelet.enacont; if (wavelet.expcontrast) { - toEdit.wavelet.expcontrast = mods.wavelet.expcontrast; + toEdit.wavelet.expcontrast = mods.wavelet.expcontrast; } if (wavelet.expchroma) { - toEdit.wavelet.expchroma = mods.wavelet.expchroma; + toEdit.wavelet.expchroma = mods.wavelet.expchroma; } if (wavelet.expedge) { - toEdit.wavelet.expedge = mods.wavelet.expedge; + toEdit.wavelet.expedge = mods.wavelet.expedge; } if (wavelet.expresid) { - toEdit.wavelet.expresid = mods.wavelet.expresid; + toEdit.wavelet.expresid = mods.wavelet.expresid; } if (wavelet.expfinal) { - toEdit.wavelet.expfinal = mods.wavelet.expfinal; + toEdit.wavelet.expfinal = mods.wavelet.expfinal; } if (wavelet.exptoning) { - toEdit.wavelet.exptoning = mods.wavelet.exptoning; + toEdit.wavelet.exptoning = mods.wavelet.exptoning; } if (wavelet.expnoise) { - toEdit.wavelet.expnoise = mods.wavelet.expnoise; + toEdit.wavelet.expnoise = mods.wavelet.expnoise; } for (int i = 0; i < 9; i++) { @@ -3012,19 +3012,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.hueskin) { - toEdit.wavelet.hueskin = mods.wavelet.hueskin; + toEdit.wavelet.hueskin = mods.wavelet.hueskin; } if (wavelet.hueskin2) { - toEdit.wavelet.hueskin2 = mods.wavelet.hueskin2; + toEdit.wavelet.hueskin2 = mods.wavelet.hueskin2; } if (wavelet.edgesensi) { - toEdit.wavelet.edgesensi = mods.wavelet.edgesensi; + toEdit.wavelet.edgesensi = mods.wavelet.edgesensi; } if (wavelet.edgeampli) { - toEdit.wavelet.edgeampli = mods.wavelet.edgeampli; + toEdit.wavelet.edgeampli = mods.wavelet.edgeampli; } if (wavelet.resconH) { @@ -3097,20 +3097,20 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng if (dirpyrequalizer.enabled) { - toEdit.dirpyrequalizer.enabled = mods.dirpyrequalizer.enabled; + toEdit.dirpyrequalizer.enabled = mods.dirpyrequalizer.enabled; } if (dirpyrequalizer.gamutlab) { - toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab; + toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab; } if (dirpyrequalizer.cbdlMethod) { - toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod; + toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod; } for (int i = 0; i < 6; i++) { if (dirpyrequalizer.mult[i]) { - toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i]; + toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i]; } } @@ -3123,93 +3123,95 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (dirpyrequalizer.hueskin) { - toEdit.dirpyrequalizer.hueskin = mods.dirpyrequalizer.hueskin; + toEdit.dirpyrequalizer.hueskin = mods.dirpyrequalizer.hueskin; } -// if (dirpyrequalizer.algo) toEdit.dirpyrequalizer.algo = mods.dirpyrequalizer.algo; +// if (dirpyrequalizer.algo) toEdit.dirpyrequalizer.algo = mods.dirpyrequalizer.algo; if (hsvequalizer.enabled) { toEdit.hsvequalizer.enabled = mods.hsvequalizer.enabled; } if (hsvequalizer.hcurve) { - toEdit.hsvequalizer.hcurve = mods.hsvequalizer.hcurve; + toEdit.hsvequalizer.hcurve = mods.hsvequalizer.hcurve; } if (hsvequalizer.scurve) { - toEdit.hsvequalizer.scurve = mods.hsvequalizer.scurve; + toEdit.hsvequalizer.scurve = mods.hsvequalizer.scurve; } if (hsvequalizer.vcurve) { - toEdit.hsvequalizer.vcurve = mods.hsvequalizer.vcurve; + toEdit.hsvequalizer.vcurve = mods.hsvequalizer.vcurve; } if (filmSimulation.enabled) { - toEdit.filmSimulation.enabled = mods.filmSimulation.enabled; + toEdit.filmSimulation.enabled = mods.filmSimulation.enabled; } if (filmSimulation.clutFilename) { - toEdit.filmSimulation.clutFilename = mods.filmSimulation.clutFilename; + toEdit.filmSimulation.clutFilename = mods.filmSimulation.clutFilename; } if (filmSimulation.strength) { - toEdit.filmSimulation.strength = dontforceSet && options.baBehav[ADDSET_FILMSIMULATION_STRENGTH] ? toEdit.filmSimulation.strength + mods.filmSimulation.strength : mods.filmSimulation.strength; + toEdit.filmSimulation.strength = dontforceSet && options.baBehav[ADDSET_FILMSIMULATION_STRENGTH] ? toEdit.filmSimulation.strength + mods.filmSimulation.strength : mods.filmSimulation.strength; } if (softlight.enabled) { - toEdit.softlight.enabled = mods.softlight.enabled; + toEdit.softlight.enabled = mods.softlight.enabled; } if (softlight.strength) { - toEdit.softlight.strength = dontforceSet && options.baBehav[ADDSET_SOFTLIGHT_STRENGTH] ? toEdit.softlight.strength + mods.softlight.strength : mods.softlight.strength; + toEdit.softlight.strength = dontforceSet && options.baBehav[ADDSET_SOFTLIGHT_STRENGTH] ? toEdit.softlight.strength + mods.softlight.strength : mods.softlight.strength; } if (dehaze.enabled) { - toEdit.dehaze.enabled = mods.dehaze.enabled; + toEdit.dehaze.enabled = mods.dehaze.enabled; } if (dehaze.strength) { - toEdit.dehaze.strength = dontforceSet && options.baBehav[ADDSET_DEHAZE_STRENGTH] ? toEdit.dehaze.strength + mods.dehaze.strength : mods.dehaze.strength; + toEdit.dehaze.strength = dontforceSet && options.baBehav[ADDSET_DEHAZE_STRENGTH] ? toEdit.dehaze.strength + mods.dehaze.strength : mods.dehaze.strength; } if (dehaze.depth) { - toEdit.dehaze.depth = mods.dehaze.depth; + toEdit.dehaze.depth = mods.dehaze.depth; } if (dehaze.showDepthMap) { - toEdit.dehaze.showDepthMap = mods.dehaze.showDepthMap; + toEdit.dehaze.showDepthMap = mods.dehaze.showDepthMap; } if (metadata.mode) { - toEdit.metadata.mode = mods.metadata.mode; + toEdit.metadata.mode = mods.metadata.mode; } if (filmNegative.enabled) { - toEdit.filmNegative.enabled = mods.filmNegative.enabled; + toEdit.filmNegative.enabled = mods.filmNegative.enabled; } if (filmNegative.redExp) { - toEdit.filmNegative.redExp = mods.filmNegative.redExp; + toEdit.filmNegative.redExp = mods.filmNegative.redExp; } if (filmNegative.greenExp) { - toEdit.filmNegative.greenExp = mods.filmNegative.greenExp; + toEdit.filmNegative.greenExp = mods.filmNegative.greenExp; } if (filmNegative.blueExp) { - toEdit.filmNegative.blueExp = mods.filmNegative.blueExp; + toEdit.filmNegative.blueExp = mods.filmNegative.blueExp; } // Exif changes are added to the existing ones - if (exif) + if (exif) { for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { toEdit.exif[i->first] = i->second; } + } // IPTC changes are added to the existing ones - if (iptc) + if (iptc) { for (procparams::IPTCPairs::const_iterator i = mods.iptc.begin(); i != mods.iptc.end(); ++i) { toEdit.iptc[i->first] = i->second; } + } } bool RAWParamsEdited::BayerSensor::isUnchanged() const @@ -3244,4 +3246,4 @@ bool RetinexParamsEdited::isUnchanged() const bool FilmNegativeParamsEdited::isUnchanged() const { return enabled && redExp && greenExp && blueExp; -} \ No newline at end of file +} diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index ef18e2953..34f9a414d 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -137,7 +137,6 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren //--- filmNegative = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FILMNEGATIVE")) ); - Gtk::VBox* vboxes[8]; Gtk::HSeparator* hseps[8]; @@ -255,7 +254,6 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[7]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); vboxes[7]->pack_start (*filmNegative, Gtk::PACK_SHRINK, 2); - Gtk::VBox* vbCol1 = Gtk::manage (new Gtk::VBox ()); Gtk::VBox* vbCol2 = Gtk::manage (new Gtk::VBox ()); Gtk::VBox* vbCol3 = Gtk::manage (new Gtk::VBox ()); @@ -983,7 +981,6 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.filmNegative.blueExp = falsePE.filmNegative.blueExp; } - if (dstPE) { *dstPE = filterPE; } @@ -991,4 +988,3 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param // Apply the filter! filterPE.combine(*dstPP, *srcPP, true); } - diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index bd9720dfd..42dbeb984 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -1025,8 +1025,5 @@ void ToolPanelCoordinator::setEditProvider (EditDataProvider *provider) bool ToolPanelCoordinator::getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, float* newExps) { - if(!ipc) - return false; - - return ipc->getFilmNegativeExponents(spotA.x, spotA.y, spotB.x, spotB.y, newExps); + return ipc && ipc->getFilmNegativeExponents(spotA.x, spotA.y, spotB.x, spotB.y, newExps); } From 80f2b6a00281be746ff6275b9e23f6b1a429b9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 14 Jun 2019 08:58:04 +0200 Subject: [PATCH 019/222] Replace raw arrays with `std::array<>` --- rtengine/filmnegativeproc.cc | 4 ++-- rtengine/imagesource.h | 3 ++- rtengine/improccoordinator.cc | 2 +- rtengine/improccoordinator.h | 2 +- rtengine/rawimagesource.h | 8 ++++---- rtengine/rtengine.h | 37 +++++++++++++++++++---------------- rtgui/filmnegative.cc | 6 +++--- rtgui/filmnegative.h | 22 ++++++++++----------- rtgui/toolpanelcoord.cc | 2 +- rtgui/toolpanelcoord.h | 2 +- 10 files changed, 46 insertions(+), 42 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index db98fdf02..871b7a1d9 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -82,7 +82,7 @@ float logBase(float base, float num) { return log(num) / log(base); } -bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, float newExps[3]) +bool RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) { float clearVals[3], denseVals[3]; @@ -317,4 +317,4 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p } } -} \ No newline at end of file +} diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 0a34b6bc8..bf73b5bb2 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -18,6 +18,7 @@ */ #pragma once +#include #include #include @@ -81,7 +82,7 @@ public: virtual int load (const Glib::ustring &fname) = 0; virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {}; virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) {}; - virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, float newExps[3]) { return false; }; + virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams& currentParams, std::array& newExps) { return false; }; virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) {}; virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index fb6250183..6f471eedf 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1262,7 +1262,7 @@ void ImProcCoordinator::getSpotWB(int x, int y, int rect, double& temp, double& } } -bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB, float* newExps) +bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) { MyMutex::MyLock lock(mProcessing); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index d10db8d70..fdf74d297 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -269,7 +269,7 @@ public: bool getAutoWB (double& temp, double& green, double equal, double tempBias) override; void getCamWB (double& temp, double& green) override; void getSpotWB (int x, int y, int rectSize, double& temp, double& green) override; - bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, float* newExps) override; + bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) override; void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) override; bool getHighQualComputed() override; void setHighQualComputed() override; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 6e039e7f8..9bfeb0c67 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -16,9 +16,9 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RAWIMAGESOURCE_ -#define _RAWIMAGESOURCE_ +#pragma once +#include #include #include @@ -116,7 +116,7 @@ public: int load(const Glib::ustring &fname, bool firstFrameOnly); void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override; void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) override; - bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, float newExps[3]) override; + bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) override; void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) override; void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override; void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override; @@ -309,5 +309,5 @@ protected: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; }; + } -#endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index cc46cfca8..da10d470f 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -16,23 +16,29 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RTENGINE_ -#define _RTENGINE_ +#pragma once -#include "imageformat.h" -#include "rt_math.h" -#include "procevents.h" -#include -#include -#include +#include #include -#include "../rtexif/rtexif.h" -#include "rawmetadatalocation.h" +#include + +#include + +#include + #include "iimage.h" -#include "utils.h" -#include "../rtgui/threadutils.h" -#include "settings.h" +#include "imageformat.h" #include "LUT.h" +#include "procevents.h" +#include "rawmetadatalocation.h" +#include "rt_math.h" +#include "settings.h" +#include "utils.h" + +#include "../rtexif/rtexif.h" + +#include "../rtgui/threadutils.h" + /** * @file * This file contains the main functionality of the RawTherapee engine. @@ -499,7 +505,7 @@ public: virtual bool getAutoWB (double& temp, double& green, double equal, double tempBias) = 0; virtual void getCamWB (double& temp, double& green) = 0; virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) = 0; - virtual bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, float* newExps) = 0; + virtual bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) = 0; virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) = 0; virtual void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) = 0; @@ -613,6 +619,3 @@ void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl); extern MyMutex* lcmsMutex; } - -#endif - diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 8f1fb5610..72141ecfb 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -281,8 +281,8 @@ bool FilmNegative::button1Pressed(int modifierKey) // User has selected 2 reference gray spots. Calculating new exponents // from channel values and updating parameters. - float newExps[3]; - if(fnp->getFilmNegativeExponents(refSpotCoords[0], refSpotCoords[1], newExps)) { + std::array newExps; + if (fnp->getFilmNegativeExponents(refSpotCoords[0], refSpotCoords[1], newExps)) { disableListener(); redExp->setValue(newExps[0]); greenExp->setValue(newExps[1]); @@ -335,4 +335,4 @@ void FilmNegative::switchOffEditMode () refSpotCoords.clear(); unsubscribe(); spotbutton->set_active(false); -} \ No newline at end of file +} diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 5d6c8ce03..b9dc15378 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -16,23 +16,25 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _NEG_H_ -#define _NEG_H_ +#pragma once + +#include #include -#include "toolpanel.h" -#include "adjuster.h" -#include "guiutils.h" -#include "wbprovider.h" -#include "editcallbacks.h" -#include "../rtengine/procparams.h" +#include "adjuster.h" +#include "editcallbacks.h" +#include "guiutils.h" +#include "toolpanel.h" +#include "wbprovider.h" + +#include "../rtengine/procparams.h" class FilmNegProvider { public: virtual ~FilmNegProvider() = default; - virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, float* newExps) = 0; + virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) = 0; }; class FilmNegative : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public EditSubscriber @@ -89,5 +91,3 @@ public: bool pick1(bool picked) override; }; - -#endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 42dbeb984..f7e2991e1 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -1023,7 +1023,7 @@ void ToolPanelCoordinator::setEditProvider (EditDataProvider *provider) } } -bool ToolPanelCoordinator::getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, float* newExps) +bool ToolPanelCoordinator::getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) { return ipc && ipc->getFilmNegativeExponents(spotA.x, spotA.y, spotB.x, spotB.y, newExps); } diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 9910f9757..5569861ae 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -292,7 +292,7 @@ public: Glib::ustring GetCurrentImageFilePath() override; // FilmNegProvider interface - bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, float* newExps) override; + bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) override; // rotatelistener interface void straightenRequested () override; From d01f78864c9052963d354a9c0b3cdb60f82e38be Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 14 Jun 2019 22:14:24 +0200 Subject: [PATCH 020/222] Locked red and blue exponents by default in the GUI, added CheckButton to unlock them. --- rtdata/languages/default | 4 +++- rtgui/filmnegative.cc | 33 +++++++++++++++++++++++++++------ rtgui/filmnegative.h | 4 ++++ 3 files changed, 34 insertions(+), 7 deletions(-) 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/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 8f1fb5610..72307946b 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -49,6 +49,9 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI greenExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_GREEN"), 2.0); blueExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_BLUE"), 1.72); + redExp->set_sensitive(false); + blueExp->set_sensitive(false); + redRatio = redExp->getValue() / greenExp->getValue(); blueRatio = blueExp->getValue() / greenExp->getValue(); @@ -56,6 +59,10 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI EvFilmNegativeEnabled = m->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED"); EvFilmNegativeExponents = m->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS"); + lockChannels = Gtk::manage (new Gtk::CheckButton (M("TP_FILMNEGATIVE_LOCKCHANNELS"))); + lockChannels->set_tooltip_text(M("TP_FILMNEGATIVE_LOCKCHANNELS_TOOLTIP")); + lockChannels->set_active (true); + spotgrid = Gtk::manage(new Gtk::Grid()); spotgrid->get_style_context()->add_class("grid-spacing"); @@ -86,11 +93,13 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI // 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) ); @@ -191,6 +200,12 @@ void FilmNegative::editToggled () } } +void FilmNegative::lockChannelsToggled () +{ + bool unlocked = !lockChannels->get_active(); + redExp->set_sensitive(unlocked); + blueExp->set_sensitive(unlocked); +} void FilmNegative::read (const ProcParams* pp, const ParamsEdited* pedited) { @@ -245,12 +260,18 @@ void FilmNegative::setDefaults (const ProcParams* defParams, const ParamsEdited* 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 (); + } } bool FilmNegative::mouseOver(int modifierKey) diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 5d6c8ce03..1a2262aec 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -50,6 +50,9 @@ private: Adjuster* greenExp; Adjuster* blueExp; + Gtk::CheckButton* lockChannels; + sigc::connection lockChannelsConn; + Gtk::Grid* spotgrid; Gtk::ToggleButton* spotbutton; sigc::connection spotConn; @@ -57,6 +60,7 @@ private: double redRatio, blueRatio; void editToggled (); + void lockChannelsToggled (); public: From 54cc02eea971c7002f19b16b1552729ee8acd4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Mon, 17 Jun 2019 08:03:46 +0200 Subject: [PATCH 021/222] Filmenegative core cleanup --- rtengine/filmnegativeproc.cc | 338 ++++++++++++++++++++-------------- rtengine/rawimage.cc | 2 +- rtengine/rawimage.h | 2 +- rtengine/rawimagesource.h | 1 - rtgui/filmnegative.cc | 343 ++++++++++++++++++----------------- rtgui/filmnegative.h | 80 ++++---- 6 files changed, 422 insertions(+), 344 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 871b7a1d9..51bd52365 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2019 rom9 * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,15 +19,17 @@ #include #include -#include "rtengine.h" -#include "rawimagesource.h" -#include "mytime.h" -#include "procparams.h" #ifdef _OPENMP #include #endif + +#include "rawimagesource.h" + +#include "mytime.h" #include "opthelper.h" +#include "procparams.h" #include "rt_algo.h" +#include "rtengine.h" //#define BENCHMARK #include "StopWatch.h" @@ -37,168 +39,221 @@ namespace rtengine extern const Settings* settings; -bool RawImageSource::channelsAvg(Coord spotPos, int spotSize, float avgs[3], const FilmNegativeParams ¶ms) +} + +namespace { - avgs[0] = avgs[1] = avgs[2] = 0.f; // Channel averages - if(ri->getSensorType() != ST_BAYER && ri->getSensorType() != ST_FUJI_XTRANS) +bool channelsAvg( + const rtengine::RawImage* ri, + int width, + int height, + array2D& rawData, + rtengine::Coord spotPos, + int spotSize, + const rtengine::procparams::FilmNegativeParams& params, + std::array& avgs +) +{ + avgs = {}; // Channel averages + + if (ri->getSensorType() != rtengine::ST_BAYER && ri->getSensorType() != rtengine::ST_FUJI_XTRANS) { return false; + } - if (settings->verbose) + if (rtengine::settings->verbose) { printf("Spot coord: x=%d y=%d\n", spotPos.x, spotPos.y); + } - int x1 = spotPos.x - spotSize / 2; - int x2 = spotPos.x + spotSize / 2; - int y1 = spotPos.y - spotSize / 2; - int y2 = spotPos.y + spotSize / 2; + const int half_spot_size = spotSize / 2; - if(x1<0 || x2>W || y1<0 || y2>H) + const int& x1 = spotPos.x - half_spot_size; + const int& x2 = spotPos.x + half_spot_size; + const int& y1 = spotPos.y - half_spot_size; + const int& y2 = spotPos.y + half_spot_size; + + if (x1 < 0 || x2 > width || y1 < 0 || y2 > height) { return false; // Spot goes outside bounds, bail out. + } - int pxCount[3] = {0}; // Per-channel sample counts - for(int c=spotPos.x-spotSize; c 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) { + const int ch = ri->getSensorType() == rtengine::ST_BAYER ? ri->FC(r,c) : ri->XTRANSFC(r,c); - int ch = (ri->getSensorType() == ST_BAYER) ? FC(r,c) : ri->XTRANSFC(r,c); + ++pxCount[ch]; - pxCount[ch]++; // If film negative is currently enabled, undo the effect by elevating to 1/exp, // in order to sample the original, linear value - if(params.enabled) - avgs[ch] += powf(rawData[r][c], -1 / (ch==0 ? params.redExp : ch==1 ? params.greenExp : params.blueExp)); - else + if (params.enabled) { + avgs[ch] += powf(rawData[r][c], -1.f / (ch == 0 ? params.redExp : ch == 1 ? params.greenExp : params.blueExp)); + } else { avgs[ch] += rawData[r][c]; + } } } - for(int ch=0; ch<3; ch++) - avgs[ch] = avgs[ch] / (pxCount[ch]); + for (int ch = 0; ch < 3; ++ch) { + avgs[ch] /= pxCount[ch]; + } return true; } -// Calculate logarithms in arbitrary base -float logBase(float base, float num) { - return log(num) / log(base); } -bool RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) +bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) { - float clearVals[3], denseVals[3]; + newExps = { + static_cast(currentParams.redExp), + static_cast(currentParams.greenExp), + static_cast(currentParams.blueExp) + }; - newExps[0] = currentParams.redExp; - newExps[1] = currentParams.greenExp; - newExps[2] = currentParams.blueExp; + constexpr int spotSize = 32; // TODO: Make this configurable? - int spotSize = 32; // TODO : make this confugurable ? Coord spot; + std::array clearVals; + std::array denseVals; + // Sample first spot - transformPosition (spotA.x, spotA.y, tran, spot.x, spot.y); - if(!channelsAvg(spot, spotSize, clearVals, currentParams)) - return false; - - // Sample second spot - transformPosition (spotB.x, spotB.y, tran, spot.x, spot.y); - if(!channelsAvg(spot, spotSize, denseVals, currentParams)) - return false; - - // Detect which one is the dense spot, based on green channel - if(clearVals[1] < denseVals[1]) - std::swap(clearVals, denseVals); - - if (settings->verbose) { - printf("Clear film values: R=%g G=%g B=%g\n", clearVals[0], clearVals[1], clearVals[2]); - printf("Dense film values: R=%g G=%g B=%g\n", denseVals[0], denseVals[1], denseVals[2]); + transformPosition(spotA.x, spotA.y, tran, spot.x, spot.y); + if (!channelsAvg(ri, W, H, rawData, spot, spotSize, currentParams, clearVals)) { + return false; } - float denseGreenRatio = clearVals[1] / denseVals[1]; + // Sample second spot + transformPosition(spotB.x, spotB.y, tran, spot.x, spot.y); + if (!channelsAvg(ri, W, H, rawData, spot, spotSize, currentParams, denseVals)) { + return false; + } + + // Detect which one is the dense spot, based on green channel + if (clearVals[1] < denseVals[1]) { + std::swap(clearVals, denseVals); + } + + if (settings->verbose) { + printf("Clear film values: R=%g G=%g B=%g\n", clearVals[0], clearVals[1], clearVals[2]); + printf("Dense film values: R=%g G=%g B=%g\n", denseVals[0], denseVals[1], denseVals[2]); + } + + const float denseGreenRatio = clearVals[1] / denseVals[1]; + + // Calculate logarithms in arbitrary base + const auto logBase = + [](float base, float num) -> float + { + return std::log(num) / std::log(base); + }; // Calculate exponents for each channel, based on the ratio between the bright and dark values, // compared to the ratio in the reference channel (green) - for(int ch=0; ch<3; ch++) - if(ch==1) + for (int ch = 0; ch < 3; ++ch) { + if (ch == 1) { newExps[ch] = 2.f; // Green is the reference channel - else + } else { newExps[ch] = CLAMP(2.f * logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 6.f); + } + } - if (settings->verbose) + if (settings->verbose) { printf("New exponents: R=%g G=%g B=%g\n", newExps[0], newExps[1], newExps[2]); + } return true; } -void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams ¶ms) +void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams ¶ms) { // BENCHFUNMICRO - if(!params.enabled) + if (!params.enabled) { return; + } - float exps[3] = { (float)params.redExp, (float)params.greenExp, (float)params.blueExp }; + const std::array exps = { + static_cast(params.redExp), + static_cast(params.greenExp), + static_cast(params.blueExp) + }; - MyTime t1, t2, t3,t4, t5, t6; + MyTime t1, t2, t3,t4, t5; + t1.set(); // Channel vectors to calculate medians - std::vector cvs[3] = { - std::vector(), - std::vector(), - std::vector() - }; + std::array, 3> cvs; // Sample one every 5 pixels, and push the value in the appropriate channel vector. - // Chose an odd step, not 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) { - int c = FC(row, col); // three colors, 0=R, 1=G, 2=B + // 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]); } } - } else if(ri->getSensorType() == ST_FUJI_XTRANS) { - for (int row = 0; row < H; row+=5) { - for (int col = 0; col < W; col+=5) { - int c = ri->XTRANSFC(row, col); // three colors, 0=R, 1=G, 2=B + } + 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 float MAX_OUT_VALUE = 65000.f; + constexpr float MAX_OUT_VALUE = 65000.f; t2.set(); - if (settings->verbose) + + if (settings->verbose) { printf("Median vector fill loop time us: %d\n", t2.etime(t1)); + } - float medians[3]; // Channel median values - float mults[3] = { 1.f }; // Channel normalization multipliers + t2.set(); - for (int c=0; c<3; c++) { + std::array medians; // Channel median values + std::array mults = { + 1.f, + 1.f, + 1.f + }; // Channel normalization multipliers + + for (int c = 0; c < 3; ++c) { // Find median values for each channel - if(cvs[c].size() > 0) { - findMinMaxPercentile(&cvs[c][0], cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); - medians[c] = pow_F(max(medians[c], 1.f), -exps[c]); + if (!cvs[c].empty()) { + findMinMaxPercentile(cvs[c].data(), cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); + medians[c] = pow_F(rtengine::max(medians[c], 1.f), -exps[c]); // Determine the channel multipler so that N times the median becomes 65k. This clips away // the values in the dark border surrounding the negative (due to the film holder, for example), // the reciprocal of which have blown up to stellar values. - mults[c] = MAX_OUT_VALUE / (medians[c] * 24); + mults[c] = MAX_OUT_VALUE / (medians[c] * 24.f); } } t3.set(); + if (settings->verbose) { - printf("Sample count : %lu, %lu, %lu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); - printf("Medians : %g %g %g\n", medians[0], medians[1], medians[2] ); - printf("Computed multipliers : %g %g %g\n", mults[0], mults[1], mults[2] ); + printf("Sample count: %zu, %zu, %zu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); + printf("Medians: %g %g %g\n", medians[0], medians[1], medians[2] ); + printf("Computed multipliers: %g %g %g\n", mults[0], mults[1], mults[2] ); printf("Median calc time us: %d\n", t3.etime(t2)); } + t3.set(); + + if (ri->getSensorType() == ST_BAYER) { +#ifdef __SSE2__ + const vfloat onev = F2V(1.f); + const vfloat c65535v = F2V(65535.f); +#endif - if(ri->getSensorType() == ST_BAYER) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif - for (int row = 0; row < H; row ++) { + for (int row = 0; row < H; ++row) { int col = 0; // Exponents are expressed as positive in the parameters, so negate them in order // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. @@ -209,21 +264,24 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p #ifdef __SSE2__ const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1); const vfloat multsv = _mm_setr_ps(mult0, mult1, mult0, mult1); - const vfloat onev = F2V(1.f); - const vfloat c65535v = F2V(65535.f); - for (; col < W - 3; col+=4) { + for (; col < W - 3; col += 4) { STVFU(rawData[row][col], vminf(multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv), c65535v)); } #endif // __SSE2__ - for (; col < W - 1; col+=2) { - rawData[row][col] = rtengine::min(mult0 * pow_F(max(rawData[row][col], 1.f), exps0), 65535.f); - rawData[row][col + 1] = rtengine::min(mult1 * pow_F(max(rawData[row][col + 1], 1.f), exps1), 65535.f); + for (; col < W - 1; col += 2) { + rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), 65535.f); + rawData[row][col + 1] = rtengine::min(mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1), 65535.f); } if (col < W) { - rawData[row][col] = rtengine::min(mult0 * pow_F(max(rawData[row][col], 1.f), exps0), 65535.f); + rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), 65535.f); } } - } else if(ri->getSensorType() == ST_FUJI_XTRANS) { + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { +#ifdef __SSE2__ + const vfloat onev = F2V(1.f); + const vfloat c65535v = F2V(65535.f); +#endif + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif @@ -231,8 +289,22 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p int col = 0; // Exponents are expressed as positive in the parameters, so negate them in order // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. - const float expsc[6] = {-exps[ri->XTRANSFC(row, 0)], -exps[ri->XTRANSFC(row, 1)], -exps[ri->XTRANSFC(row, 2)], -exps[ri->XTRANSFC(row, 3)], -exps[ri->XTRANSFC(row, 4)], -exps[ri->XTRANSFC(row, 5)]}; - const float multsc[6] = {mults[ri->XTRANSFC(row, 0)], mults[ri->XTRANSFC(row, 1)], mults[ri->XTRANSFC(row, 2)], mults[ri->XTRANSFC(row, 3)], mults[ri->XTRANSFC(row, 4)], mults[ri->XTRANSFC(row, 5)]}; + const std::array expsc = { + -exps[ri->XTRANSFC(row, 0)], + -exps[ri->XTRANSFC(row, 1)], + -exps[ri->XTRANSFC(row, 2)], + -exps[ri->XTRANSFC(row, 3)], + -exps[ri->XTRANSFC(row, 4)], + -exps[ri->XTRANSFC(row, 5)] + }; + const std::array multsc = { + mults[ri->XTRANSFC(row, 0)], + mults[ri->XTRANSFC(row, 1)], + mults[ri->XTRANSFC(row, 2)], + mults[ri->XTRANSFC(row, 3)], + mults[ri->XTRANSFC(row, 4)], + mults[ri->XTRANSFC(row, 5)] + }; #ifdef __SSE2__ const vfloat expsv0 = _mm_setr_ps(expsc[0], expsc[1], expsc[2], expsc[3]); const vfloat expsv1 = _mm_setr_ps(expsc[4], expsc[5], expsc[0], expsc[1]); @@ -240,81 +312,75 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p const vfloat multsv0 = _mm_setr_ps(multsc[0], multsc[1], multsc[2], multsc[3]); const vfloat multsv1 = _mm_setr_ps(multsc[4], multsc[5], multsc[0], multsc[1]); const vfloat multsv2 = _mm_setr_ps(multsc[2], multsc[3], multsc[4], multsc[5]); - const vfloat onev = F2V(1.f); - const vfloat c65535v = F2V(65535.f); - for (; col < W - 11; col+=12) { + for (; col < W - 11; col += 12) { STVFU(rawData[row][col], vminf(multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0), c65535v)); STVFU(rawData[row][col + 4], vminf(multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1), c65535v)); STVFU(rawData[row][col + 8], vminf(multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2), c65535v)); } #endif // __SSE2__ - for (; col < W - 5; col+=6) { + for (; col < W - 5; col += 6) { for (int c = 0; c < 6; ++c) { - rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); } } for (int c = 0; col < W; col++, c++) { - rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); } } } + t4.set(); + + if (settings->verbose) { + printf("Pow loop time us: %d\n", t4.etime(t3)); + } t4.set(); - if (settings->verbose) - printf("Pow loop time us: %d\n", t4.etime(t3)); - - - t5.set(); PixelsMap bitmapBads(W, H); int totBP = 0; // Hold count of bad pixels to correct - if(ri->getSensorType() == ST_BAYER) { - - + if (ri->getSensorType() == ST_BAYER) { #ifdef _OPENMP #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) #endif - - for(int i = 0; i < H; i++) - for(int j = 0; j < W; j++) { + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { if (rawData[i][j] >= MAX_OUT_VALUE) { bitmapBads.set(j, i); - totBP++; + ++totBP; } } - - if (totBP > 0) { - interpolateBadPixelsBayer( bitmapBads, rawData ); } - } else if(ri->getSensorType() == ST_FUJI_XTRANS) { - -#ifdef _OPENMP - #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) -#endif - - for(int i = 0; i < H; i++) - for(int j = 0; j < W; j++) { - if (rawData[i][j] >= MAX_OUT_VALUE) { - bitmapBads.set(j, i); - totBP++; - } - } - if (totBP > 0) { - interpolateBadPixelsXtrans( bitmapBads ); + interpolateBadPixelsBayer(bitmapBads, rawData); } } + else if (ri->getSensorType() == ST_FUJI_XTRANS) { +#ifdef _OPENMP + #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + if (rawData[i][j] >= MAX_OUT_VALUE) { + bitmapBads.set(j, i); + totBP++; + } + } + } + + if (totBP > 0) { + interpolateBadPixelsXtrans(bitmapBads); + } + } + + t5.set(); - t6.set(); if (settings->verbose) { printf("Bad pixels count: %d\n", totBP); - printf("Bad pixels interpolation time us: %d\n", t6.etime(t5)); + printf("Bad pixels interpolation time us: %d\n", t5.etime(t4)); } } - -} diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 1fa1630ab..0134d4d16 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -67,7 +67,7 @@ RawImage::~RawImage() } } -eSensorType RawImage::getSensorType() +eSensorType RawImage::getSensorType() const { if (isBayer()) { return ST_BAYER; diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 0dabfef0d..4ff6d79c9 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -185,7 +185,7 @@ public: return float_raw_image; } - eSensorType getSensorType(); + eSensorType getSensorType() const; void getRgbCam (float rgbcam[3][4]); void getXtransMatrix ( int xtransMatrix[6][6]); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 9bfeb0c67..c04da5b66 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -43,7 +43,6 @@ private: static LUTf initInvGrad (); static void colorSpaceConversion_ (Imagefloat* im, const procparams::ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName); int defTransform (int tran); - bool channelsAvg(Coord spotPos, int spotSize, float avgs[3], const FilmNegativeParams ¶ms); protected: MyMutex getImageMutex; // locks getImage diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 72141ecfb..fef4fc6c6 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2019 rom9 * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,52 +16,52 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include "filmnegative.h" - #include -#include "rtimage.h" -#include "options.h" +#include "filmnegative.h" + #include "editwidgets.h" #include "eventmapper.h" +#include "options.h" +#include "rtimage.h" +#include "../rtengine/procparams.h" -using namespace rtengine; -using namespace rtengine::procparams; - - -FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FILMNEGATIVE_LABEL"), false, true), EditSubscriber(ET_OBJECTS) +namespace { - auto mkExponentAdjuster = [this](Glib::ustring label, double defaultVal) { - Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 6, 0.001, defaultVal)); //exponent - adj->setAdjusterListener (this); - - if (adj->delay < options.adjusterMaxDelay) { - adj->delay = options.adjusterMaxDelay; - } - - adj->show(); - return adj; - }; +Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring& label, double defaultVal) +{ + Adjuster* const adj = Gtk::manage(new Adjuster(label, 0.3, 6, 0.001, defaultVal)); // exponent + adj->setAdjusterListener(listener); - redExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_RED"), 2.72); - greenExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_GREEN"), 2.0); - blueExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_BLUE"), 1.72); + if (adj->delay < options.adjusterMaxDelay) { + adj->delay = options.adjusterMaxDelay; + } - redRatio = redExp->getValue() / greenExp->getValue(); - blueRatio = blueExp->getValue() / greenExp->getValue(); + adj->show(); + return adj; +} - auto m = ProcEventMapper::getInstance(); - EvFilmNegativeEnabled = m->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED"); - EvFilmNegativeExponents = m->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS"); +} - - spotgrid = Gtk::manage(new Gtk::Grid()); +FilmNegative::FilmNegative() : + FoldableToolPanel(this, "filmnegative", M("TP_FILMNEGATIVE_LABEL"), false, true), + EditSubscriber(ET_OBJECTS), + evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS")), + evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), + fnp(nullptr), + 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)), + 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()) +{ spotgrid->get_style_context()->add_class("grid-spacing"); setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - spotbutton = Gtk::manage (new Gtk::ToggleButton (M("TP_FILMNEGATIVE_PICK"))); setExpandAlignProperties(spotbutton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotbutton->get_style_context()->add_class("independent"); spotbutton->set_tooltip_text(M("TP_FILMNEGATIVE_GUESS_TOOLTIP")); @@ -83,120 +83,47 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI // spotsize->append ("4"); spotgrid->attach (*spotbutton, 0, 1, 1, 1); -// spotgrid->attach (*slab, 1, 0, 1, 1); + // spotgrid->attach (*slab, 1, 0, 1, 1); // spotgrid->attach (*wbsizehelper, 2, 0, 1, 1); - 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 ); - - spotbutton->signal_toggled().connect( sigc::mem_fun(*this, &FilmNegative::editToggled) ); -// spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); + 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); + spotbutton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); + // spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); // Editing geometry; create the spot rectangle - Rectangle *spotRect = new Rectangle(); + Rectangle* const spotRect = new Rectangle(); spotRect->filled = false; - EditSubscriber::visibleGeometry.push_back( spotRect ); + visibleGeometry.push_back(spotRect); // 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(); + // This is to make sure the getCursor() call is fired everywhere. + Rectangle* imgRect = new Rectangle(); imgRect->filled = true; - EditSubscriber::mouseOverGeometry.push_back( imgRect ); - + mouseOverGeometry.push_back(imgRect); } FilmNegative::~FilmNegative() { -// idle_register.destroy(); - - for (std::vector::const_iterator i = visibleGeometry.begin(); i != visibleGeometry.end(); ++i) { - delete *i; + for (auto geometry : visibleGeometry) { + delete geometry; } - for (std::vector::const_iterator i = mouseOverGeometry.begin(); i != mouseOverGeometry.end(); ++i) { - delete *i; - } - -} - - - -void FilmNegative::enabledChanged() -{ - if (listener) { - if (get_inconsistent()) { - listener->panelChanged(EvFilmNegativeEnabled, M("GENERAL_UNCHANGED")); - } else if (getEnabled()) { - listener->panelChanged(EvFilmNegativeEnabled, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(EvFilmNegativeEnabled, M("GENERAL_DISABLED")); - } + for (auto geometry : mouseOverGeometry) { + delete geometry; } } - -void FilmNegative::adjusterChanged(Adjuster* a, double newval) +void FilmNegative::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { - if (listener) { - if(a == redExp || a == greenExp || a == blueExp) { - disableListener(); - if(a == greenExp) { - redExp->setValue(a->getValue() * redRatio); - blueExp->setValue(a->getValue() * blueRatio); - } else if(a == redExp) { - redRatio = newval / greenExp->getValue(); - } else if(a == blueExp) { - blueRatio = newval / greenExp->getValue(); - } - enableListener(); + disableListener(); - if(getEnabled()) { - listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( - "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); - } - } - } -} - -void FilmNegative::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - -void FilmNegative::setEditProvider (EditDataProvider* provider) -{ - EditSubscriber::setEditProvider(provider); -} - -void FilmNegative::editToggled () -{ - if (spotbutton->get_active()) { - subscribe(); - - int w, h; - getEditProvider()->getImageSize(w, h); - - // Stick a dummy rectangle over the whole image in mouseOverGeometry. - // This is to make sure the getCursor call is fired everywhere. - const auto imgRect = static_cast(mouseOverGeometry.at(0)); - imgRect->setXYWH(0, 0, w, h); - - } else { - this->refSpotCoords.clear(); - unsubscribe(); - } -} - - -void FilmNegative::read (const ProcParams* pp, const ParamsEdited* pedited) -{ - disableListener (); - - if(pedited) { + if (pedited) { redExp->setEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); greenExp->setEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); blueExp->setEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); @@ -208,10 +135,10 @@ void FilmNegative::read (const ProcParams* pp, const ParamsEdited* pedited) greenExp->setValue(pp->filmNegative.greenExp); blueExp->setValue(pp->filmNegative.blueExp); - enableListener (); + enableListener(); } -void FilmNegative::write (ProcParams* pp, ParamsEdited* pedited) +void FilmNegative::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) { pp->filmNegative.redExp = redExp->getValue(); pp->filmNegative.greenExp = greenExp->getValue(); @@ -226,37 +153,103 @@ void FilmNegative::write (ProcParams* pp, ParamsEdited* pedited) } } -void FilmNegative::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +void FilmNegative::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) { redExp->setValue(defParams->filmNegative.redExp); greenExp->setValue(defParams->filmNegative.greenExp); blueExp->setValue(defParams->filmNegative.blueExp); if (pedited) { - redExp->setDefaultEditedState (pedited->filmNegative.redExp ? Edited : UnEdited); - greenExp->setDefaultEditedState (pedited->filmNegative.greenExp ? Edited : UnEdited); - blueExp->setDefaultEditedState (pedited->filmNegative.blueExp ? Edited : UnEdited); + redExp->setDefaultEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); + greenExp->setDefaultEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); + blueExp->setDefaultEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); } else { - redExp->setDefaultEditedState (Irrelevant); - greenExp->setDefaultEditedState (Irrelevant); - blueExp->setDefaultEditedState (Irrelevant); + redExp->setDefaultEditedState(Irrelevant); + greenExp->setDefaultEditedState(Irrelevant); + blueExp->setDefaultEditedState(Irrelevant); } } -void FilmNegative::setBatchMode (bool batchMode) +void FilmNegative::setBatchMode(bool batchMode) { spotConn.disconnect(); removeIfThere(this, spotgrid, false); - ToolPanel::setBatchMode (batchMode); - redExp->showEditedCB (); - greenExp->showEditedCB (); - blueExp->showEditedCB (); + ToolPanel::setBatchMode(batchMode); + redExp->showEditedCB(); + greenExp->showEditedCB(); + blueExp->showEditedCB(); +} + +void FilmNegative::adjusterChanged(Adjuster* a, double newval) +{ + if (listener) { + if (a == redExp || a == greenExp || a == blueExp) { + disableListener(); + if (a == greenExp) { + redExp->setValue(a->getValue() * redRatio); + blueExp->setValue(a->getValue() * blueRatio); + } + else if (a == redExp) { + redRatio = newval / greenExp->getValue(); + } + else if (a == blueExp) { + blueRatio = newval / greenExp->getValue(); + } + enableListener(); + + if (getEnabled()) { + listener->panelChanged( + evFilmNegativeExponents, + Glib::ustring::compose( + "R=%1 ; G=%2 ; B=%3", + redExp->getTextValue(), + greenExp->getTextValue(), + blueExp->getTextValue() + ) + ); + } + } + } +} + +void FilmNegative::adjusterAutoToggled(Adjuster* a, bool newval) +{ +} + +void FilmNegative::enabledChanged() +{ + if (listener) { + if (get_inconsistent()) { + listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_UNCHANGED")); + } + else if (getEnabled()) { + listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_ENABLED")); + } + else { + listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_DISABLED")); + } + } +} + +void FilmNegative::setFilmNegProvider(FilmNegProvider* p) +{ + fnp = p; +} + +void FilmNegative::setEditProvider(EditDataProvider* provider) +{ + EditSubscriber::setEditProvider(provider); +} + +CursorShape FilmNegative::getCursor(int objectID) const +{ + return CSSpotWB; } bool FilmNegative::mouseOver(int modifierKey) { - EditDataProvider *provider = getEditProvider(); - const auto spotRect = static_cast(visibleGeometry.at(0)); + EditDataProvider* const provider = getEditProvider(); + Rectangle* const spotRect = static_cast(visibleGeometry.at(0)); spotRect->setXYWH(provider->posImage.x - 16, provider->posImage.y - 16, 32, 32); return true; @@ -264,20 +257,18 @@ bool FilmNegative::mouseOver(int modifierKey) bool FilmNegative::button1Pressed(int modifierKey) { - EditDataProvider *provider = getEditProvider(); + EditDataProvider* const provider = getEditProvider(); - if(provider) { // debug. remove me + if (provider) { // TODO: Remove me (rom9) printf("x=%d y=%d pv1=%f pv2=%f pv3=%f\n", provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); } EditSubscriber::action = EditSubscriber::Action::NONE; if (listener) { - refSpotCoords.push_back(provider->posImage); - if(refSpotCoords.size() == 2) { - + if (refSpotCoords.size() == 2) { // User has selected 2 reference gray spots. Calculating new exponents // from channel values and updating parameters. @@ -292,8 +283,15 @@ bool FilmNegative::button1Pressed(int modifierKey) enableListener(); if (listener && getEnabled()) { - listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( - "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); + listener->panelChanged( + evFilmNegativeExponents, + Glib::ustring::compose( + "R=%1 ; G=%2 ; B=%3", + redExp->getTextValue(), + greenExp->getTextValue(), + blueExp->getTextValue() + ) + ); } } @@ -304,35 +302,50 @@ bool FilmNegative::button1Pressed(int modifierKey) return true; } -bool FilmNegative::button1Released () +bool FilmNegative::button1Released() { - EditDataProvider *provider = getEditProvider(); + EditDataProvider* const provider = getEditProvider(); - if(provider) { // debug. remove me + if (provider) { // TODO: Remove me (rom9) printf("x=%d y=%d pv1=%f pv2=%f pv3=%f\n", provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); } EditSubscriber::action = EditSubscriber::Action::NONE; + return true; } -// TODO remove me ; couldn't make Action::PICKING work -bool FilmNegative::pick1 (bool picked) { - EditDataProvider *provider = getEditProvider(); - if(provider) { // debug. remove me - printf("Picked pick=%d x=%d y=%d pv1=%f pv2=%f pv3=%f\n", picked, provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); - } - return true; -} - -CursorShape FilmNegative::getCursor(int objectID) const -{ - return CSSpotWB; -} - -void FilmNegative::switchOffEditMode () +void FilmNegative::switchOffEditMode() { refSpotCoords.clear(); unsubscribe(); spotbutton->set_active(false); } + +// TODO: Remove me ; couldn't make Action::PICKING work (rom9) +bool FilmNegative::pick1(bool picked) +{ + EditDataProvider* const provider = getEditProvider(); + if (provider) { // TODO: Remove me (rom9) + printf("Picked pick=%d x=%d y=%d pv1=%f pv2=%f pv3=%f\n", picked, provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); + } + return true; +} + +void FilmNegative::editToggled() +{ + if (spotbutton->get_active()) { + subscribe(); + + int w, h; + getEditProvider()->getImageSize(w, h); + + // Stick a dummy rectangle over the whole image in mouseOverGeometry. + // This is to make sure the getCursor() call is fired everywhere. + Rectangle* const imgRect = static_cast(mouseOverGeometry.at(0)); + imgRect->setXYWH(0, 0, w, h); + } else { + refSpotCoords.clear(); + unsubscribe(); + } +} diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index b9dc15378..31d561127 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2019 rom9 * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,66 +28,66 @@ #include "toolpanel.h" #include "wbprovider.h" -#include "../rtengine/procparams.h" +#include "../rtengine/noncopyable.h" class FilmNegProvider { public: virtual ~FilmNegProvider() = default; + virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) = 0; }; -class FilmNegative : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public EditSubscriber +class FilmNegative : + public rtengine::NonCopyable, + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public EditSubscriber { - -private: - rtengine::ProcEvent EvFilmNegativeExponents; - rtengine::ProcEvent EvFilmNegativeEnabled; - - std::vector refSpotCoords; - - FilmNegProvider *fnp; - - Adjuster* redExp; - Adjuster* greenExp; - Adjuster* blueExp; - - Gtk::Grid* spotgrid; - Gtk::ToggleButton* spotbutton; - sigc::connection spotConn; - - double redRatio, blueRatio; - - void editToggled (); - public: + FilmNegative(); + ~FilmNegative() override; - FilmNegative (); - ~FilmNegative () override; + void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; + void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void setBatchMode(bool batchMode) override; - void setFilmNegProvider(FilmNegProvider* p) - { - fnp = p; - }; - - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; - void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; - void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; - void setBatchMode (bool batchMode) override; - - void adjusterChanged (Adjuster* a, double newval) override; + void adjusterChanged(Adjuster* a, double newval) override; void adjusterAutoToggled(Adjuster* a, bool newval) override; - void spotPressed (); void enabledChanged() override; - void setEditProvider (EditDataProvider* provider) override; + void setFilmNegProvider(FilmNegProvider* p); + + void setEditProvider(EditDataProvider* provider) override; // EditSubscriber interface CursorShape getCursor(int objectID) const override; bool mouseOver(int modifierKey) override; bool button1Pressed(int modifierKey) override; bool button1Released() override; - void switchOffEditMode () override; + void switchOffEditMode() override; bool pick1(bool picked) override; +private: + void editToggled(); + + const rtengine::ProcEvent evFilmNegativeExponents; + const rtengine::ProcEvent evFilmNegativeEnabled; + + std::vector refSpotCoords; + + FilmNegProvider* fnp; + + Adjuster* const redExp; + Adjuster* const greenExp; + Adjuster* const blueExp; + + Gtk::Grid* const spotgrid; + Gtk::ToggleButton* const spotbutton; + sigc::connection spotConn; + + double redRatio; + double blueRatio; }; From 8de581ac39cc4686d50a7908eadf80780fbb0848 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Mon, 17 Jun 2019 21:46:50 +0200 Subject: [PATCH 022/222] Removed old debugging stuff from rtgui/filmnegative.cc --- rtgui/filmnegative.cc | 21 --------------------- rtgui/filmnegative.h | 1 - 2 files changed, 22 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 0e0f1ee51..8e0e5133f 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -274,10 +274,6 @@ bool FilmNegative::button1Pressed(int modifierKey) { EditDataProvider* const provider = getEditProvider(); - if (provider) { // TODO: Remove me (rom9) - printf("x=%d y=%d pv1=%f pv2=%f pv3=%f\n", provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); - } - EditSubscriber::action = EditSubscriber::Action::NONE; if (listener) { @@ -319,14 +315,7 @@ bool FilmNegative::button1Pressed(int modifierKey) bool FilmNegative::button1Released() { - EditDataProvider* const provider = getEditProvider(); - - if (provider) { // TODO: Remove me (rom9) - printf("x=%d y=%d pv1=%f pv2=%f pv3=%f\n", provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); - } - EditSubscriber::action = EditSubscriber::Action::NONE; - return true; } @@ -337,16 +326,6 @@ void FilmNegative::switchOffEditMode() spotbutton->set_active(false); } -// TODO: Remove me ; couldn't make Action::PICKING work (rom9) -bool FilmNegative::pick1(bool picked) -{ - EditDataProvider* const provider = getEditProvider(); - if (provider) { // TODO: Remove me (rom9) - printf("Picked pick=%d x=%d y=%d pv1=%f pv2=%f pv3=%f\n", picked, provider->posImage.x, provider->posImage.y, provider->getPipetteVal1(), provider->getPipetteVal2(), provider->getPipetteVal3()); - } - return true; -} - void FilmNegative::editToggled() { if (spotbutton->get_active()) { diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index e29a20103..655217367 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -68,7 +68,6 @@ public: bool button1Pressed(int modifierKey) override; bool button1Released() override; void switchOffEditMode() override; - bool pick1(bool picked) override; private: void editToggled(); From 7c0275ca1a034dacb8f130bfffc40e5399a52f7b Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 18 Jun 2019 13:52:58 +0200 Subject: [PATCH 023/222] Updated copyright notice in new source files --- rtengine/filmnegativeproc.cc | 2 +- rtgui/filmnegative.cc | 2 +- rtgui/filmnegative.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index f367c4368..bd68314e3 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2019 rom9 + * Copyright (c) 2019 Alberto Romei * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 8e0e5133f..b6cb9f1c6 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2019 rom9 + * Copyright (c) 2019 Alberto Romei * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 655217367..b21bc23c3 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2019 rom9 + * Copyright (c) 2019 Alberto Romei * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From c9c834dc633ac98b17be363b214526125491b691 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 18 Jun 2019 21:02:53 +0200 Subject: [PATCH 024/222] Very honored to add myself to AUTHORS.txt, as suggested by heckflosse: https://github.com/Beep6581/RawTherapee/pull/5349#pullrequestreview-247409279 --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 15e3e13d4..160869776 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -28,6 +28,7 @@ Development contributors, in last name alphabetical order: Adam Reichold Philip Rinn Jan Rinze + Alberto Romei Ben S. Andrey Skvortsov Fabio Suprani From 03dc855fc73898b5957fdf1d39c26a612d6938f5 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 18 Jun 2019 21:08:18 +0200 Subject: [PATCH 025/222] Merged cleanup patch proposed by heckflosse, moves exponents negation to a single place. Now it's much easier to read. --- rtengine/filmnegativeproc.cc | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index bd68314e3..f5a231c05 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -172,10 +172,12 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ return; } + // Exponents are expressed as positive in the parameters, so negate them in order + // to get the reciprocals. const std::array exps = { - static_cast(params.redExp), - static_cast(params.greenExp), - static_cast(params.blueExp) + static_cast(-params.redExp), + static_cast(-params.greenExp), + static_cast(-params.blueExp) }; MyTime t1, t2, t3,t4, t5; @@ -244,8 +246,8 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ // Find median values for each channel if (!cvs[c].empty()) { findMinMaxPercentile(cvs[c].data(), cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); - medians[c] = pow_F(rtengine::max(medians[c], 1.f), -exps[c]); - // Determine the channel multipler so that N times the median becomes 65k. This clips away + medians[c] = pow_F(rtengine::max(medians[c], 1.f), exps[c]); + // Determine the channel multiplier so that N times the median becomes 65k. This clips away // the values in the dark border surrounding the negative (due to the film holder, for example), // the reciprocal of which have blown up to stellar values. mults[c] = MAX_OUT_VALUE / (medians[c] * 24.f); @@ -274,10 +276,9 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ #endif for (int row = 0; row < H; ++row) { int col = 0; - // Exponents are expressed as positive in the parameters, so negate them in order - // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. - const float exps0 = -exps[FC(row, col)]; - const float exps1 = -exps[FC(row, col + 1)]; + // Avoid trouble with zeroes, minimum pixel value is 1. + const float exps0 = exps[FC(row, col)]; + const float exps1 = exps[FC(row, col + 1)]; const float mult0 = mults[FC(row, col)]; const float mult1 = mults[FC(row, col + 1)]; #ifdef __SSE2__ @@ -306,15 +307,14 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ #endif for (int row = 0; row < H; row ++) { int col = 0; - // Exponents are expressed as positive in the parameters, so negate them in order - // to get the reciprocals. Avoid trouble with zeroes, minimum pixel value is 1. + // Avoid trouble with zeroes, minimum pixel value is 1. const std::array expsc = { - -exps[ri->XTRANSFC(row, 0)], - -exps[ri->XTRANSFC(row, 1)], - -exps[ri->XTRANSFC(row, 2)], - -exps[ri->XTRANSFC(row, 3)], - -exps[ri->XTRANSFC(row, 4)], - -exps[ri->XTRANSFC(row, 5)] + exps[ri->XTRANSFC(row, 0)], + exps[ri->XTRANSFC(row, 1)], + exps[ri->XTRANSFC(row, 2)], + exps[ri->XTRANSFC(row, 3)], + exps[ri->XTRANSFC(row, 4)], + exps[ri->XTRANSFC(row, 5)] }; const std::array multsc = { mults[ri->XTRANSFC(row, 0)], From 789edc5bd32c9a604ce71544836d06695b576c49 Mon Sep 17 00:00:00 2001 From: Eric Jiang Date: Tue, 18 Jun 2019 18:02:10 -0700 Subject: [PATCH 026/222] Apply code-cleanup patch from @Floessie See https://github.com/Beep6581/RawTherapee/pull/5325 --- rtengine/imagedata.cc | 73 +++++++++++++++++++++-------------------- rtengine/imagedata.h | 2 +- rtgui/cacheimagedata.cc | 37 +++++++++++++++++---- 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 26fe80f03..faa7ad5ed 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -69,37 +69,40 @@ FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname, std::uniqu return new FramesData (fname, std::move(rml), firstFrameOnly); } -FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) - : frameRootDir(frameRootDir_), iptc(nullptr), time(), timeStamp(), iso_speed(0), aperture(0.), focal_len(0.), focal_len35mm(0.), focus_dist(0.f), - shutter(0.), expcomp(0.), make("Unknown"), model("Unknown"), orientation("Unknown"), rating(0), lens("Unknown"), - sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), isHDR(false) +FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) : + frameRootDir(frameRootDir_), + iptc(nullptr), + time{}, + timeStamp{}, + iso_speed(0), + aperture(0.), + focal_len(0.), + focal_len35mm(0.), + focus_dist(0.f), + shutter(0.), + expcomp(0.), + make("Unknown"), + model("Unknown"), + orientation("Unknown"), + rating(0), + lens("Unknown"), + sampleFormat(IIOSF_UNKNOWN), + isPixelShift(false), + isHDR(false) { - memset (&time, 0, sizeof(time)); - if (!frameRootDir) { return; } - rtexif::Tag* tag; - rtexif::TagDirectory* newFrameRootDir = frameRootDir; - - memset(&time, 0, sizeof(time)); - timeStamp = 0; - iso_speed = 0; - aperture = 0.0; - focal_len = 0.0; - focal_len35mm = 0.0; - focus_dist = 0.0f; - shutter = 0.0; - expcomp = 0.0; make.clear(); model.clear(); serial.clear(); orientation.clear(); lens.clear(); - rating = 0; - tag = newFrameRootDir->findTag("Make"); + rtexif::TagDirectory* newFrameRootDir = frameRootDir; + + rtexif::Tag* tag = newFrameRootDir->findTag("Make"); if (!tag) { newFrameRootDir = rootDir; tag = newFrameRootDir->findTag("Make"); @@ -198,17 +201,11 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* } char sXMPRating[64]; if (newFrameRootDir->getXMPTagValue("xmp:Rating", sXMPRating)) { - rating = atoi(sXMPRating); - } - // guard against out-of-range values - if (rating > 5) { - rating = 5; - } - // Currently, Rating=-1 is not supported. A value of -1 should mean - // "Rejected" according to the specification. Maybe in the future, Rating=-1 - // sets InTrash=true? - if (rating < 0) { - rating = 0; + // Guard against out-of-range values (<0, >5) + rating = rtengine::max(0, rtengine::min(5, atoi(sXMPRating))); + // Currently, Rating=-1 is not supported. A value of -1 should mean + // "Rejected" according to the specification. Maybe in the future, Rating=-1 + // sets InTrash=true? } tag = newFrameRootDir->findTagUpward("MakerNote"); @@ -1197,15 +1194,21 @@ std::string FramesData::getOrientation(unsigned int frame) const } ); } -int FramesData::getRating (unsigned int frame) const + +int FramesData::getRating(unsigned int frame) const { - return frames.empty() || frame >= frames.size() ? 0 : frames.at(frame)->getRating (); + return getFromFrame( + frames, + frame, + [](const FrameData& frame_data) + { + return frame_data.getRating(); + } + ); } - //------inherited functions--------------// - std::string FramesMetaData::apertureToString (double aperture) { diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 097a5cc80..d06820296 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -127,7 +127,7 @@ public: std::string getModel (unsigned int frame = 0) const override; std::string getLens (unsigned int frame = 0) const override; std::string getSerialNumber (unsigned int frame = 0) const; - std::string getOrientation (unsigned int frame = 0) const; + std::string getOrientation (unsigned int frame = 0) const override; int getRating (unsigned int frame = 0) const override; }; diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 47318990d..1756f523b 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -24,12 +24,37 @@ #include "../rtengine/procparams.h" -CacheImageData::CacheImageData () - : md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false), - timeValid(false), year(0), month(0), day(0), hour(0), min(0), sec(0), exifValid(false), frameCount(1), - fnumber(0.0), shutter(0.0), focalLen(0.0), focalLen35mm(0.0), focusDist(0.f), iso(0), rating(0), isHDR (false), - isPixelShift (false), sensortype(rtengine::ST_NONE), sampleFormat(rtengine::IIOSF_UNKNOWN), - redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), rotate(0), thumbImgType(0) +CacheImageData::CacheImageData() : + supported(false), + format(FT_Invalid), + rankOld(-1), + inTrashOld(false), + recentlySaved(false), + timeValid(false), + year(0), + month(0), + day(0), + hour(0), + min(0), + sec(0), + exifValid(false), + frameCount(1), + fnumber(0.0), + shutter(0.0), + focalLen(0.0), + focalLen35mm(0.0), + focusDist(0.f), + iso(0), + rating(0), + isHDR (false), + isPixelShift (false), + sensortype(rtengine::ST_NONE), + sampleFormat(rtengine::IIOSF_UNKNOWN), + redAWBMul(-1.0), + greenAWBMul(-1.0), + blueAWBMul(-1.0), + rotate(0), + thumbImgType(0) { } From 880a6e125e85977f590de24ec60bbe40710193e9 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 21 Jun 2019 07:12:42 +0200 Subject: [PATCH 027/222] Added film negative processing in thumbnails, with correct white balance. Calculated channel averages to restore the same initial conditions as RawImageSource, where get_colorsCoeff is called with forceAutoWB = true. Code still needs refinement and cleanup. --- rtengine/rtthumbnail.cc | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 0a74cf8c2..52691475e 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -39,9 +39,12 @@ #include "settings.h" #include "procparams.h" #include +#define BENCHMARK #include "StopWatch.h" #include "median.h" +#include "rt_algo.h" + namespace { @@ -1167,6 +1170,75 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT Imagefloat* baseImg = resizeTo (rwidth, rheight, interp, thumbImg); + if(isRaw && params.filmNegative.enabled) { + StopWatch stop1("Thumbnail film negative", true); + + // Channel exponents + const float rexp = -params.filmNegative.redExp; + const float gexp = -params.filmNegative.greenExp; + const float bexp = -params.filmNegative.blueExp; + + // Need to calculate channel averages, to fake the same conditions + // found in rawimagesource, where get_ColorsCoeff is called with + // forceAutoWB=true. + float rsum = 0.f, gsum = 0.f, bsum = 0.f; + + // Channel vectors to calculate medians + std::vector rv, gv, bv; + + for (int i = 0; i < rheight; i++) { + for (int j = 0; j < rwidth; j++) { + const float r = baseImg->r(i, j); + const float g = baseImg->g(i, j); + const float b = baseImg->b(i, j); + + rsum += r; + gsum += g; + bsum += b; + + rv.push_back(r); + gv.push_back(g); + bv.push_back(b); + } + } + + const float ravg = rsum / (rheight*rwidth); + const float gavg = gsum / (rheight*rwidth); + const float bavg = bsum / (rheight*rwidth); + + // Shifting current WB multipliers, based on channel averages. + rmi /= (gavg/ravg); + // gmi /= (gAvg/gAvg); green chosen as reference channel + bmi /= (gavg/bavg); + + float rmed, gmed, bmed; + findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); + findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); + findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); + + rmed = powf(rmed, rexp); + gmed = powf(gmed, gexp); + bmed = powf(bmed, bexp); + + const float MAX_OUT_VALUE = 65000.f; + const float rmult = (MAX_OUT_VALUE / (rmed * 24)) ; + const float gmult = (MAX_OUT_VALUE / (gmed * 24)) ; + const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ; + + if (settings->verbose) { + printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); + printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); + } + + for (int i = 0; i < rheight; i++) { + for (int j = 0; j < rwidth; j++) { + baseImg->r(i, j) = CLIP(rmult * powf(baseImg->r (i, j), rexp)); + baseImg->g(i, j) = CLIP(gmult * powf(baseImg->g (i, j), gexp)); + baseImg->b(i, j) = CLIP(bmult * powf(baseImg->b (i, j), bexp)); + } + } + } + if (params.coarse.rotate) { baseImg->rotate (params.coarse.rotate); rwidth = baseImg->getWidth(); From 8c6458daff364af5fb8c621009f0ec1fd417a707 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 21 Jun 2019 20:51:50 +0200 Subject: [PATCH 028/222] Removed "lock channels" CheckButton, it wasn't very useful. Keeping the "(lead)" note on the green channel label, to give a hint that this slider controls the other two as well. --- rtdata/languages/default | 2 -- rtgui/filmnegative.cc | 20 -------------------- rtgui/filmnegative.h | 4 ---- 3 files changed, 26 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 36e441015..79fdc5729 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1642,8 +1642,6 @@ TP_FILMNEGATIVE_BLUE;Blue 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/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index b6cb9f1c6..36f2e7c34 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -54,18 +54,11 @@ 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); @@ -93,13 +86,11 @@ 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) ); @@ -183,11 +174,7 @@ void FilmNegative::setBatchMode(bool batchMode) { 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(); @@ -343,10 +330,3 @@ 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 b21bc23c3..b8aa338c6 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -71,7 +71,6 @@ public: private: void editToggled(); - void lockChannelsToggled(); const rtengine::ProcEvent evFilmNegativeExponents; const rtengine::ProcEvent evFilmNegativeEnabled; @@ -84,9 +83,6 @@ 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; From 2fde6e562ad52cff16c098651377d20a0e35b8cd Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Sun, 23 Jun 2019 22:21:24 +0200 Subject: [PATCH 029/222] The "dual-spot" exponents calculation feature now honors the master (green) exponent set by the user, and adjusts red and blue based on the ratios between the new, "guessed" exponents. This way, if the user has chosen a different master exponent than the default, using the feature just alters the color characteristic of the conversion, while keeping the same contrast level. --- rtengine/filmnegativeproc.cc | 4 ++-- rtgui/filmnegative.cc | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index f5a231c05..eed10fdc4 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -151,9 +151,9 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s // compared to the ratio in the reference channel (green) for (int ch = 0; ch < 3; ++ch) { if (ch == 1) { - newExps[ch] = 2.f; // Green is the reference channel + newExps[ch] = 1.f; // Green is the reference channel } else { - newExps[ch] = CLAMP(2.f * logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 6.f); + newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 6.f); } } diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 36f2e7c34..d84c1bd0a 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -273,11 +273,12 @@ bool FilmNegative::button1Pressed(int modifierKey) std::array newExps; if (fnp->getFilmNegativeExponents(refSpotCoords[0], refSpotCoords[1], newExps)) { disableListener(); - redExp->setValue(newExps[0]); - greenExp->setValue(newExps[1]); - blueExp->setValue(newExps[2]); - redRatio = redExp->getValue() / greenExp->getValue(); - blueRatio = blueExp->getValue() / greenExp->getValue(); + // Leaving green exponent unchanged, setting red and blue exponents based on + // the ratios between newly calculated exponents. + redRatio = newExps[0] / newExps[1]; + blueRatio = newExps[2] / newExps[1]; + redExp->setValue(greenExp->getValue() * redRatio); + blueExp->setValue(greenExp->getValue() * blueRatio); enableListener(); if (listener && getEnabled()) { From 22f6297a5bd09e04482949ad91c847389e3b6b64 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Mon, 24 Jun 2019 21:48:06 +0200 Subject: [PATCH 030/222] Removed clipping check for values above 65535 (reverts commit 9156572). It was just a defensive check to avoid hitting corner cases like this: 1e4f9ac , that is already fixed elsewhere. The check is now causing problems with the dual-spot feature, because after clipping, the formula cannot be undone to get back the original raw values. Since there are no known issues caused by raw values >65k, i'm removing the check until there will be a good reason to re-introduce it. --- rtengine/filmnegativeproc.cc | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index eed10fdc4..6e2f4e37c 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -268,7 +268,6 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ if (ri->getSensorType() == ST_BAYER) { #ifdef __SSE2__ const vfloat onev = F2V(1.f); - const vfloat c65535v = F2V(65535.f); #endif #ifdef _OPENMP @@ -285,21 +284,20 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1); const vfloat multsv = _mm_setr_ps(mult0, mult1, mult0, mult1); for (; col < W - 3; col += 4) { - STVFU(rawData[row][col], vminf(multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv), c65535v)); + STVFU(rawData[row][col], multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv)); } #endif // __SSE2__ for (; col < W - 1; col += 2) { - rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), 65535.f); - rawData[row][col + 1] = rtengine::min(mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1), 65535.f); + rawData[row][col] = mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0); + rawData[row][col + 1] = mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1); } if (col < W) { - rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), 65535.f); + rawData[row][col] = mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0); } } } else if (ri->getSensorType() == ST_FUJI_XTRANS) { #ifdef __SSE2__ const vfloat onev = F2V(1.f); - const vfloat c65535v = F2V(65535.f); #endif #ifdef _OPENMP @@ -332,18 +330,18 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ const vfloat multsv1 = _mm_setr_ps(multsc[4], multsc[5], multsc[0], multsc[1]); const vfloat multsv2 = _mm_setr_ps(multsc[2], multsc[3], multsc[4], multsc[5]); for (; col < W - 11; col += 12) { - STVFU(rawData[row][col], vminf(multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0), c65535v)); - STVFU(rawData[row][col + 4], vminf(multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1), c65535v)); - STVFU(rawData[row][col + 8], vminf(multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2), c65535v)); + STVFU(rawData[row][col], multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0)); + STVFU(rawData[row][col + 4], multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1)); + STVFU(rawData[row][col + 8], multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2)); } #endif // __SSE2__ for (; col < W - 5; col += 6) { for (int c = 0; c < 6; ++c) { - rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); + rawData[row][col + c] = multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]); } } for (int c = 0; col < W; col++, c++) { - rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), 65535.f); + rawData[row][col + c] = multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]); } } } From 157d83d1694754d837f30ce85314806e950b444b Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Wed, 26 Jun 2019 00:14:03 +0200 Subject: [PATCH 031/222] Partially reverting my last commit. When using large exponents, huge raw values could cause segfaults in ImProcFunctions:rgbProc (specifically in shadowToneCurve), and in Amaze demosaic. Re-added the clipping check on raw values, but with a higher threshold. This way, raw clipping is less frequent in highlight areas (so those can be used as spots for exponents calculation), but the threshold is low enough to avoid the segfaults. Not a very clean solution, need to find a better one... --- rtengine/filmnegativeproc.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 6e2f4e37c..555a47506 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -263,11 +263,14 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ printf("Median calc time us: %d\n", t3.etime(t2)); } + constexpr float CLIP_VAL = 20 * MAX_OUT_VALUE; + t3.set(); if (ri->getSensorType() == ST_BAYER) { #ifdef __SSE2__ const vfloat onev = F2V(1.f); + const vfloat clipv = F2V(CLIP_VAL); #endif #ifdef _OPENMP @@ -284,20 +287,21 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1); const vfloat multsv = _mm_setr_ps(mult0, mult1, mult0, mult1); for (; col < W - 3; col += 4) { - STVFU(rawData[row][col], multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv)); + STVFU(rawData[row][col], vminf(multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv), clipv)); } #endif // __SSE2__ for (; col < W - 1; col += 2) { - rawData[row][col] = mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0); - rawData[row][col + 1] = mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1); + rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL); + rawData[row][col + 1] = rtengine::min(mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1), CLIP_VAL); } if (col < W) { - rawData[row][col] = mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0); + rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL); } } } else if (ri->getSensorType() == ST_FUJI_XTRANS) { #ifdef __SSE2__ const vfloat onev = F2V(1.f); + const vfloat clipv = F2V(CLIP_VAL); #endif #ifdef _OPENMP @@ -330,18 +334,18 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ const vfloat multsv1 = _mm_setr_ps(multsc[4], multsc[5], multsc[0], multsc[1]); const vfloat multsv2 = _mm_setr_ps(multsc[2], multsc[3], multsc[4], multsc[5]); for (; col < W - 11; col += 12) { - STVFU(rawData[row][col], multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0)); - STVFU(rawData[row][col + 4], multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1)); - STVFU(rawData[row][col + 8], multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2)); + STVFU(rawData[row][col], vminf(multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0), clipv)); + STVFU(rawData[row][col + 4], vminf(multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1), clipv)); + STVFU(rawData[row][col + 8], vminf(multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2), clipv)); } #endif // __SSE2__ for (; col < W - 5; col += 6) { for (int c = 0; c < 6; ++c) { - rawData[row][col + c] = multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]); + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL); } } for (int c = 0; col < W; col++, c++) { - rawData[row][col + c] = multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]); + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL); } } } From 63a6e1b79cc4a6033c2fcb77b74d78857423829b Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Wed, 26 Jun 2019 01:06:48 +0200 Subject: [PATCH 032/222] Changed GUI behaviour so that the first slider sets the reference exponent (green channel), and the other two sliders set the ratio of the red/blue exponent to the reference one. This should be more intuitive, and less confusing when clicking on the reset-to-default slider button. Now the first slider sets the general contrast, while the other two affect the color. Lowered exponent slider max value from 6 to 4 (it was too large to be useful). New sliders are log-scale. --- rtdata/languages/default | 6 +-- rtgui/filmnegative.cc | 87 +++++++++++++++++----------------------- rtgui/filmnegative.h | 7 +--- 3 files changed, 42 insertions(+), 58 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 79fdc5729..63c877bbf 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1638,12 +1638,12 @@ TP_EXPOSURE_TCMODE_STANDARD;Standard 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 (lead) +TP_FILMNEGATIVE_BLUE;Blue ratio +TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) 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_PICK;Pick white and black spots -TP_FILMNEGATIVE_RED;Red exponent +TP_FILMNEGATIVE_RED;Red ratio TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots TP_FILMSIMULATION_LABEL;Film Simulation TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index d84c1bd0a..129af3034 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -30,11 +30,15 @@ namespace { -Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring& label, double defaultVal) +Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring& label, double minV, double maxV, double defaultVal, bool log) { - Adjuster* const adj = Gtk::manage(new Adjuster(label, 0.3, 6, 0.001, defaultVal)); // exponent + Adjuster* const adj = Gtk::manage(new Adjuster(label, minV, maxV, 0.001, defaultVal)); // exponent adj->setAdjusterListener(listener); + if (log) { + adj->setLogScale(10, minV, false); + } + if (adj->delay < options.adjusterMaxDelay) { adj->delay = options.adjusterMaxDelay; } @@ -51,13 +55,11 @@ FilmNegative::FilmNegative() : evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS")), evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), fnp(nullptr), - 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)), + greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 2.0, false)), + redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 3, 1.36, true)), + blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 3, 0.86, true)), 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()) + spotbutton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))) { spotgrid->get_style_context()->add_class("grid-spacing"); setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -86,9 +88,9 @@ FilmNegative::FilmNegative() : // spotgrid->attach (*slab, 1, 0, 1, 1); // spotgrid->attach (*wbsizehelper, 2, 0, 1, 1); - pack_start(*redExp, Gtk::PACK_SHRINK, 0); pack_start(*greenExp, Gtk::PACK_SHRINK, 0); - pack_start(*blueExp, Gtk::PACK_SHRINK, 0); + pack_start(*redRatio, Gtk::PACK_SHRINK, 0); + pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); pack_start(*spotgrid, Gtk::PACK_SHRINK, 0); spotbutton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); @@ -124,49 +126,49 @@ void FilmNegative::read(const rtengine::procparams::ProcParams* pp, const Params disableListener(); if (pedited) { - redExp->setEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); + redRatio->setEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); greenExp->setEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); - blueExp->setEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); + blueRatio->setEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); set_inconsistent(multiImage && !pedited->filmNegative.enabled); } setEnabled(pp->filmNegative.enabled); - redExp->setValue(pp->filmNegative.redExp); + redRatio->setValue(pp->filmNegative.redExp / pp->filmNegative.greenExp); greenExp->setValue(pp->filmNegative.greenExp); - blueExp->setValue(pp->filmNegative.blueExp); + blueRatio->setValue(pp->filmNegative.blueExp / pp->filmNegative.greenExp); enableListener(); } void FilmNegative::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) { - pp->filmNegative.redExp = redExp->getValue(); + pp->filmNegative.redExp = greenExp->getValue() * redRatio->getValue(); pp->filmNegative.greenExp = greenExp->getValue(); - pp->filmNegative.blueExp = blueExp->getValue(); + pp->filmNegative.blueExp = greenExp->getValue() * blueRatio->getValue(); pp->filmNegative.enabled = getEnabled(); if (pedited) { - pedited->filmNegative.redExp = redExp->getEditedState(); + pedited->filmNegative.redExp = greenExp->getEditedState() || redRatio->getEditedState(); pedited->filmNegative.greenExp = greenExp->getEditedState(); - pedited->filmNegative.blueExp = blueExp->getEditedState(); + pedited->filmNegative.blueExp = greenExp->getEditedState() || blueRatio->getEditedState(); pedited->filmNegative.enabled = !get_inconsistent(); } } void FilmNegative::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) { - redExp->setValue(defParams->filmNegative.redExp); + redRatio->setValue(defParams->filmNegative.redExp / defParams->filmNegative.greenExp); greenExp->setValue(defParams->filmNegative.greenExp); - blueExp->setValue(defParams->filmNegative.blueExp); + blueRatio->setValue(defParams->filmNegative.blueExp / defParams->filmNegative.greenExp); if (pedited) { - redExp->setDefaultEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); + redRatio->setDefaultEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); greenExp->setDefaultEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); - blueExp->setDefaultEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); + blueRatio->setDefaultEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); } else { - redExp->setDefaultEditedState(Irrelevant); + redRatio->setDefaultEditedState(Irrelevant); greenExp->setDefaultEditedState(Irrelevant); - blueExp->setDefaultEditedState(Irrelevant); + blueRatio->setDefaultEditedState(Irrelevant); } } @@ -176,37 +178,24 @@ void FilmNegative::setBatchMode(bool batchMode) spotConn.disconnect(); removeIfThere(this, spotgrid, false); ToolPanel::setBatchMode(batchMode); - redExp->showEditedCB(); + redRatio->showEditedCB(); greenExp->showEditedCB(); - blueExp->showEditedCB(); + blueRatio->showEditedCB(); } } void FilmNegative::adjusterChanged(Adjuster* a, double newval) { if (listener) { - if (a == redExp || a == greenExp || a == blueExp) { - disableListener(); - if (a == greenExp) { - redExp->setValue(a->getValue() * redRatio); - blueExp->setValue(a->getValue() * blueRatio); - } - else if (a == redExp) { - redRatio = newval / greenExp->getValue(); - } - else if (a == blueExp) { - blueRatio = newval / greenExp->getValue(); - } - enableListener(); - + if (a == redRatio || a == greenExp || a == blueRatio) { if (getEnabled()) { listener->panelChanged( evFilmNegativeExponents, Glib::ustring::compose( "R=%1 ; G=%2 ; B=%3", - redExp->getTextValue(), - greenExp->getTextValue(), - blueExp->getTextValue() + greenExp->getValue() * redRatio->getValue(), + greenExp->getValue(), + greenExp->getValue() * blueRatio->getValue() ) ); } @@ -275,10 +264,8 @@ bool FilmNegative::button1Pressed(int modifierKey) disableListener(); // Leaving green exponent unchanged, setting red and blue exponents based on // the ratios between newly calculated exponents. - redRatio = newExps[0] / newExps[1]; - blueRatio = newExps[2] / newExps[1]; - redExp->setValue(greenExp->getValue() * redRatio); - blueExp->setValue(greenExp->getValue() * blueRatio); + redRatio->setValue(newExps[0] / newExps[1]); + blueRatio->setValue(newExps[2] / newExps[1]); enableListener(); if (listener && getEnabled()) { @@ -286,9 +273,9 @@ bool FilmNegative::button1Pressed(int modifierKey) evFilmNegativeExponents, Glib::ustring::compose( "R=%1 ; G=%2 ; B=%3", - redExp->getTextValue(), - greenExp->getTextValue(), - blueExp->getTextValue() + greenExp->getValue() * redRatio->getValue(), + greenExp->getValue(), + greenExp->getValue() * blueRatio->getValue() ) ); } diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index b8aa338c6..7de1bd56a 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -79,14 +79,11 @@ private: FilmNegProvider* fnp; - Adjuster* const redExp; Adjuster* const greenExp; - Adjuster* const blueExp; + Adjuster* const redRatio; + Adjuster* const blueRatio; Gtk::Grid* const spotgrid; Gtk::ToggleButton* const spotbutton; sigc::connection spotConn; - - double redRatio; - double blueRatio; }; From a3004bb2b8be6242b927a048d3f68a77456e80fc Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Thu, 27 Jun 2019 22:03:59 +0200 Subject: [PATCH 033/222] Added SSE2 optimization in film negative thumbnail processing. --- rtengine/rtthumbnail.cc | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 52691475e..7e4544a0d 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1229,12 +1229,33 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); } - + +#ifdef __SSE2__ + const vfloat clipv = F2V(MAXVALF); + const vfloat rexpv = F2V(rexp); + const vfloat gexpv = F2V(gexp); + const vfloat bexpv = F2V(bexp); + const vfloat rmultv = F2V(rmult); + const vfloat gmultv = F2V(gmult); + const vfloat bmultv = F2V(bmult); +#endif + for (int i = 0; i < rheight; i++) { - for (int j = 0; j < rwidth; j++) { - baseImg->r(i, j) = CLIP(rmult * powf(baseImg->r (i, j), rexp)); - baseImg->g(i, j) = CLIP(gmult * powf(baseImg->g (i, j), gexp)); - baseImg->b(i, j) = CLIP(bmult * powf(baseImg->b (i, j), bexp)); + float *rline = baseImg->r(i); + float *gline = baseImg->g(i); + float *bline = baseImg->b(i); + int j = 0; +#ifdef __SSE2__ + for (; j < rwidth - 3; j +=4) { + STVFU(rline[j], vminf(rmultv * pow_F(LVFU(rline[j]), rexpv), clipv)); + STVFU(gline[j], vminf(gmultv * pow_F(LVFU(gline[j]), gexpv), clipv)); + STVFU(bline[j], vminf(bmultv * pow_F(LVFU(bline[j]), bexpv), clipv)); + } +#endif + for (; j < rwidth; ++j) { + rline[j] = CLIP(rmult * powf(rline[j], rexp)); + gline[j] = CLIP(gmult * powf(gline[j], gexp)); + bline[j] = CLIP(bmult * powf(bline[j], bexp)); } } } From 938fc63dd0b25200cd4732c10aaa4ab2b51b718e Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Thu, 27 Jun 2019 23:01:51 +0200 Subject: [PATCH 034/222] Replaced `powf` calls with the optimized `pow_F` macro (which also works for the non-SSE2 case). --- rtengine/rtthumbnail.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 7e4544a0d..60052f783 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1253,9 +1253,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT } #endif for (; j < rwidth; ++j) { - rline[j] = CLIP(rmult * powf(rline[j], rexp)); - gline[j] = CLIP(gmult * powf(gline[j], gexp)); - bline[j] = CLIP(bmult * powf(bline[j], bexp)); + rline[j] = CLIP(rmult * pow_F(rline[j], rexp)); + gline[j] = CLIP(gmult * pow_F(gline[j], gexp)); + bline[j] = CLIP(bmult * pow_F(bline[j], bexp)); } } } From d7bab9ba9f7981b3e1710f88ec25df9200c5e11d Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 28 Jun 2019 20:44:40 +0200 Subject: [PATCH 035/222] Changed `channelsAverage()` to sample values from the original data in the RawImage instance, taking into account black levels. This lets me completely revert my awful commit 22f6297a5 and clip values to 65535, as it should be to avoid trouble downstream. --- rtengine/filmnegativeproc.cc | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 555a47506..4abe32b86 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -49,6 +49,7 @@ bool channelsAvg( int width, int height, array2D& rawData, + const float* cblacksom, rtengine::Coord spotPos, int spotSize, const rtengine::procparams::FilmNegativeParams& params, @@ -83,13 +84,9 @@ bool channelsAvg( ++pxCount[ch]; - // If film negative is currently enabled, undo the effect by elevating to 1/exp, - // in order to sample the original, linear value - if (params.enabled) { - avgs[ch] += powf(rawData[r][c], -1.f / (ch == 0 ? params.redExp : ch == 1 ? params.greenExp : params.blueExp)); - } else { - avgs[ch] += rawData[r][c]; - } + // Sample the original unprocessed values from RawImage, subtracting black levels. + // Scaling is irrelevant, as we are only interested in the ratio between two spots. + avgs[ch] += ri->data[r][c] - cblacksom[ch]; } } @@ -118,13 +115,13 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s // Sample first spot transformPosition(spotA.x, spotA.y, tran, spot.x, spot.y); - if (!channelsAvg(ri, W, H, rawData, spot, spotSize, currentParams, clearVals)) { + if (!channelsAvg(ri, W, H, rawData, cblacksom, spot, spotSize, currentParams, clearVals)) { return false; } // Sample second spot transformPosition(spotB.x, spotB.y, tran, spot.x, spot.y); - if (!channelsAvg(ri, W, H, rawData, spot, spotSize, currentParams, denseVals)) { + if (!channelsAvg(ri, W, H, rawData, cblacksom, spot, spotSize, currentParams, denseVals)) { return false; } @@ -263,7 +260,7 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ printf("Median calc time us: %d\n", t3.etime(t2)); } - constexpr float CLIP_VAL = 20 * MAX_OUT_VALUE; + constexpr float CLIP_VAL = 65535.f; t3.set(); From 4e09fd4f212efd3e8b0606302745beb1ef42d066 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 28 Jun 2019 21:29:06 +0200 Subject: [PATCH 036/222] Changed master exponent default from 2.0 to 1.5; it was too large for high-contrast negatives. Set all sliders as log-scale, centered at 1.0, so that reasonable values can be fine-tuned more easily. --- rtengine/filmnegativeproc.cc | 2 +- rtengine/procparams.cc | 6 +++--- rtgui/filmnegative.cc | 15 ++++++--------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 4abe32b86..f3cca1245 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -150,7 +150,7 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s if (ch == 1) { newExps[ch] = 1.f; // Green is the reference channel } else { - newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 6.f); + newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 4.f); } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 4ed97f767..b35faca94 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2736,9 +2736,9 @@ bool MetaDataParams::operator!=(const MetaDataParams &other) const FilmNegativeParams::FilmNegativeParams() : enabled(false), - redExp(2.72), - greenExp(2.0), - blueExp(1.72) + redExp(2.04), + greenExp(1.5), + blueExp(1.29) { } diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 129af3034..0e6ec9e8f 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -30,14 +30,11 @@ namespace { -Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring& label, double minV, double maxV, double defaultVal, bool log) +Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring& label, double minV, double maxV, double defaultVal) { - Adjuster* const adj = Gtk::manage(new Adjuster(label, minV, maxV, 0.001, defaultVal)); // exponent + Adjuster* const adj = Gtk::manage(new Adjuster(label, minV, maxV, 0.001, defaultVal)); adj->setAdjusterListener(listener); - - if (log) { - adj->setLogScale(10, minV, false); - } + adj->setLogScale(6, 1, true); if (adj->delay < options.adjusterMaxDelay) { adj->delay = options.adjusterMaxDelay; @@ -55,9 +52,9 @@ FilmNegative::FilmNegative() : evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS")), evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), fnp(nullptr), - greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 2.0, false)), - redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 3, 1.36, true)), - blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 3, 0.86, true)), + greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 1.5)), + redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 3, 1.36)), + blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 3, 0.86)), spotgrid(Gtk::manage(new Gtk::Grid())), spotbutton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))) { From 536bbf95aad6a0c6e989aef36773ec14378a5fbd Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 28 Jun 2019 22:17:28 +0200 Subject: [PATCH 037/222] Added comments to clarify the difference between default exponents in procparams and default ratios in the GUI sliders. --- rtgui/filmnegative.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 0e6ec9e8f..4956968e3 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -52,9 +52,9 @@ FilmNegative::FilmNegative() : evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS")), evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), fnp(nullptr), - greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 1.5)), - redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 3, 1.36)), - blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 3, 0.86)), + greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 1.5)), // master exponent (green channel) + redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 3, (2.04 / 1.5))), // ratio of red exponent to master exponent + blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 3, (1.29 / 1.5))), // ratio of blue exponent to master exponent spotgrid(Gtk::manage(new Gtk::Grid())), spotbutton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))) { From 0920f6dfe8d5656429ef36147cf356dd9e491a12 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 28 Jun 2019 22:51:22 +0200 Subject: [PATCH 038/222] rawData is not needed anymore in channelsAvg after commit d7bab9ba --- rtengine/filmnegativeproc.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index f3cca1245..db5705a3c 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -48,7 +48,6 @@ bool channelsAvg( const rtengine::RawImage* ri, int width, int height, - array2D& rawData, const float* cblacksom, rtengine::Coord spotPos, int spotSize, @@ -115,13 +114,13 @@ bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D s // Sample first spot transformPosition(spotA.x, spotA.y, tran, spot.x, spot.y); - if (!channelsAvg(ri, W, H, rawData, cblacksom, spot, spotSize, currentParams, clearVals)) { + if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, currentParams, clearVals)) { return false; } // Sample second spot transformPosition(spotB.x, spotB.y, tran, spot.x, spot.y); - if (!channelsAvg(ri, W, H, rawData, cblacksom, spot, spotSize, currentParams, denseVals)) { + if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, currentParams, denseVals)) { return false; } From 41e5899f97bd7055f6ba957c490aeb8d2005c5a0 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 28 Jun 2019 22:54:32 +0200 Subject: [PATCH 039/222] Moved film negative thumbnail processing to own compilation unit --- rtengine/CMakeLists.txt | 1 + rtengine/filmnegativethumb.cc | 139 ++++++++++++++++++++++++++++++++++ rtengine/rtthumbnail.cc | 91 +--------------------- rtengine/rtthumbnail.h | 2 + 4 files changed, 143 insertions(+), 90 deletions(-) create mode 100644 rtengine/filmnegativethumb.cc diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 9ac09fbcc..c5c8afa82 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -62,6 +62,7 @@ set(RTENGINESOURCEFILES fast_demo.cc ffmanager.cc filmnegativeproc.cc + filmnegativethumb.cc flatcurves.cc gauss.cc green_equil_RT.cc diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc new file mode 100644 index 000000000..8889915e6 --- /dev/null +++ b/rtengine/filmnegativethumb.cc @@ -0,0 +1,139 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Romei + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#include + +#ifdef _OPENMP +#include +#endif + +#include "rtengine.h" +#include "rtthumbnail.h" + +#include "mytime.h" +#include "opthelper.h" +#include "procparams.h" +#include "rt_algo.h" +#include "rtengine.h" +#include "settings.h" +#include "procparams.h" +#define BENCHMARK +#include "StopWatch.h" + +namespace rtengine +{ + +extern const Settings* settings; + +} + +void rtengine::Thumbnail::processFilmNegative( + const procparams::ProcParams ¶ms, + const Imagefloat* baseImg, + const int rwidth, const int rheight, + float &rmi, float &gmi, float &bmi +) { + StopWatch stop1("Thumbnail film negative", true); + + // Channel exponents + const float rexp = -params.filmNegative.redExp; + const float gexp = -params.filmNegative.greenExp; + const float bexp = -params.filmNegative.blueExp; + + // Need to calculate channel averages, to fake the same conditions + // found in rawimagesource, where get_ColorsCoeff is called with + // forceAutoWB=true. + float rsum = 0.f, gsum = 0.f, bsum = 0.f; + + // Channel vectors to calculate medians + std::vector rv, gv, bv; + + for (int i = 0; i < rheight; i++) { + for (int j = 0; j < rwidth; j++) { + const float r = baseImg->r(i, j); + const float g = baseImg->g(i, j); + const float b = baseImg->b(i, j); + + rsum += r; + gsum += g; + bsum += b; + + rv.push_back(r); + gv.push_back(g); + bv.push_back(b); + } + } + + const float ravg = rsum / (rheight*rwidth); + const float gavg = gsum / (rheight*rwidth); + const float bavg = bsum / (rheight*rwidth); + + // Shifting current WB multipliers, based on channel averages. + rmi /= (gavg/ravg); + // gmi /= (gAvg/gAvg); green chosen as reference channel + bmi /= (gavg/bavg); + + float rmed, gmed, bmed; + findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); + findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); + findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); + + rmed = powf(rmed, rexp); + gmed = powf(gmed, gexp); + bmed = powf(bmed, bexp); + + const float MAX_OUT_VALUE = 65000.f; + const float rmult = (MAX_OUT_VALUE / (rmed * 24)) ; + const float gmult = (MAX_OUT_VALUE / (gmed * 24)) ; + const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ; + + if (settings->verbose) { + printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); + printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); + } + +#ifdef __SSE2__ + const vfloat clipv = F2V(MAXVALF); + const vfloat rexpv = F2V(rexp); + const vfloat gexpv = F2V(gexp); + const vfloat bexpv = F2V(bexp); + const vfloat rmultv = F2V(rmult); + const vfloat gmultv = F2V(gmult); + const vfloat bmultv = F2V(bmult); +#endif + + for (int i = 0; i < rheight; i++) { + float *rline = baseImg->r(i); + float *gline = baseImg->g(i); + float *bline = baseImg->b(i); + int j = 0; +#ifdef __SSE2__ + for (; j < rwidth - 3; j +=4) { + STVFU(rline[j], vminf(rmultv * pow_F(LVFU(rline[j]), rexpv), clipv)); + STVFU(gline[j], vminf(gmultv * pow_F(LVFU(gline[j]), gexpv), clipv)); + STVFU(bline[j], vminf(bmultv * pow_F(LVFU(bline[j]), bexpv), clipv)); + } +#endif + for (; j < rwidth; ++j) { + rline[j] = CLIP(rmult * pow_F(rline[j], rexp)); + gline[j] = CLIP(gmult * pow_F(gline[j], gexp)); + bline[j] = CLIP(bmult * pow_F(bline[j], bexp)); + } + } +} \ No newline at end of file diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 60052f783..4b0baa685 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -39,12 +39,9 @@ #include "settings.h" #include "procparams.h" #include -#define BENCHMARK #include "StopWatch.h" #include "median.h" -#include "rt_algo.h" - namespace { @@ -1171,93 +1168,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT Imagefloat* baseImg = resizeTo (rwidth, rheight, interp, thumbImg); if(isRaw && params.filmNegative.enabled) { - StopWatch stop1("Thumbnail film negative", true); - - // Channel exponents - const float rexp = -params.filmNegative.redExp; - const float gexp = -params.filmNegative.greenExp; - const float bexp = -params.filmNegative.blueExp; - - // Need to calculate channel averages, to fake the same conditions - // found in rawimagesource, where get_ColorsCoeff is called with - // forceAutoWB=true. - float rsum = 0.f, gsum = 0.f, bsum = 0.f; - - // Channel vectors to calculate medians - std::vector rv, gv, bv; - - for (int i = 0; i < rheight; i++) { - for (int j = 0; j < rwidth; j++) { - const float r = baseImg->r(i, j); - const float g = baseImg->g(i, j); - const float b = baseImg->b(i, j); - - rsum += r; - gsum += g; - bsum += b; - - rv.push_back(r); - gv.push_back(g); - bv.push_back(b); - } - } - - const float ravg = rsum / (rheight*rwidth); - const float gavg = gsum / (rheight*rwidth); - const float bavg = bsum / (rheight*rwidth); - - // Shifting current WB multipliers, based on channel averages. - rmi /= (gavg/ravg); - // gmi /= (gAvg/gAvg); green chosen as reference channel - bmi /= (gavg/bavg); - - float rmed, gmed, bmed; - findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); - findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); - findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); - - rmed = powf(rmed, rexp); - gmed = powf(gmed, gexp); - bmed = powf(bmed, bexp); - - const float MAX_OUT_VALUE = 65000.f; - const float rmult = (MAX_OUT_VALUE / (rmed * 24)) ; - const float gmult = (MAX_OUT_VALUE / (gmed * 24)) ; - const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ; - - if (settings->verbose) { - printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); - printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); - } - -#ifdef __SSE2__ - const vfloat clipv = F2V(MAXVALF); - const vfloat rexpv = F2V(rexp); - const vfloat gexpv = F2V(gexp); - const vfloat bexpv = F2V(bexp); - const vfloat rmultv = F2V(rmult); - const vfloat gmultv = F2V(gmult); - const vfloat bmultv = F2V(bmult); -#endif - - for (int i = 0; i < rheight; i++) { - float *rline = baseImg->r(i); - float *gline = baseImg->g(i); - float *bline = baseImg->b(i); - int j = 0; -#ifdef __SSE2__ - for (; j < rwidth - 3; j +=4) { - STVFU(rline[j], vminf(rmultv * pow_F(LVFU(rline[j]), rexpv), clipv)); - STVFU(gline[j], vminf(gmultv * pow_F(LVFU(gline[j]), gexpv), clipv)); - STVFU(bline[j], vminf(bmultv * pow_F(LVFU(bline[j]), bexpv), clipv)); - } -#endif - for (; j < rwidth; ++j) { - rline[j] = CLIP(rmult * pow_F(rline[j], rexp)); - gline[j] = CLIP(gmult * pow_F(gline[j], gexp)); - bline[j] = CLIP(bmult * pow_F(bline[j], bexp)); - } - } + processFilmNegative(params, baseImg, rwidth, rheight, rmi, gmi, bmi); } if (params.coarse.rotate) { diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index df33b892d..09a0510eb 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -68,6 +68,8 @@ class Thumbnail bool gammaCorrected; double colorMatrix[3][3]; + void processFilmNegative(const procparams::ProcParams& params, const Imagefloat* baseImg, int rwidth, int rheight, float &rmi, float &gmi, float &bmi); + public: bool isRaw; From b4c109f275beaf33d624c9ac7a4ea42cb480d41b Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Sat, 29 Jun 2019 16:06:40 +0200 Subject: [PATCH 040/222] ProcParams now contain red and blue ratios, to be aligned with values in the GUI. --- rtdata/languages/Catala | 6 +-- rtdata/languages/Chinese (Simplified) | 6 +-- rtdata/languages/Deutsch | 6 +-- rtdata/languages/English (UK) | 6 +-- rtdata/languages/English (US) | 6 +-- rtdata/languages/Italiano | 6 +-- rtdata/languages/Magyar | 6 +-- rtdata/languages/Nederlands | 6 +-- rtdata/languages/Polish | 6 +-- rtdata/languages/Portugues (Brasil) | 6 +-- rtdata/languages/Russian | 6 +-- rtdata/languages/Serbian (Cyrilic Characters) | 6 +-- rtdata/languages/Swedish | 6 +-- rtdata/languages/default | 2 +- rtengine/filmnegativeproc.cc | 8 ++-- rtengine/filmnegativethumb.cc | 12 +----- rtengine/procparams.cc | 16 ++++---- rtengine/procparams.h | 4 +- rtgui/filmnegative.cc | 38 +++++++++---------- rtgui/paramsedited.cc | 18 ++++----- rtgui/paramsedited.h | 4 +- rtgui/partialpastedlg.cc | 4 +- 22 files changed, 88 insertions(+), 96 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index f9bcf25b2..a6b104be2 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1315,7 +1315,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1853,12 +1853,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index 78807ddd4..9f0e4b365 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1362,7 +1362,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1800,12 +1800,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index fd2d0d07a..e3aa6ea44 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -2365,11 +2365,11 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - !!!!!!!!!!!!!!!!!!!!!!!!! !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed -!TP_FILMNEGATIVE_BLUE;Blue exponent +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 24bffbb0a..677dc1818 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -839,7 +839,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1667,12 +1667,12 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !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_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 5dad9591a..7d2c5ff43 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -749,7 +749,7 @@ !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1638,12 +1638,12 @@ !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_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 98d86b69d..2390c0d81 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -1540,7 +1540,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1905,12 +1905,12 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 7aa5b30c3..c3272133a 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1249,7 +1249,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1818,12 +1818,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 508f06384..179ba9b3f 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -2037,7 +2037,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -2232,12 +2232,12 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colors !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_CUSTOM;Custom diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index e35f583ff..daca63dd6 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1622,7 +1622,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1931,12 +1931,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. !TP_EXPOSURE_TCMODE_LUMINANCE;Luminance !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index 0bafe632f..0a9f4fe89 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -2259,7 +2259,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset !HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !MAIN_FRAME_PLACES_DEL;Remove !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. @@ -2273,12 +2273,12 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_COLORTONING_LABREGION_OFFSET;Offset !TP_COLORTONING_LABREGION_POWER;Power !TP_CROP_PPI;PPI -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 9e43f1098..dd4c501d7 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -1707,7 +1707,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type @@ -1976,12 +1976,12 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_DISTORTION_AUTO_TIP;Automatically corrects lens distortion in raw files by matching it against the embedded JPEG image if one exists and has had its lens disortion auto-corrected by the camera. !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FLATFIELD_CLIPCONTROL;Clip control diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index ce1452821..966213d1d 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1515,7 +1515,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1904,12 +1904,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index cd3b9b3fc..4fb3e301b 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -1864,7 +1864,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -2119,12 +2119,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colors !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. -!TP_FILMNEGATIVE_BLUE;Blue exponent +!TP_FILMNEGATIVE_BLUE;Blue ratio !TP_FILMNEGATIVE_GREEN;Green exponent !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_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red exponent +!TP_FILMNEGATIVE_RED;Red ratio !TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. diff --git a/rtdata/languages/default b/rtdata/languages/default index 63c877bbf..d5e3b13fa 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -748,7 +748,7 @@ HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -HISTORY_MSG_FILMNEGATIVE_EXPONENTS;Film negative exponents changed +HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values HISTORY_MSG_HISTMATCHING;Auto-matched tone curve HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index db5705a3c..58d87d103 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -101,9 +101,9 @@ bool channelsAvg( bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) { newExps = { - static_cast(currentParams.redExp), + static_cast(currentParams.redRatio * currentParams.greenExp), static_cast(currentParams.greenExp), - static_cast(currentParams.blueExp) + static_cast(currentParams.blueRatio * currentParams.greenExp) }; constexpr int spotSize = 32; // TODO: Make this configurable? @@ -171,9 +171,9 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ // Exponents are expressed as positive in the parameters, so negate them in order // to get the reciprocals. const std::array exps = { - static_cast(-params.redExp), + static_cast(-params.redRatio * params.greenExp), static_cast(-params.greenExp), - static_cast(-params.blueExp) + static_cast(-params.blueRatio * params.greenExp) }; MyTime t1, t2, t3,t4, t5; diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc index 8889915e6..610781872 100644 --- a/rtengine/filmnegativethumb.cc +++ b/rtengine/filmnegativethumb.cc @@ -17,18 +17,10 @@ * along with RawTherapee. If not, see . */ #include -#include - -#ifdef _OPENMP -#include -#endif #include "rtengine.h" #include "rtthumbnail.h" - -#include "mytime.h" #include "opthelper.h" -#include "procparams.h" #include "rt_algo.h" #include "rtengine.h" #include "settings.h" @@ -52,9 +44,9 @@ void rtengine::Thumbnail::processFilmNegative( StopWatch stop1("Thumbnail film negative", true); // Channel exponents - const float rexp = -params.filmNegative.redExp; + const float rexp = -params.filmNegative.redRatio * params.filmNegative.greenExp; const float gexp = -params.filmNegative.greenExp; - const float bexp = -params.filmNegative.blueExp; + const float bexp = -params.filmNegative.blueRatio * params.filmNegative.greenExp; // Need to calculate channel averages, to fake the same conditions // found in rawimagesource, where get_ColorsCoeff is called with diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index b35faca94..45c71b03a 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2736,9 +2736,9 @@ bool MetaDataParams::operator!=(const MetaDataParams &other) const FilmNegativeParams::FilmNegativeParams() : enabled(false), - redExp(2.04), + redRatio(1.36), greenExp(1.5), - blueExp(1.29) + blueRatio(0.86) { } @@ -2746,9 +2746,9 @@ bool FilmNegativeParams::operator ==(const FilmNegativeParams& other) const { return enabled == other.enabled - && redExp == other.redExp + && redRatio == other.redRatio && greenExp == other.greenExp - && blueExp == other.blueExp; + && blueRatio == other.blueRatio; } bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const @@ -3589,9 +3589,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Film negative saveToKeyfile(!pedited || pedited->filmNegative.enabled, "Film Negative", "Enabled", filmNegative.enabled, keyFile); - saveToKeyfile(!pedited || pedited->filmNegative.redExp, "Film Negative", "RedExponent", filmNegative.redExp, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.redRatio, "Film Negative", "RedRatio", filmNegative.redRatio, keyFile); saveToKeyfile(!pedited || pedited->filmNegative.greenExp, "Film Negative", "GreenExponent", filmNegative.greenExp, keyFile); - saveToKeyfile(!pedited || pedited->filmNegative.blueExp, "Film Negative", "BlueExponent", filmNegative.blueExp, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.blueRatio, "Film Negative", "BlueRatio", filmNegative.blueRatio, keyFile); // EXIF change list if (!pedited || pedited->exif) { @@ -5138,9 +5138,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("Film Negative")) { assignFromKeyfile(keyFile, "Film Negative", "Enabled", pedited, filmNegative.enabled, pedited->filmNegative.enabled); - assignFromKeyfile(keyFile, "Film Negative", "RedExponent", pedited, filmNegative.redExp, pedited->filmNegative.redExp); + assignFromKeyfile(keyFile, "Film Negative", "RedRatio", pedited, filmNegative.redRatio, pedited->filmNegative.redRatio); assignFromKeyfile(keyFile, "Film Negative", "GreenExponent", pedited, filmNegative.greenExp, pedited->filmNegative.greenExp); - assignFromKeyfile(keyFile, "Film Negative", "BlueExponent", pedited, filmNegative.blueExp, pedited->filmNegative.blueExp); + assignFromKeyfile(keyFile, "Film Negative", "BlueRatio", pedited, filmNegative.blueRatio, pedited->filmNegative.blueRatio); } if (keyFile.has_group("MetaData")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2af018035..46eb530bc 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1501,9 +1501,9 @@ struct RAWParams { */ struct FilmNegativeParams { bool enabled; - double redExp; + double redRatio; double greenExp; - double blueExp; + double blueRatio; FilmNegativeParams(); diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 4956968e3..598c9463a 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -49,7 +49,7 @@ Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring FilmNegative::FilmNegative() : FoldableToolPanel(this, "filmnegative", M("TP_FILMNEGATIVE_LABEL"), false, true), EditSubscriber(ET_OBJECTS), - evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS")), + evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_VALUES")), evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), fnp(nullptr), greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 1.5)), // master exponent (green channel) @@ -123,45 +123,45 @@ void FilmNegative::read(const rtengine::procparams::ProcParams* pp, const Params disableListener(); if (pedited) { - redRatio->setEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); + redRatio->setEditedState(pedited->filmNegative.redRatio ? Edited : UnEdited); greenExp->setEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); - blueRatio->setEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); + blueRatio->setEditedState(pedited->filmNegative.blueRatio ? Edited : UnEdited); set_inconsistent(multiImage && !pedited->filmNegative.enabled); } setEnabled(pp->filmNegative.enabled); - redRatio->setValue(pp->filmNegative.redExp / pp->filmNegative.greenExp); + redRatio->setValue(pp->filmNegative.redRatio); greenExp->setValue(pp->filmNegative.greenExp); - blueRatio->setValue(pp->filmNegative.blueExp / pp->filmNegative.greenExp); + blueRatio->setValue(pp->filmNegative.blueRatio); enableListener(); } void FilmNegative::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) { - pp->filmNegative.redExp = greenExp->getValue() * redRatio->getValue(); + pp->filmNegative.redRatio = redRatio->getValue(); pp->filmNegative.greenExp = greenExp->getValue(); - pp->filmNegative.blueExp = greenExp->getValue() * blueRatio->getValue(); + pp->filmNegative.blueRatio = blueRatio->getValue(); pp->filmNegative.enabled = getEnabled(); if (pedited) { - pedited->filmNegative.redExp = greenExp->getEditedState() || redRatio->getEditedState(); + pedited->filmNegative.redRatio = redRatio->getEditedState(); pedited->filmNegative.greenExp = greenExp->getEditedState(); - pedited->filmNegative.blueExp = greenExp->getEditedState() || blueRatio->getEditedState(); + pedited->filmNegative.blueRatio = blueRatio->getEditedState(); pedited->filmNegative.enabled = !get_inconsistent(); } } void FilmNegative::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) { - redRatio->setValue(defParams->filmNegative.redExp / defParams->filmNegative.greenExp); + redRatio->setValue(defParams->filmNegative.redRatio); greenExp->setValue(defParams->filmNegative.greenExp); - blueRatio->setValue(defParams->filmNegative.blueExp / defParams->filmNegative.greenExp); + blueRatio->setValue(defParams->filmNegative.blueRatio); if (pedited) { - redRatio->setDefaultEditedState(pedited->filmNegative.redExp ? Edited : UnEdited); + redRatio->setDefaultEditedState(pedited->filmNegative.redRatio ? Edited : UnEdited); greenExp->setDefaultEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); - blueRatio->setDefaultEditedState(pedited->filmNegative.blueExp ? Edited : UnEdited); + blueRatio->setDefaultEditedState(pedited->filmNegative.blueRatio ? Edited : UnEdited); } else { redRatio->setDefaultEditedState(Irrelevant); greenExp->setDefaultEditedState(Irrelevant); @@ -189,10 +189,10 @@ void FilmNegative::adjusterChanged(Adjuster* a, double newval) listener->panelChanged( evFilmNegativeExponents, Glib::ustring::compose( - "R=%1 ; G=%2 ; B=%3", - greenExp->getValue() * redRatio->getValue(), + "Ref=%1 ; R=%2 ; B=%3", greenExp->getValue(), - greenExp->getValue() * blueRatio->getValue() + redRatio->getValue(), + blueRatio->getValue() ) ); } @@ -269,10 +269,10 @@ bool FilmNegative::button1Pressed(int modifierKey) listener->panelChanged( evFilmNegativeExponents, Glib::ustring::compose( - "R=%1 ; G=%2 ; B=%3", - greenExp->getValue() * redRatio->getValue(), + "Ref=%1 ; R=%2 ; B=%3", greenExp->getValue(), - greenExp->getValue() * blueRatio->getValue() + redRatio->getValue(), + blueRatio->getValue() ) ); } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 7d52d309a..952b08161 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -581,9 +581,9 @@ void ParamsEdited::set(bool v) dehaze.depth = v; metadata.mode = v; filmNegative.enabled = v; - filmNegative.redExp = v; + filmNegative.redRatio = v; filmNegative.greenExp = v; - filmNegative.blueExp = v; + filmNegative.blueRatio = v; exif = v; iptc = v; @@ -1147,9 +1147,9 @@ void ParamsEdited::initFrom(const std::vector& dehaze.depth = dehaze.depth && p.dehaze.depth == other.dehaze.depth; metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode; filmNegative.enabled = filmNegative.enabled && p.filmNegative.enabled == other.filmNegative.enabled; - filmNegative.redExp = filmNegative.redExp && p.filmNegative.redExp == other.filmNegative.redExp; + filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; filmNegative.greenExp = filmNegative.greenExp && p.filmNegative.greenExp == other.filmNegative.greenExp; - filmNegative.blueExp = filmNegative.blueExp && p.filmNegative.blueExp == other.filmNegative.blueExp; + filmNegative.blueRatio = filmNegative.blueRatio && p.filmNegative.blueRatio == other.filmNegative.blueRatio; // How the hell can we handle that??? // exif = exif && p.exif==other.exif @@ -3187,16 +3187,16 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.filmNegative.enabled = mods.filmNegative.enabled; } - if (filmNegative.redExp) { - toEdit.filmNegative.redExp = mods.filmNegative.redExp; + if (filmNegative.redRatio) { + toEdit.filmNegative.redRatio = mods.filmNegative.redRatio; } if (filmNegative.greenExp) { toEdit.filmNegative.greenExp = mods.filmNegative.greenExp; } - if (filmNegative.blueExp) { - toEdit.filmNegative.blueExp = mods.filmNegative.blueExp; + if (filmNegative.blueRatio) { + toEdit.filmNegative.blueRatio = mods.filmNegative.blueRatio; } // Exif changes are added to the existing ones @@ -3245,5 +3245,5 @@ bool RetinexParamsEdited::isUnchanged() const bool FilmNegativeParamsEdited::isUnchanged() const { - return enabled && redExp && greenExp && blueExp; + return enabled && redRatio && greenExp && blueRatio; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 57e6f2cdd..08a41fc7a 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -668,9 +668,9 @@ struct MetaDataParamsEdited { struct FilmNegativeParamsEdited { bool enabled; - bool redExp; + bool redRatio; bool greenExp; - bool blueExp; + bool blueRatio; bool isUnchanged() const; }; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 34f9a414d..52adcfbf7 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -976,9 +976,9 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param if (!filmNegative->get_active ()) { filterPE.filmNegative.enabled = falsePE.filmNegative.enabled; - filterPE.filmNegative.redExp = falsePE.filmNegative.redExp; + filterPE.filmNegative.redRatio = falsePE.filmNegative.redRatio; filterPE.filmNegative.greenExp = falsePE.filmNegative.greenExp; - filterPE.filmNegative.blueExp = falsePE.filmNegative.blueExp; + filterPE.filmNegative.blueRatio = falsePE.filmNegative.blueRatio; } if (dstPE) { From 4d6c3f2ce2438fcd9ecc7337f2329b493d2a050f Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 7 Jul 2019 15:29:24 +0200 Subject: [PATCH 041/222] Speedup for color propagation --- rtengine/hilite_recon.cc | 137 ++++++++++++++++++++++++-------------- rtengine/rawimagesource.h | 2 - 2 files changed, 86 insertions(+), 53 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 699d42071..38da3ea26 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -28,14 +28,11 @@ #include "rawimagesource.h" #include "rt_math.h" #include "opthelper.h" -namespace rtengine -{ +#define BENCHMARK +#include "StopWatch.h" -extern const Settings* settings; - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::boxblur2(float** src, float** dst, float** temp, int H, int W, int box ) +namespace { +void boxblur2(float** src, float** dst, float** temp, int startY, int startX, int H, int W, int box ) { //box blur image channel; box size = 2*box+1 //horizontal blur @@ -45,23 +42,23 @@ void RawImageSource::boxblur2(float** src, float** dst, float** temp, int H, int for (int row = 0; row < H; row++) { int len = box + 1; - temp[row][0] = src[row][0] / len; + temp[row][0] = src[row + startY][startX] / len; for (int j = 1; j <= box; j++) { - temp[row][0] += src[row][j] / len; + temp[row][0] += src[row + startY][j + startX] / len; } for (int col = 1; col <= box; col++) { - temp[row][col] = (temp[row][col - 1] * len + src[row][col + box]) / (len + 1); + temp[row][col] = (temp[row][col - 1] * len + src[row + startY][col + box + startX]) / (len + 1); len ++; } for (int col = box + 1; col < W - box; col++) { - temp[row][col] = temp[row][col - 1] + (src[row][col + box] - src[row][col - box - 1]) / len; + temp[row][col] = temp[row][col - 1] + (src[row + startY][col + box + startX] - src[row + startY][col - box - 1 + startX]) / len; } for (int col = W - box; col < W; col++) { - temp[row][col] = (temp[row][col - 1] * len - src[row][col - box - 1]) / (len - 1); + temp[row][col] = (temp[row][col - 1] * len - src[row + startY][col - box - 1 + startX]) / (len - 1); len --; } } @@ -210,7 +207,7 @@ void RawImageSource::boxblur2(float** src, float** dst, float** temp, int H, int } -void RawImageSource::boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int box, int samp ) +void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int box, int samp ) { #ifdef _OPENMP @@ -386,8 +383,16 @@ void RawImageSource::boxblur_resamp(float **src, float **dst, float ** temp, int } +} +namespace rtengine +{ + +extern const Settings* settings; + + void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** blue) { + BENCHFUN double progress = 0.0; if (plistener) { @@ -477,28 +482,58 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b for (int c = 0; c < ColorCount; c++) { medFactor[c] = max(1.0f, max_f[c] / medpt) / (-blendpt); } + int minx = width - 1; + int maxx = 0; + int miny = height - 1; + int maxy = 0; - multi_array2D channelblur(width, height, 0, 48); - array2D temp(width, height); // allocate temporary buffer + #pragma omp parallel for reduction(min:minx,miny) reduction(max:maxx,maxy) schedule(dynamic, 16) + for (int i = 0; i < height; ++i) { + for (int j = 0; j< width; ++j) { + if(red[i][j] >= max_f[0] || green[i][j] >= max_f[1] || blue[i][j] >= max_f[2]) { + minx = std::min(minx, j); + maxx = std::max(maxx, j); + miny = std::min(miny, i); + maxy = std::max(maxy, i); + } + } + } + + std::cout << "minx : " << minx << std::endl; + std::cout << "maxx : " << maxx << std::endl; + std::cout << "miny : " << miny << std::endl; + std::cout << "maxy : " << maxy << std::endl; + + constexpr int blurBorder = 256; + minx = std::max(0, minx - blurBorder); + miny = std::max(0, miny - blurBorder); + maxx = std::min(width - 1, maxx + blurBorder); + maxy = std::min(height - 1, maxy + blurBorder); + const int blurWidth = maxx - minx + 1; + const int blurHeight = maxy - miny + 1; + + std::cout << "Corrected area reduced by factor: " << (((float)width * height) / (blurWidth * blurHeight)) << std::endl; + multi_array2D channelblur(blurWidth, blurHeight, 0, 48); + array2D temp(blurWidth, blurHeight); // allocate temporary buffer // blur RGB channels - boxblur2(red, channelblur[0], temp, height, width, 4); + boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, blurWidth, 4); if(plistener) { progress += 0.05; plistener->setProgress(progress); } - boxblur2(green, channelblur[1], temp, height, width, 4); + boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, blurWidth, 4); if(plistener) { progress += 0.05; plistener->setProgress(progress); } - boxblur2(blue, channelblur[2], temp, height, width, 4); - + boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, blurWidth, 4); + if(plistener) { progress += 0.05; plistener->setProgress(progress); @@ -509,9 +544,9 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b #pragma omp parallel for #endif - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { - channelblur[0][i][j] = fabsf(channelblur[0][i][j] - red[i][j]) + fabsf(channelblur[1][i][j] - green[i][j]) + fabsf(channelblur[2][i][j] - blue[i][j]); + for(int i = 0; i < blurHeight; i++) + for(int j = 0; j < blurWidth; j++) { + channelblur[0][i][j] = fabsf(channelblur[0][i][j] - red[i + miny][j + minx]) + fabsf(channelblur[1][i][j] - green[i + miny][j + minx]) + fabsf(channelblur[2][i][j] - blue[i + miny][j + minx]); } for (int c = 1; c < 3; c++) { @@ -523,7 +558,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b plistener->setProgress(progress); } - multi_array2D hilite_full(width, height, ARRAY2D_CLEAR_DATA, 32); + multi_array2D hilite_full(blurWidth, blurHeight, ARRAY2D_CLEAR_DATA, 32); if(plistener) { progress += 0.10; @@ -538,18 +573,18 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b #pragma omp parallel for reduction(+:hipass_sum,hipass_norm) schedule(dynamic,16) #endif - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { + for (int i = 0; i < blurHeight; i++) { + for (int j = 0; j < blurWidth; j++) { //if one or more channels is highlight but none are blown, add to highlight accumulator - if ((red[i][j] > thresh[0] || green[i][j] > thresh[1] || blue[i][j] > thresh[2]) && - (red[i][j] < max_f[0] && green[i][j] < max_f[1] && blue[i][j] < max_f[2])) { + if ((red[i + miny][j + minx] > thresh[0] || green[i + miny][j + minx] > thresh[1] || blue[i + miny][j + minx] > thresh[2]) && + (red[i + miny][j + minx] < max_f[0] && green[i + miny][j + minx] < max_f[1] && blue[i + miny][j + minx] < max_f[2])) { hipass_sum += channelblur[0][i][j]; hipass_norm ++; - hilite_full[0][i][j] = red[i][j]; - hilite_full[1][i][j] = green[i][j]; - hilite_full[2][i][j] = blue[i][j]; + hilite_full[0][i][j] = red[i + miny][j + minx]; + hilite_full[1][i][j] = green[i + miny][j + minx]; + hilite_full[2][i][j] = blue[i + miny][j + minx]; hilite_full[3][i][j] = 1.f; } @@ -563,10 +598,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b plistener->setProgress(progress); } - array2D hilite_full4(width, height); + array2D hilite_full4(blurWidth, blurHeight); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //blur highlight data - boxblur2(hilite_full[3], hilite_full4, temp, height, width, 1); + boxblur2(hilite_full[3], hilite_full4, temp, 0, 0, blurHeight, blurWidth, 1); temp.free(); // free temporary buffer @@ -579,8 +614,8 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b #pragma omp parallel for schedule(dynamic,16) #endif - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { + for (int i = 0; i < blurHeight; i++) { + for (int j = 0; j < blurWidth; j++) { if (channelblur[0][i][j] > hipass_ave) { //too much variation hilite_full[0][i][j] = hilite_full[1][i][j] = hilite_full[2][i][j] = hilite_full[3][i][j] = 0.f; @@ -597,18 +632,18 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b channelblur[0].free(); //free up some memory hilite_full4.free(); //free up some memory - int hfh = (height - (height % pitch)) / pitch; - int hfw = (width - (width % pitch)) / pitch; + int hfh = (blurHeight - (blurHeight % pitch)) / pitch; + int hfw = (blurWidth - (blurWidth % pitch)) / pitch; multi_array2D hilite(hfw + 1, hfh + 1, ARRAY2D_CLEAR_DATA, 48); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // blur and resample highlight data; range=size of blur, pitch=sample spacing - array2D temp2((width / pitch) + ((width % pitch) == 0 ? 0 : 1), height); + array2D temp2((blurWidth / pitch) + ((blurWidth % pitch) == 0 ? 0 : 1), blurHeight); for (int m = 0; m < 4; m++) { - boxblur_resamp(hilite_full[m], hilite[m], temp2, height, width, range, pitch); + boxblur_resamp(hilite_full[m], hilite[m], temp2, blurHeight, blurWidth, range, pitch); if(plistener) { progress += 0.05; @@ -953,12 +988,12 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b #pragma omp parallel for schedule(dynamic,16) #endif - for (int i = 0; i < height; i++) { + for (int i = 0; i < blurHeight; i++) { int i1 = min((i - (i % pitch)) / pitch, hfh - 1); - for (int j = 0; j < width; j++) { + for (int j = 0; j < blurWidth; j++) { - float pixel[3] = {red[i][j], green[i][j], blue[i][j]}; + float pixel[3] = {red[i + miny][j + minx], green[i + miny][j + minx], blue[i + miny][j + minx]}; if (pixel[0] < max_f[0] && pixel[1] < max_f[1] && pixel[2] < max_f[2]) { continue; //pixel not clipped @@ -1109,36 +1144,36 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b float Y = (0.299 * clipfix[0] + 0.587 * clipfix[1] + 0.114 * clipfix[2]); float factor = whitept / Y; - red[i][j] = clipfix[0] * factor; - green[i][j] = clipfix[1] * factor; - blue[i][j] = clipfix[2] * factor; + red[i + miny][j + minx] = clipfix[0] * factor; + green[i + miny][j + minx] = clipfix[1] * factor; + blue[i + miny][j + minx] = clipfix[2] * factor; } else {//some channels clipped float notclipped[3] = {pixel[0] <= max_f[0] ? 1.f : 0.f, pixel[1] <= max_f[1] ? 1.f : 0.f, pixel[2] <= max_f[2] ? 1.f : 0.f}; if (notclipped[0] == 0.f) { //red clipped - red[i][j] = max(red[i][j], (clipfix[0] * ((notclipped[1] * pixel[1] + notclipped[2] * pixel[2]) / + red[i + miny][j + minx] = max(red[i + miny][j + minx], (clipfix[0] * ((notclipped[1] * pixel[1] + notclipped[2] * pixel[2]) / (notclipped[1] * clipfix[1] + notclipped[2] * clipfix[2] + epsilon)))); } if (notclipped[1] == 0.f) { //green clipped - green[i][j] = max(green[i][j], (clipfix[1] * ((notclipped[2] * pixel[2] + notclipped[0] * pixel[0]) / + green[i + miny][j + minx] = max(green[i + miny][j + minx], (clipfix[1] * ((notclipped[2] * pixel[2] + notclipped[0] * pixel[0]) / (notclipped[2] * clipfix[2] + notclipped[0] * clipfix[0] + epsilon)))); } if (notclipped[2] == 0.f) { //blue clipped - blue[i][j] = max(blue[i][j], (clipfix[2] * ((notclipped[0] * pixel[0] + notclipped[1] * pixel[1]) / + blue[i + miny][j + minx] = max(blue[i + miny][j + minx], (clipfix[2] * ((notclipped[0] * pixel[0] + notclipped[1] * pixel[1]) / (notclipped[0] * clipfix[0] + notclipped[1] * clipfix[1] + epsilon)))); } } - Y = (0.299 * red[i][j] + 0.587 * green[i][j] + 0.114 * blue[i][j]); + Y = (0.299 * red[i + miny][j + minx] + 0.587 * green[i + miny][j + minx] + 0.114 * blue[i + miny][j + minx]); if (Y > whitept) { float factor = whitept / Y; - red[i][j] *= factor; - green[i][j] *= factor; - blue[i][j] *= factor; + red[i + miny][j + minx] *= factor; + green[i + miny][j + minx] *= factor; + blue[i + miny][j + minx] *= factor; } } } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 4c7b0ba21..64018f354 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -195,8 +195,6 @@ public: } static void inverse33 (const double (*coeff)[3], double (*icoeff)[3]); - void boxblur2(float** src, float** dst, float** temp, int H, int W, int box ); - void boxblur_resamp(float **src, float **dst, float** temp, int H, int W, int box, int samp ); void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, const RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); void HLRecovery_inpaint (float** red, float** green, float** blue) override; static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval); From 54fdbe41ea361467ff90104e7183fc38aad42efb Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 8 Jul 2019 23:57:24 +0200 Subject: [PATCH 042/222] dump SSE code in boxblur2 because new code is faster with auto-vectorization, also pad bufferwidth for boxblur2 to a multiple of 16 --- rtengine/hilite_recon.cc | 189 +++++++++++---------------------------- 1 file changed, 52 insertions(+), 137 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 38da3ea26..b7c4d349c 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -22,6 +22,10 @@ // //////////////////////////////////////////////////////////////// +#ifndef NDEBUG +#include +#endif + #include #include #include "array2D.h" @@ -32,8 +36,11 @@ #include "StopWatch.h" namespace { -void boxblur2(float** src, float** dst, float** temp, int startY, int startX, int H, int W, int box ) +void boxblur2(const float* const* src, float** dst, float** temp, int startY, int startX, int H, int W, int box) { + constexpr int numCols = 16; + assert((W % numCols) == 0); + //box blur image channel; box size = 2*box+1 //horizontal blur #ifdef _OPENMP @@ -63,148 +70,52 @@ void boxblur2(float** src, float** dst, float** temp, int startY, int startX, in } } -#ifdef __SSE2__ //vertical blur #ifdef _OPENMP #pragma omp parallel #endif { - float len = box + 1; - vfloat lenv = F2V( len ); - vfloat lenp1v = F2V( len + 1.0f ); - vfloat onev = F2V( 1.0f ); - vfloat tempv, temp2v; + float tempvalN[numCols] ALIGNED64; #ifdef _OPENMP - #pragma omp for nowait + #pragma omp for #endif - - for (int col = 0; col < W - 7; col += 8) { - tempv = LVFU(temp[0][col]) / lenv; - temp2v = LVFU(temp[0][col + 4]) / lenv; - + for (int col = 0; col < W - numCols + 1; col += numCols) { + float len = box + 1; + for(int n = 0; n < numCols; n++) { + tempvalN[n] = temp[0][col + n] / len; + } for (int i = 1; i <= box; i++) { - tempv = tempv + LVFU(temp[i][col]) / lenv; - temp2v = temp2v + LVFU(temp[i][col + 4]) / lenv; + for(int n = 0; n < numCols; n++) { + tempvalN[n] += temp[i][col + n] / len; + } + } + for(int n = 0; n < numCols; n++) { + dst[0][col + n] = tempvalN[n]; } - - _mm_storeu_ps( &dst[0][col], tempv); - _mm_storeu_ps( &dst[0][col + 4], temp2v); - for (int row = 1; row <= box; row++) { - tempv = (tempv * lenv + LVFU(temp[(row + box)][col])) / lenp1v; - temp2v = (temp2v * lenv + LVFU(temp[(row + box)][col + 4])) / lenp1v; - _mm_storeu_ps( &dst[row][col], tempv); - _mm_storeu_ps( &dst[row][col + 4], temp2v); - lenv = lenp1v; - lenp1v = lenp1v + onev; + for(int n = 0; n < numCols; n++) { + tempvalN[n] = (tempvalN[n] * len + temp[(row + box)][col + n]) / (len + 1); + dst[row][col + n] = tempvalN[n]; + } + len ++; } - + const float rlen = 1.f / len; for (int row = box + 1; row < H - box; row++) { - tempv = tempv + (LVFU(temp[(row + box)][col]) - LVFU(temp[(row - box - 1)][col])) / lenv; - temp2v = temp2v + (LVFU(temp[(row + box)][col + 4]) - LVFU(temp[(row - box - 1)][col + 4])) / lenv; - _mm_storeu_ps( &dst[row][col], tempv); - _mm_storeu_ps( &dst[row][col + 4], temp2v); + for(int n = 0; n < numCols; n++) { + tempvalN[n] = tempvalN[n] + (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; + dst[row][col + n] = tempvalN[n]; + } } for (int row = H - box; row < H; row++) { - lenp1v = lenv; - lenv = lenv - onev; - tempv = (tempv * lenp1v - LVFU(temp[(row - box - 1)][col])) / lenv; - temp2v = (temp2v * lenp1v - LVFU(temp[(row - box - 1)][col + 4])) / lenv; - _mm_storeu_ps( &dst[row][col], tempv ); - _mm_storeu_ps( &dst[row][col + 4], temp2v ); - } - } - -#ifdef _OPENMP - #pragma omp single -#endif - { - for (int col = W - (W % 8); col < W - 3; col += 4) { - tempv = LVFU(temp[0][col]) / lenv; - - for (int i = 1; i <= box; i++) { - tempv = tempv + LVFU(temp[i][col]) / lenv; - } - - _mm_storeu_ps( &dst[0][col], tempv); - - for (int row = 1; row <= box; row++) { - tempv = (tempv * lenv + LVFU(temp[(row + box)][col])) / lenp1v; - _mm_storeu_ps( &dst[row][col], tempv); - lenv = lenp1v; - lenp1v = lenp1v + onev; - } - - for (int row = box + 1; row < H - box; row++) { - tempv = tempv + (LVFU(temp[(row + box)][col]) - LVFU(temp[(row - box - 1)][col])) / lenv; - _mm_storeu_ps( &dst[row][col], tempv); - } - - for (int row = H - box; row < H; row++) { - lenp1v = lenv; - lenv = lenv - onev; - tempv = (tempv * lenp1v - LVFU(temp[(row - box - 1)][col])) / lenv; - _mm_storeu_ps( &dst[row][col], tempv ); - } - } - - for (int col = W - (W % 4); col < W; col++) { - int len = box + 1; - dst[0][col] = temp[0][col] / len; - - for (int i = 1; i <= box; i++) { - dst[0][col] += temp[i][col] / len; - } - - for (int row = 1; row <= box; row++) { - dst[row][col] = (dst[(row - 1)][col] * len + temp[(row + box)][col]) / (len + 1); - len ++; - } - - for (int row = box + 1; row < H - box; row++) { - dst[row][col] = dst[(row - 1)][col] + (temp[(row + box)][col] - temp[(row - box - 1)][col]) / len; - } - - for (int row = H - box; row < H; row++) { - dst[row][col] = (dst[(row - 1)][col] * len - temp[(row - box - 1)][col]) / (len - 1); - len --; + for(int n = 0; n < numCols; n++) { + tempvalN[n] = (dst[(row - 1)][col + n] * len - temp[(row - box - 1)][col + n]) / (len - 1); + dst[row][col + n] = tempvalN[n]; } + len --; } } } - -#else - //vertical blur -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int col = 0; col < W; col++) { - int len = box + 1; - dst[0][col] = temp[0][col] / len; - - for (int i = 1; i <= box; i++) { - dst[0][col] += temp[i][col] / len; - } - - for (int row = 1; row <= box; row++) { - dst[row][col] = (dst[(row - 1)][col] * len + temp[(row + box)][col]) / (len + 1); - len ++; - } - - for (int row = box + 1; row < H - box; row++) { - dst[row][col] = dst[(row - 1)][col] + (temp[(row + box)][col] - temp[(row - box - 1)][col]) / len; - } - - for (int row = H - box; row < H; row++) { - dst[row][col] = (dst[(row - 1)][col] * len - temp[(row - box - 1)][col]) / (len - 1); - len --; - } - } - -#endif - } void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int box, int samp ) @@ -263,19 +174,19 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b } } - static const int numCols = 8; // process numCols columns at once for better L1 CPU cache usage + constexpr int numCols = 8; // process numCols columns at once for better L1 CPU cache usage #ifdef _OPENMP #pragma omp parallel #endif { - float tempvalN[numCols] ALIGNED16; + float tempvalN[numCols] ALIGNED64; #ifdef _OPENMP #pragma omp for nowait #endif //vertical blur for (int col = 0; col < (W / samp) - (numCols - 1); col += numCols) { - int len = box + 1; + float len = box + 1; for(int n = 0; n < numCols; n++) { tempvalN[n] = temp[0][col + n] / len; @@ -304,10 +215,10 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b len ++; } - + const float rlen = 1.f / len; for (int row = box + 1; row < H - box; row++) { for(int n = 0; n < numCols; n++) { - tempvalN[n] = tempvalN[n] + (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) / len; + tempvalN[n] = tempvalN[n] + (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; } if(row % samp == 0) { @@ -511,28 +422,32 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b maxy = std::min(height - 1, maxy + blurBorder); const int blurWidth = maxx - minx + 1; const int blurHeight = maxy - miny + 1; + const int bufferWidth = blurWidth + ((16 - (blurWidth % 16)) & 15); + + std::cout << "blurWidth : " << blurWidth << std::endl; + std::cout << "bufferWidth : " << bufferWidth << std::endl; std::cout << "Corrected area reduced by factor: " << (((float)width * height) / (blurWidth * blurHeight)) << std::endl; - multi_array2D channelblur(blurWidth, blurHeight, 0, 48); - array2D temp(blurWidth, blurHeight); // allocate temporary buffer + multi_array2D channelblur(bufferWidth, blurHeight, 0, 48); + array2D temp(bufferWidth, blurHeight); // allocate temporary buffer // blur RGB channels - boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, blurWidth, 4); + boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, bufferWidth, 4); if(plistener) { progress += 0.05; plistener->setProgress(progress); } - boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, blurWidth, 4); + boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, bufferWidth, 4); if(plistener) { progress += 0.05; plistener->setProgress(progress); } - boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, blurWidth, 4); + boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, bufferWidth, 4); if(plistener) { progress += 0.05; @@ -558,7 +473,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b plistener->setProgress(progress); } - multi_array2D hilite_full(blurWidth, blurHeight, ARRAY2D_CLEAR_DATA, 32); + multi_array2D hilite_full(bufferWidth, blurHeight, ARRAY2D_CLEAR_DATA, 32); if(plistener) { progress += 0.10; @@ -598,10 +513,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b plistener->setProgress(progress); } - array2D hilite_full4(blurWidth, blurHeight); + array2D hilite_full4(bufferWidth, blurHeight); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //blur highlight data - boxblur2(hilite_full[3], hilite_full4, temp, 0, 0, blurHeight, blurWidth, 1); + boxblur2(hilite_full[3], hilite_full4, temp, 0, 0, blurHeight, bufferWidth, 1); temp.free(); // free temporary buffer From 4f73e5bb3cb4cbdd5749a8b7614319b65567cee8 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 9 Jul 2019 00:20:04 +0200 Subject: [PATCH 043/222] Fix oob access in last commit --- rtengine/hilite_recon.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index b7c4d349c..e78bd7365 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -36,10 +36,10 @@ #include "StopWatch.h" namespace { -void boxblur2(const float* const* src, float** dst, float** temp, int startY, int startX, int H, int W, int box) +void boxblur2(const float* const* src, float** dst, float** temp, int startY, int startX, int H, int W, int bufferW, int box) { constexpr int numCols = 16; - assert((W % numCols) == 0); + assert((bufferW % numCols) == 0); //box blur image channel; box size = 2*box+1 //horizontal blur @@ -79,7 +79,7 @@ void boxblur2(const float* const* src, float** dst, float** temp, int startY, in #ifdef _OPENMP #pragma omp for #endif - for (int col = 0; col < W - numCols + 1; col += numCols) { + for (int col = 0; col < bufferW - numCols + 1; col += numCols) { float len = box + 1; for(int n = 0; n < numCols; n++) { tempvalN[n] = temp[0][col + n] / len; @@ -433,21 +433,21 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b // blur RGB channels - boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, bufferWidth, 4); + boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); if(plistener) { progress += 0.05; plistener->setProgress(progress); } - boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, bufferWidth, 4); + boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); if(plistener) { progress += 0.05; plistener->setProgress(progress); } - boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, bufferWidth, 4); + boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); if(plistener) { progress += 0.05; @@ -516,7 +516,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b array2D hilite_full4(bufferWidth, blurHeight); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //blur highlight data - boxblur2(hilite_full[3], hilite_full4, temp, 0, 0, blurHeight, bufferWidth, 1); + boxblur2(hilite_full[3], hilite_full4, temp, 0, 0, blurHeight, blurWidth, bufferWidth, 1); temp.free(); // free temporary buffer From fe43bf1bf2df00d51826093cd09269c03a7ece03 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 9 Jul 2019 00:40:25 +0200 Subject: [PATCH 044/222] color propagation: use up to 4 cores where previously only up to 3 cores were used --- rtengine/hilite_recon.cc | 313 +++++++++++++++++++++------------------ 1 file changed, 169 insertions(+), 144 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index e78bd7365..a726481dd 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -617,192 +617,217 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel +#endif + { +#ifdef _OPENMP + #pragma omp for nowait #endif - for (int c = 0; c < 3; c++) { - for (int j = 1; j < hfw - 1; j++) { - for (int i = 2; i < hfh - 2; i++) { - //from left - if (hilite[3][i][j] > epsilon) { - hilite_dir0[c][j][i] = hilite[c][i][j] / hilite[3][i][j]; - } else { - hilite_dir0[c][j][i] = 0.1f * ((hilite_dir0[0 + c][j - 1][i - 2] + hilite_dir0[0 + c][j - 1][i - 1] + hilite_dir0[0 + c][j - 1][i] + hilite_dir0[0 + c][j - 1][i + 1] + hilite_dir0[0 + c][j - 1][i + 2]) / - (hilite_dir0[0 + 3][j - 1][i - 2] + hilite_dir0[0 + 3][j - 1][i - 1] + hilite_dir0[0 + 3][j - 1][i] + hilite_dir0[0 + 3][j - 1][i + 1] + hilite_dir0[0 + 3][j - 1][i + 2] + epsilon)); + for (int c = 0; c < 3; c++) { + for (int j = 1; j < hfw - 1; j++) { + for (int i = 2; i < hfh - 2; i++) { + //from left + if (hilite[3][i][j] > epsilon) { + hilite_dir0[c][j][i] = hilite[c][i][j] / hilite[3][i][j]; + } else { + hilite_dir0[c][j][i] = 0.1f * ((hilite_dir0[0 + c][j - 1][i - 2] + hilite_dir0[0 + c][j - 1][i - 1] + hilite_dir0[0 + c][j - 1][i] + hilite_dir0[0 + c][j - 1][i + 1] + hilite_dir0[0 + c][j - 1][i + 2]) / + (hilite_dir0[0 + 3][j - 1][i - 2] + hilite_dir0[0 + 3][j - 1][i - 1] + hilite_dir0[0 + 3][j - 1][i] + hilite_dir0[0 + 3][j - 1][i + 1] + hilite_dir0[0 + 3][j - 1][i + 2] + epsilon)); + } + } + + if(hilite[3][2][j] <= epsilon) { + hilite_dir[0 + c][0][j] = hilite_dir0[c][j][2]; + } + + if(hilite[3][3][j] <= epsilon) { + hilite_dir[0 + c][1][j] = hilite_dir0[c][j][3]; + } + + if(hilite[3][hfh - 3][j] <= epsilon) { + hilite_dir[4 + c][hfh - 1][j] = hilite_dir0[c][j][hfh - 3]; + } + + if(hilite[3][hfh - 4][j] <= epsilon) { + hilite_dir[4 + c][hfh - 2][j] = hilite_dir0[c][j][hfh - 4]; } } - if(hilite[3][2][j] <= epsilon) { - hilite_dir[0 + c][0][j] = hilite_dir0[c][j][2]; - } - - if(hilite[3][3][j] <= epsilon) { - hilite_dir[0 + c][1][j] = hilite_dir0[c][j][3]; - } - - if(hilite[3][hfh - 3][j] <= epsilon) { - hilite_dir[4 + c][hfh - 1][j] = hilite_dir0[c][j][hfh - 3]; - } - - if(hilite[3][hfh - 4][j] <= epsilon) { - hilite_dir[4 + c][hfh - 2][j] = hilite_dir0[c][j][hfh - 4]; + for (int i = 2; i < hfh - 2; i++) { + if(hilite[3][i][hfw - 2] <= epsilon) { + hilite_dir4[c][hfw - 1][i] = hilite_dir0[c][hfw - 2][i]; + } } } - for (int i = 2; i < hfh - 2; i++) { - if(hilite[3][i][hfw - 2] <= epsilon) { - hilite_dir4[c][hfw - 1][i] = hilite_dir0[c][hfw - 2][i]; +#ifdef _OPENMP + #pragma omp single +#endif + { + for (int j = hfw - 2; j > 0; j--) { + for (int i = 2; i < hfh - 2; i++) { + //from right + if (hilite[3][i][j] > epsilon) { + hilite_dir4[3][j][i] = 1.f; + } else { + hilite_dir4[3][j][i] = (hilite_dir4[3][(j + 1)][(i - 2)] + hilite_dir4[3][(j + 1)][(i - 1)] + hilite_dir4[3][(j + 1)][(i)] + hilite_dir4[3][(j + 1)][(i + 1)] + hilite_dir4[3][(j + 1)][(i + 2)]) == 0.f ? 0.f : 0.1f; + } + } + + if(hilite[3][2][j] <= epsilon) { + hilite_dir[0 + 3][0][j] += hilite_dir4[3][j][2]; + } + + if(hilite[3][hfh - 3][j] <= epsilon) { + hilite_dir[4 + 3][hfh - 1][j] += hilite_dir4[3][j][hfh - 3]; + } + } + + for (int i = 2; i < hfh - 2; i++) { + if(hilite[3][i][0] <= epsilon) { + hilite_dir[0 + 3][i - 2][0] += hilite_dir4[3][0][i]; + hilite_dir[4 + 3][i + 2][0] += hilite_dir4[3][0][i]; + } + + if(hilite[3][i][1] <= epsilon) { + hilite_dir[0 + 3][i - 2][1] += hilite_dir4[3][1][i]; + hilite_dir[4 + 3][i + 2][1] += hilite_dir4[3][1][i]; + } + + if(hilite[3][i][hfw - 2] <= epsilon) { + hilite_dir[0 + 3][i - 2][hfw - 2] += hilite_dir4[3][hfw - 2][i]; + hilite_dir[4 + 3][i + 2][hfw - 2] += hilite_dir4[3][hfw - 2][i]; + } } } } - if(plistener) { progress += 0.05; plistener->setProgress(progress); } - for (int j = hfw - 2; j > 0; j--) { - for (int i = 2; i < hfh - 2; i++) { - //from right - if (hilite[3][i][j] > epsilon) { - hilite_dir4[3][j][i] = 1.f; - } else { - hilite_dir4[3][j][i] = (hilite_dir4[3][(j + 1)][(i - 2)] + hilite_dir4[3][(j + 1)][(i - 1)] + hilite_dir4[3][(j + 1)][(i)] + hilite_dir4[3][(j + 1)][(i + 1)] + hilite_dir4[3][(j + 1)][(i + 2)]) == 0.f ? 0.f : 0.1f; - } - } - - if(hilite[3][2][j] <= epsilon) { - hilite_dir[0 + 3][0][j] += hilite_dir4[3][j][2]; - } - - if(hilite[3][hfh - 3][j] <= epsilon) { - hilite_dir[4 + 3][hfh - 1][j] += hilite_dir4[3][j][hfh - 3]; - } - } - - for (int i = 2; i < hfh - 2; i++) { - if(hilite[3][i][0] <= epsilon) { - hilite_dir[0 + 3][i - 2][0] += hilite_dir4[3][0][i]; - hilite_dir[4 + 3][i + 2][0] += hilite_dir4[3][0][i]; - } - - if(hilite[3][i][1] <= epsilon) { - hilite_dir[0 + 3][i - 2][1] += hilite_dir4[3][1][i]; - hilite_dir[4 + 3][i + 2][1] += hilite_dir4[3][1][i]; - } - - if(hilite[3][i][hfw - 2] <= epsilon) { - hilite_dir[0 + 3][i - 2][hfw - 2] += hilite_dir4[3][hfw - 2][i]; - hilite_dir[4 + 3][i + 2][hfw - 2] += hilite_dir4[3][hfw - 2][i]; - } - } - #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel +#endif + { +#ifdef _OPENMP + #pragma omp for nowait #endif - for (int c = 0; c < 3; c++) { - for (int j = hfw - 2; j > 0; j--) { - for (int i = 2; i < hfh - 2; i++) { - //from right - if (hilite[3][i][j] > epsilon) { - hilite_dir4[c][j][i] = hilite[c][i][j] / hilite[3][i][j]; - } else { - hilite_dir4[c][j][i] = 0.1 * ((hilite_dir4[c][(j + 1)][(i - 2)] + hilite_dir4[c][(j + 1)][(i - 1)] + hilite_dir4[c][(j + 1)][(i)] + hilite_dir4[c][(j + 1)][(i + 1)] + hilite_dir4[c][(j + 1)][(i + 2)]) / - (hilite_dir4[3][(j + 1)][(i - 2)] + hilite_dir4[3][(j + 1)][(i - 1)] + hilite_dir4[3][(j + 1)][(i)] + hilite_dir4[3][(j + 1)][(i + 1)] + hilite_dir4[3][(j + 1)][(i + 2)] + epsilon)); + for (int c = 0; c < 3; c++) { + for (int j = hfw - 2; j > 0; j--) { + for (int i = 2; i < hfh - 2; i++) { + //from right + if (hilite[3][i][j] > epsilon) { + hilite_dir4[c][j][i] = hilite[c][i][j] / hilite[3][i][j]; + } else { + hilite_dir4[c][j][i] = 0.1f * ((hilite_dir4[c][(j + 1)][(i - 2)] + hilite_dir4[c][(j + 1)][(i - 1)] + hilite_dir4[c][(j + 1)][(i)] + hilite_dir4[c][(j + 1)][(i + 1)] + hilite_dir4[c][(j + 1)][(i + 2)]) / + (hilite_dir4[3][(j + 1)][(i - 2)] + hilite_dir4[3][(j + 1)][(i - 1)] + hilite_dir4[3][(j + 1)][(i)] + hilite_dir4[3][(j + 1)][(i + 1)] + hilite_dir4[3][(j + 1)][(i + 2)] + epsilon)); + } + } + + if(hilite[3][2][j] <= epsilon) { + hilite_dir[0 + c][0][j] += hilite_dir4[c][j][2]; + } + + if(hilite[3][hfh - 3][j] <= epsilon) { + hilite_dir[4 + c][hfh - 1][j] += hilite_dir4[c][j][hfh - 3]; } } - if(hilite[3][2][j] <= epsilon) { - hilite_dir[0 + c][0][j] += hilite_dir4[c][j][2]; - } + for (int i = 2; i < hfh - 2; i++) { + if(hilite[3][i][0] <= epsilon) { + hilite_dir[0 + c][i - 2][0] += hilite_dir4[c][0][i]; + hilite_dir[4 + c][i + 2][0] += hilite_dir4[c][0][i]; + } - if(hilite[3][hfh - 3][j] <= epsilon) { - hilite_dir[4 + c][hfh - 1][j] += hilite_dir4[c][j][hfh - 3]; + if(hilite[3][i][1] <= epsilon) { + hilite_dir[0 + c][i - 2][1] += hilite_dir4[c][1][i]; + hilite_dir[4 + c][i + 2][1] += hilite_dir4[c][1][i]; + } + + if(hilite[3][i][hfw - 2] <= epsilon) { + hilite_dir[0 + c][i - 2][hfw - 2] += hilite_dir4[c][hfw - 2][i]; + hilite_dir[4 + c][i + 2][hfw - 2] += hilite_dir4[c][hfw - 2][i]; + } } } - for (int i = 2; i < hfh - 2; i++) { - if(hilite[3][i][0] <= epsilon) { - hilite_dir[0 + c][i - 2][0] += hilite_dir4[c][0][i]; - hilite_dir[4 + c][i + 2][0] += hilite_dir4[c][0][i]; - } - - if(hilite[3][i][1] <= epsilon) { - hilite_dir[0 + c][i - 2][1] += hilite_dir4[c][1][i]; - hilite_dir[4 + c][i + 2][1] += hilite_dir4[c][1][i]; - } - - if(hilite[3][i][hfw - 2] <= epsilon) { - hilite_dir[0 + c][i - 2][hfw - 2] += hilite_dir4[c][hfw - 2][i]; - hilite_dir[4 + c][i + 2][hfw - 2] += hilite_dir4[c][hfw - 2][i]; - } - } - } - - if(plistener) { - progress += 0.05; - plistener->setProgress(progress); - } - - - for (int i = 1; i < hfh - 1; i++) - for (int j = 2; j < hfw - 2; j++) { - //from top - if (hilite[3][i][j] > epsilon) { - hilite_dir[0 + 3][i][j] = 1.f; - } else { - hilite_dir[0 + 3][i][j] = (hilite_dir[0 + 3][i - 1][j - 2] + hilite_dir[0 + 3][i - 1][j - 1] + hilite_dir[0 + 3][i - 1][j] + hilite_dir[0 + 3][i - 1][j + 1] + hilite_dir[0 + 3][i - 1][j + 2]) == 0.f ? 0.f : 0.1f; - } - } - - for (int j = 2; j < hfw - 2; j++) { - if(hilite[3][hfh - 2][j] <= epsilon) { - hilite_dir[4 + 3][hfh - 1][j] += hilite_dir[0 + 3][hfh - 2][j]; - } - } - #ifdef _OPENMP - #pragma omp parallel for + #pragma omp single #endif + { + for (int i = 1; i < hfh - 1; i++) + for (int j = 2; j < hfw - 2; j++) { + //from top + if (hilite[3][i][j] > epsilon) { + hilite_dir[0 + 3][i][j] = 1.f; + } else { + hilite_dir[0 + 3][i][j] = (hilite_dir[0 + 3][i - 1][j - 2] + hilite_dir[0 + 3][i - 1][j - 1] + hilite_dir[0 + 3][i - 1][j] + hilite_dir[0 + 3][i - 1][j + 1] + hilite_dir[0 + 3][i - 1][j + 2]) == 0.f ? 0.f : 0.1f; + } + } - for (int c = 0; c < 3; c++) { - for (int i = 1; i < hfh - 1; i++) { for (int j = 2; j < hfw - 2; j++) { - //from top - if (hilite[3][i][j] > epsilon) { - hilite_dir[0 + c][i][j] = hilite[c][i][j] / hilite[3][i][j]; - } else { - hilite_dir[0 + c][i][j] = 0.1 * ((hilite_dir[0 + c][i - 1][j - 2] + hilite_dir[0 + c][i - 1][j - 1] + hilite_dir[0 + c][i - 1][j] + hilite_dir[0 + c][i - 1][j + 1] + hilite_dir[0 + c][i - 1][j + 2]) / - (hilite_dir[0 + 3][i - 1][j - 2] + hilite_dir[0 + 3][i - 1][j - 1] + hilite_dir[0 + 3][i - 1][j] + hilite_dir[0 + 3][i - 1][j + 1] + hilite_dir[0 + 3][i - 1][j + 2] + epsilon)); + if(hilite[3][hfh - 2][j] <= epsilon) { + hilite_dir[4 + 3][hfh - 1][j] += hilite_dir[0 + 3][hfh - 2][j]; } } } - - for (int j = 2; j < hfw - 2; j++) { - if(hilite[3][hfh - 2][j] <= epsilon) { - hilite_dir[4 + c][hfh - 1][j] += hilite_dir[0 + c][hfh - 2][j]; - } - } } - if(plistener) { progress += 0.05; plistener->setProgress(progress); } - for (int i = hfh - 2; i > 0; i--) - for (int j = 2; j < hfw - 2; j++) { - //from bottom - if (hilite[3][i][j] > epsilon) { - hilite_dir[4 + 3][i][j] = 1.f; - } else { - hilite_dir[4 + 3][i][j] = (hilite_dir[4 + 3][(i + 1)][(j - 2)] + hilite_dir[4 + 3][(i + 1)][(j - 1)] + hilite_dir[4 + 3][(i + 1)][(j)] + hilite_dir[4 + 3][(i + 1)][(j + 1)] + hilite_dir[4 + 3][(i + 1)][(j + 2)]) == 0.f ? 0.f : 0.1f; +#ifdef _OPENMP + #pragma omp parallel +#endif + { +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int c = 0; c < 3; c++) { + for (int i = 1; i < hfh - 1; i++) { + for (int j = 2; j < hfw - 2; j++) { + //from top + if (hilite[3][i][j] > epsilon) { + hilite_dir[0 + c][i][j] = hilite[c][i][j] / hilite[3][i][j]; + } else { + hilite_dir[0 + c][i][j] = 0.1f * ((hilite_dir[0 + c][i - 1][j - 2] + hilite_dir[0 + c][i - 1][j - 1] + hilite_dir[0 + c][i - 1][j] + hilite_dir[0 + c][i - 1][j + 1] + hilite_dir[0 + c][i - 1][j + 2]) / + (hilite_dir[0 + 3][i - 1][j - 2] + hilite_dir[0 + 3][i - 1][j - 1] + hilite_dir[0 + 3][i - 1][j] + hilite_dir[0 + 3][i - 1][j + 1] + hilite_dir[0 + 3][i - 1][j + 2] + epsilon)); + } + } + } + + for (int j = 2; j < hfw - 2; j++) { + if(hilite[3][hfh - 2][j] <= epsilon) { + hilite_dir[4 + c][hfh - 1][j] += hilite_dir[0 + c][hfh - 2][j]; + } } } + +#ifdef _OPENMP + #pragma omp single +#endif + for (int i = hfh - 2; i > 0; i--) + for (int j = 2; j < hfw - 2; j++) { + //from bottom + if (hilite[3][i][j] > epsilon) { + hilite_dir[4 + 3][i][j] = 1.f; + } else { + hilite_dir[4 + 3][i][j] = (hilite_dir[4 + 3][(i + 1)][(j - 2)] + hilite_dir[4 + 3][(i + 1)][(j - 1)] + hilite_dir[4 + 3][(i + 1)][(j)] + hilite_dir[4 + 3][(i + 1)][(j + 1)] + hilite_dir[4 + 3][(i + 1)][(j + 2)]) == 0.f ? 0.f : 0.1f; + } + } + } + + if(plistener) { + progress += 0.05; + plistener->setProgress(progress); + } + #ifdef _OPENMP #pragma omp parallel for #endif @@ -814,7 +839,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b if (hilite[3][i][j] > epsilon) { hilite_dir[4 + c][i][j] = hilite[c][i][j] / hilite[3][i][j]; } else { - hilite_dir[4 + c][i][j] = 0.1 * ((hilite_dir[4 + c][(i + 1)][(j - 2)] + hilite_dir[4 + c][(i + 1)][(j - 1)] + hilite_dir[4 + c][(i + 1)][(j)] + hilite_dir[4 + c][(i + 1)][(j + 1)] + hilite_dir[4 + c][(i + 1)][(j + 2)]) / + hilite_dir[4 + c][i][j] = 0.1f * ((hilite_dir[4 + c][(i + 1)][(j - 2)] + hilite_dir[4 + c][(i + 1)][(j - 1)] + hilite_dir[4 + c][(i + 1)][(j)] + hilite_dir[4 + c][(i + 1)][(j + 1)] + hilite_dir[4 + c][(i + 1)][(j + 2)]) / (hilite_dir[4 + 3][(i + 1)][(j - 2)] + hilite_dir[4 + 3][(i + 1)][(j - 1)] + hilite_dir[4 + 3][(i + 1)][(j)] + hilite_dir[4 + 3][(i + 1)][(j + 1)] + hilite_dir[4 + 3][(i + 1)][(j + 2)] + epsilon)); } } From c56106beaee25a0bd370bc22e75de23258ae40f7 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 9 Jul 2019 17:39:53 +0200 Subject: [PATCH 045/222] color propagation: small speedup, also some code formating --- rtengine/hilite_recon.cc | 273 +++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 140 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index a726481dd..7fe527a78 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -22,9 +22,7 @@ // //////////////////////////////////////////////////////////////// -#ifndef NDEBUG #include -#endif #include #include @@ -81,19 +79,19 @@ void boxblur2(const float* const* src, float** dst, float** temp, int startY, in #endif for (int col = 0; col < bufferW - numCols + 1; col += numCols) { float len = box + 1; - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = temp[0][col + n] / len; } for (int i = 1; i <= box; i++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] += temp[i][col + n] / len; } } - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { dst[0][col + n] = tempvalN[n]; } for (int row = 1; row <= box; row++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = (tempvalN[n] * len + temp[(row + box)][col + n]) / (len + 1); dst[row][col + n] = tempvalN[n]; } @@ -101,14 +99,14 @@ void boxblur2(const float* const* src, float** dst, float** temp, int startY, in } const float rlen = 1.f / len; for (int row = box + 1; row < H - box; row++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = tempvalN[n] + (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; dst[row][col + n] = tempvalN[n]; } } for (int row = H - box; row < H; row++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = (dst[(row - 1)][col + n] * len - temp[(row - box - 1)][col + n]) / (len - 1); dst[row][col + n] = tempvalN[n]; } @@ -118,7 +116,7 @@ void boxblur2(const float* const* src, float** dst, float** temp, int startY, in } } -void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int box, int samp ) +void boxblur_resamp(const float * const *src, float **dst, float ** temp, int H, int W, int box, int samp ) { #ifdef _OPENMP @@ -145,7 +143,7 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b for (int col = 1; col <= box; col++) { tempval = (tempval * len + src[row][col + box]) / (len + 1); - if(col % samp == 0) { + if (col % samp == 0) { temp[row][col / samp] = tempval; } @@ -157,7 +155,7 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b for (int col = box + 1; col < W - box; col++) { tempval = tempval + (src[row][col + box] - src[row][col - box - 1]) * oneByLen; - if(col % samp == 0) { + if (col % samp == 0) { temp[row][col / samp] = tempval; } } @@ -165,7 +163,7 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b for (int col = W - box; col < W; col++) { tempval = (tempval * len - src[row][col - box - 1]) / (len - 1); - if(col % samp == 0) { + if (col % samp == 0) { temp[row][col / samp] = tempval; } @@ -188,27 +186,27 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b for (int col = 0; col < (W / samp) - (numCols - 1); col += numCols) { float len = box + 1; - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = temp[0][col + n] / len; } for (int i = 1; i <= box; i++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] += temp[i][col + n] / len; } } - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { dst[0][col + n] = tempvalN[n]; } for (int row = 1; row <= box; row++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = (tempvalN[n] * len + temp[(row + box)][col + n]) / (len + 1); } - if(row % samp == 0) { - for(int n = 0; n < numCols; n++) { + if (row % samp == 0) { + for (int n = 0; n < numCols; n++) { dst[row / samp][col + n] = tempvalN[n]; } } @@ -217,24 +215,24 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b } const float rlen = 1.f / len; for (int row = box + 1; row < H - box; row++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = tempvalN[n] + (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; } - if(row % samp == 0) { - for(int n = 0; n < numCols; n++) { + if (row % samp == 0) { + for (int n = 0; n < numCols; n++) { dst[row / samp][col + n] = tempvalN[n]; } } } for (int row = H - box; row < H; row++) { - for(int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; n++) { tempvalN[n] = (tempvalN[n] * len - temp[(row - box - 1)][col + n]) / (len - 1); } - if(row % samp == 0) { - for(int n = 0; n < numCols; n++) { + if (row % samp == 0) { + for (int n = 0; n < numCols; n++) { dst[row / samp][col + n] = tempvalN[n]; } } @@ -263,7 +261,7 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b for (int row = 1; row <= box; row++) { tempval = (tempval * len + temp[(row + box)][col]) / (len + 1); - if(row % samp == 0) { + if (row % samp == 0) { dst[row / samp][col] = tempval; } @@ -273,7 +271,7 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b for (int row = box + 1; row < H - box; row++) { tempval = tempval + (temp[(row + box)][col] - temp[(row - box - 1)][col]) / len; - if(row % samp == 0) { + if (row % samp == 0) { dst[row / samp][col] = tempval; } } @@ -281,7 +279,7 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b for (int row = H - box; row < H; row++) { tempval = (tempval * len - temp[(row - box - 1)][col]) / (len - 1); - if(row % samp == 0) { + if (row % samp == 0) { dst[row / samp][col] = tempval; } @@ -290,8 +288,6 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b } } } - - } } @@ -301,7 +297,7 @@ namespace rtengine extern const Settings* settings; -void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** blue) +void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blue) { BENCHFUN double progress = 0.0; @@ -311,8 +307,8 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b plistener->setProgress (progress); } - int height = H; - int width = W; + const int height = H; + const int width = W; constexpr int range = 2; constexpr int pitch = 4; @@ -330,20 +326,20 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b constexpr float itrans[ColorCount][ColorCount] = { { 1.f, 0.8660254f, -0.5f }, { 1.f, -0.8660254f, -0.5f }, { 1.f, 0.f, 1.f } }; - if(settings->verbose) - for(int c = 0; c < 3; c++) { + if (settings->verbose) + for (int c = 0; c < 3; c++) { printf("chmax[%d] : %f\tclmax[%d] : %f\tratio[%d] : %f\n", c, chmax[c], c, clmax[c], c, chmax[c] / clmax[c]); } float factor[3]; - for(int c = 0; c < ColorCount; c++) { + for (int c = 0; c < ColorCount; c++) { factor[c] = chmax[c] / clmax[c]; } float minFactor = min(factor[0], factor[1], factor[2]); - if(minFactor > 1.f) { // all 3 channels clipped + if (minFactor > 1.f) { // all 3 channels clipped // calculate clip factor per channel for (int c = 0; c < ColorCount; c++) { factor[c] /= minFactor; @@ -354,15 +350,15 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b float maxValNew = 0.f; for (int c = 0; c < ColorCount; c++) { - if(chmax[c] / factor[c] > maxValNew) { + if (chmax[c] / factor[c] > maxValNew) { maxValNew = chmax[c] / factor[c]; maxpos = c; } } - float clipFactor = clmax[maxpos] / maxValNew; + const float clipFactor = clmax[maxpos] / maxValNew; - if(clipFactor < maxpct) + if (clipFactor < maxpct) // if max clipFactor < maxpct (0.95) adjust per channel factors for (int c = 0; c < ColorCount; c++) { @@ -372,7 +368,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b factor[0] = factor[1] = factor[2] = 1.f; } - if(settings->verbose) + if (settings->verbose) for (int c = 0; c < ColorCount; c++) { printf("correction factor[%d] : %f\n", c, factor[c]); } @@ -384,10 +380,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b max_f[c] = chmax[c] * maxpct / factor[c]; } - float whitept = max(max_f[0], max_f[1], max_f[2]); - float clippt = min(max_f[0], max_f[1], max_f[2]); - float medpt = max_f[0] + max_f[1] + max_f[2] - whitept - clippt; - float blendpt = blendthresh * clippt; + const float whitept = max(max_f[0], max_f[1], max_f[2]); + const float clippt = min(max_f[0], max_f[1], max_f[2]); + const float medpt = max_f[0] + max_f[1] + max_f[2] - whitept - clippt; + const float blendpt = blendthresh * clippt; float medFactor[3]; for (int c = 0; c < ColorCount; c++) { @@ -401,7 +397,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b #pragma omp parallel for reduction(min:minx,miny) reduction(max:maxx,maxy) schedule(dynamic, 16) for (int i = 0; i < height; ++i) { for (int j = 0; j< width; ++j) { - if(red[i][j] >= max_f[0] || green[i][j] >= max_f[1] || blue[i][j] >= max_f[2]) { + if (red[i][j] >= max_f[0] || green[i][j] >= max_f[1] || blue[i][j] >= max_f[2]) { minx = std::min(minx, j); maxx = std::max(maxx, j); miny = std::min(miny, i); @@ -410,10 +406,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - std::cout << "minx : " << minx << std::endl; - std::cout << "maxx : " << maxx << std::endl; - std::cout << "miny : " << miny << std::endl; - std::cout << "maxy : " << maxy << std::endl; + if (plistener) { + progress += 0.05; + plistener->setProgress(progress); + } constexpr int blurBorder = 256; minx = std::max(0, minx - blurBorder); @@ -424,10 +420,16 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b const int blurHeight = maxy - miny + 1; const int bufferWidth = blurWidth + ((16 - (blurWidth % 16)) & 15); + std::cout << "minx : " << minx << std::endl; + std::cout << "maxx : " << maxx << std::endl; + std::cout << "miny : " << miny << std::endl; + std::cout << "maxy : " << maxy << std::endl; + std::cout << "blurWidth : " << blurWidth << std::endl; std::cout << "bufferWidth : " << bufferWidth << std::endl; - std::cout << "Corrected area reduced by factor: " << (((float)width * height) / (blurWidth * blurHeight)) << std::endl; + std::cout << "Corrected area reduced by factor: " << (((float)width * height) / (bufferWidth * blurHeight)) << std::endl; + std::cout << "Peak memory usage reduced from ~" << (30ul * ((size_t)width * (size_t)height)) / (1024*1024) << " Mb to ~" << (30ul * ((size_t)bufferWidth * (size_t)blurHeight)) / (1024*1024) << " Mb" << std::endl; multi_array2D channelblur(bufferWidth, blurHeight, 0, 48); array2D temp(bufferWidth, blurHeight); // allocate temporary buffer @@ -435,22 +437,22 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); - if(plistener) { - progress += 0.05; + if (plistener) { + progress += 0.07; plistener->setProgress(progress); } boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); - if(plistener) { - progress += 0.05; + if (plistener) { + progress += 0.07; plistener->setProgress(progress); } boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); - if(plistener) { - progress += 0.05; + if (plistener) { + progress += 0.07; plistener->setProgress(progress); } @@ -459,8 +461,8 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b #pragma omp parallel for #endif - for(int i = 0; i < blurHeight; i++) - for(int j = 0; j < blurWidth; j++) { + for (int i = 0; i < blurHeight; i++) + for (int j = 0; j < blurWidth; j++) { channelblur[0][i][j] = fabsf(channelblur[0][i][j] - red[i + miny][j + minx]) + fabsf(channelblur[1][i][j] - green[i + miny][j + minx]) + fabsf(channelblur[2][i][j] - blue[i + miny][j + minx]); } @@ -468,15 +470,15 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b channelblur[c].free(); //free up some memory } - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } multi_array2D hilite_full(bufferWidth, blurHeight, ARRAY2D_CLEAR_DATA, 32); - if(plistener) { - progress += 0.10; + if (plistener) { + progress += 0.05; plistener->setProgress(progress); } @@ -506,9 +508,9 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } }//end of filling highlight array - float hipass_ave = 2.f * hipass_sum / (hipass_norm + epsilon); + const float hipass_ave = 2.f * hipass_sum / (hipass_norm + epsilon); - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } @@ -520,8 +522,8 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b temp.free(); // free temporary buffer - if(plistener) { - progress += 0.05; + if (plistener) { + progress += 0.07; plistener->setProgress(progress); } @@ -560,7 +562,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b for (int m = 0; m < 4; m++) { boxblur_resamp(hilite_full[m], hilite[m], temp2, blurHeight, blurWidth, range, pitch); - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } @@ -577,7 +579,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b multi_array2D hilite_dir0(hfh, hfw, ARRAY2D_CLEAR_DATA, 64); multi_array2D hilite_dir4(hfh, hfw, ARRAY2D_CLEAR_DATA, 64); - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } @@ -594,25 +596,25 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - if(hilite[3][2][j] <= epsilon) { + if (hilite[3][2][j] <= epsilon) { hilite_dir[0 + 3][0][j] = hilite_dir0[3][j][2]; } - if(hilite[3][3][j] <= epsilon) { + if (hilite[3][3][j] <= epsilon) { hilite_dir[0 + 3][1][j] = hilite_dir0[3][j][3]; } - if(hilite[3][hfh - 3][j] <= epsilon) { + if (hilite[3][hfh - 3][j] <= epsilon) { hilite_dir[4 + 3][hfh - 1][j] = hilite_dir0[3][j][hfh - 3]; } - if(hilite[3][hfh - 4][j] <= epsilon) { + if (hilite[3][hfh - 4][j] <= epsilon) { hilite_dir[4 + 3][hfh - 2][j] = hilite_dir0[3][j][hfh - 4]; } } for (int i = 2; i < hfh - 2; i++) { - if(hilite[3][i][hfw - 2] <= epsilon) { + if (hilite[3][i][hfw - 2] <= epsilon) { hilite_dir4[3][hfw - 1][i] = hilite_dir0[3][hfw - 2][i]; } } @@ -637,25 +639,25 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - if(hilite[3][2][j] <= epsilon) { + if (hilite[3][2][j] <= epsilon) { hilite_dir[0 + c][0][j] = hilite_dir0[c][j][2]; } - if(hilite[3][3][j] <= epsilon) { + if (hilite[3][3][j] <= epsilon) { hilite_dir[0 + c][1][j] = hilite_dir0[c][j][3]; } - if(hilite[3][hfh - 3][j] <= epsilon) { + if (hilite[3][hfh - 3][j] <= epsilon) { hilite_dir[4 + c][hfh - 1][j] = hilite_dir0[c][j][hfh - 3]; } - if(hilite[3][hfh - 4][j] <= epsilon) { + if (hilite[3][hfh - 4][j] <= epsilon) { hilite_dir[4 + c][hfh - 2][j] = hilite_dir0[c][j][hfh - 4]; } } for (int i = 2; i < hfh - 2; i++) { - if(hilite[3][i][hfw - 2] <= epsilon) { + if (hilite[3][i][hfw - 2] <= epsilon) { hilite_dir4[c][hfw - 1][i] = hilite_dir0[c][hfw - 2][i]; } } @@ -675,34 +677,34 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - if(hilite[3][2][j] <= epsilon) { + if (hilite[3][2][j] <= epsilon) { hilite_dir[0 + 3][0][j] += hilite_dir4[3][j][2]; } - if(hilite[3][hfh - 3][j] <= epsilon) { + if (hilite[3][hfh - 3][j] <= epsilon) { hilite_dir[4 + 3][hfh - 1][j] += hilite_dir4[3][j][hfh - 3]; } } for (int i = 2; i < hfh - 2; i++) { - if(hilite[3][i][0] <= epsilon) { + if (hilite[3][i][0] <= epsilon) { hilite_dir[0 + 3][i - 2][0] += hilite_dir4[3][0][i]; hilite_dir[4 + 3][i + 2][0] += hilite_dir4[3][0][i]; } - if(hilite[3][i][1] <= epsilon) { + if (hilite[3][i][1] <= epsilon) { hilite_dir[0 + 3][i - 2][1] += hilite_dir4[3][1][i]; hilite_dir[4 + 3][i + 2][1] += hilite_dir4[3][1][i]; } - if(hilite[3][i][hfw - 2] <= epsilon) { + if (hilite[3][i][hfw - 2] <= epsilon) { hilite_dir[0 + 3][i - 2][hfw - 2] += hilite_dir4[3][hfw - 2][i]; hilite_dir[4 + 3][i + 2][hfw - 2] += hilite_dir4[3][hfw - 2][i]; } } } } - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } @@ -727,27 +729,27 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - if(hilite[3][2][j] <= epsilon) { + if (hilite[3][2][j] <= epsilon) { hilite_dir[0 + c][0][j] += hilite_dir4[c][j][2]; } - if(hilite[3][hfh - 3][j] <= epsilon) { + if (hilite[3][hfh - 3][j] <= epsilon) { hilite_dir[4 + c][hfh - 1][j] += hilite_dir4[c][j][hfh - 3]; } } for (int i = 2; i < hfh - 2; i++) { - if(hilite[3][i][0] <= epsilon) { + if (hilite[3][i][0] <= epsilon) { hilite_dir[0 + c][i - 2][0] += hilite_dir4[c][0][i]; hilite_dir[4 + c][i + 2][0] += hilite_dir4[c][0][i]; } - if(hilite[3][i][1] <= epsilon) { + if (hilite[3][i][1] <= epsilon) { hilite_dir[0 + c][i - 2][1] += hilite_dir4[c][1][i]; hilite_dir[4 + c][i + 2][1] += hilite_dir4[c][1][i]; } - if(hilite[3][i][hfw - 2] <= epsilon) { + if (hilite[3][i][hfw - 2] <= epsilon) { hilite_dir[0 + c][i - 2][hfw - 2] += hilite_dir4[c][hfw - 2][i]; hilite_dir[4 + c][i + 2][hfw - 2] += hilite_dir4[c][hfw - 2][i]; } @@ -769,13 +771,13 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } for (int j = 2; j < hfw - 2; j++) { - if(hilite[3][hfh - 2][j] <= epsilon) { + if (hilite[3][hfh - 2][j] <= epsilon) { hilite_dir[4 + 3][hfh - 1][j] += hilite_dir[0 + 3][hfh - 2][j]; } } } } - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } @@ -802,7 +804,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } for (int j = 2; j < hfw - 2; j++) { - if(hilite[3][hfh - 2][j] <= epsilon) { + if (hilite[3][hfh - 2][j] <= epsilon) { hilite_dir[4 + c][hfh - 1][j] += hilite_dir[0 + c][hfh - 2][j]; } } @@ -823,7 +825,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } @@ -846,7 +848,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } @@ -911,38 +913,38 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b hilite_dir4[c][hfw - 1][hfh - 1] = hilite_dir4[c][hfw - 1][hfh - 2] = hilite_dir4[c][hfw - 2][hfh - 1] = hilite_dir4[c][hfw - 2][hfh - 2] = hilite_dir4[c][hfw - 3][hfh - 3]; } - if(plistener) { + if (plistener) { progress += 0.05; plistener->setProgress(progress); } //free up some memory - for(int c = 0; c < 4; c++) { + for (int c = 0; c < 4; c++) { hilite[c].free(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // now reconstruct clipped channels using color ratios - +StopWatch Stop1("last loop"); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif for (int i = 0; i < blurHeight; i++) { - int i1 = min((i - (i % pitch)) / pitch, hfh - 1); + const int i1 = min((i - (i % pitch)) / pitch, hfh - 1); for (int j = 0; j < blurWidth; j++) { - float pixel[3] = {red[i + miny][j + minx], green[i + miny][j + minx], blue[i + miny][j + minx]}; + const float pixel[3] = {red[i + miny][j + minx], green[i + miny][j + minx], blue[i + miny][j + minx]}; if (pixel[0] < max_f[0] && pixel[1] < max_f[1] && pixel[2] < max_f[2]) { continue; //pixel not clipped } - int j1 = min((j - (j % pitch)) / pitch, hfw - 1); + const int j1 = min((j - (j % pitch)) / pitch, hfw - 1); //estimate recovered values using modified HLRecovery_blend algorithm - float rgb[ColorCount], rgb_blend[ColorCount] = {}, cam[2][ColorCount], lab[2][ColorCount], sum[2], chratio; + float rgb[ColorCount], rgb_blend[ColorCount] = {}, cam[2][ColorCount], lab[2][ColorCount], sum[2]; // Copy input pixel to rgb so it's easier to access in loops rgb[0] = pixel[0]; @@ -972,12 +974,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } - if(sum[0] == 0.f) { // avoid division by zero - sum[0] = epsilon; - } - - chratio = sqrtf(sum[1] / sum[0]); + // avoid division by zero + sum[0] = std::max(sum[0], epsilon); + const float chratio = sqrtf(sum[1] / sum[0]); // Apply ratio to lightness in lab space for (int c = 1; c < ColorCount; c++) { @@ -998,19 +998,18 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } // Copy converted pixel back - float rfrac = max(0.f, min(1.f, medFactor[0] * (pixel[0] - blendpt))); - float gfrac = max(0.f, min(1.f, medFactor[1] * (pixel[1] - blendpt))); - float bfrac = max(0.f, min(1.f, medFactor[2] * (pixel[2] - blendpt))); - if (pixel[0] > blendpt) { + const float rfrac = max(0.f, min(1.f, medFactor[0] * (pixel[0] - blendpt))); rgb_blend[0] = rfrac * rgb[0] + (1.f - rfrac) * pixel[0]; } if (pixel[1] > blendpt) { + const float gfrac = max(0.f, min(1.f, medFactor[1] * (pixel[1] - blendpt))); rgb_blend[1] = gfrac * rgb[1] + (1.f - gfrac) * pixel[1]; } if (pixel[2] > blendpt) { + const float bfrac = max(0.f, min(1.f, medFactor[2] * (pixel[2] - blendpt))); rgb_blend[2] = bfrac * rgb[2] + (1.f - bfrac) * pixel[2]; } @@ -1019,7 +1018,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b //there are clipped highlights //first, determine weighted average of unclipped extensions (weighting is by 'hue' proximity) - float totwt = 0.f; + bool totwt = false; float clipfix[3] = {0.f, 0.f, 0.f}; float Y = epsilon + rgb_blend[0] + rgb_blend[1] + rgb_blend[2]; @@ -1031,25 +1030,23 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b float Yhi = 1.f / (hilite_dir0[0][j1][i1] + hilite_dir0[1][j1][i1] + hilite_dir0[2][j1][i1]); if (Yhi < 2.f) { - float dirwt = 1.f / (1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir0[0][j1][i1] * Yhi) + + const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir0[0][j1][i1] * Yhi) + SQR(rgb_blend[1] - hilite_dir0[1][j1][i1] * Yhi) + - SQR(rgb_blend[2] - hilite_dir0[2][j1][i1] * Yhi))); - totwt = dirwt; - dirwt /= (hilite_dir0[3][j1][i1] + epsilon); + SQR(rgb_blend[2] - hilite_dir0[2][j1][i1] * Yhi))) * (hilite_dir0[3][j1][i1] + epsilon)); + totwt = true; clipfix[0] = dirwt * hilite_dir0[0][j1][i1]; clipfix[1] = dirwt * hilite_dir0[1][j1][i1]; clipfix[2] = dirwt * hilite_dir0[2][j1][i1]; } for (int dir = 0; dir < 2; dir++) { - float Yhi = 1.f / ( hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]); + const float Yhi = 1.f / ( hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]); if (Yhi < 2.f) { - float dirwt = 1.f / (1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir[dir * 4 + 0][i1][j1] * Yhi) + + const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir[dir * 4 + 0][i1][j1] * Yhi) + SQR(rgb_blend[1] - hilite_dir[dir * 4 + 1][i1][j1] * Yhi) + - SQR(rgb_blend[2] - hilite_dir[dir * 4 + 2][i1][j1] * Yhi))); - totwt += dirwt; - dirwt /= (hilite_dir[dir * 4 + 3][i1][j1] + epsilon); + SQR(rgb_blend[2] - hilite_dir[dir * 4 + 2][i1][j1] * Yhi))) * (hilite_dir[dir * 4 + 3][i1][j1] + epsilon)); + totwt = true; clipfix[0] += dirwt * hilite_dir[dir * 4 + 0][i1][j1]; clipfix[1] += dirwt * hilite_dir[dir * 4 + 1][i1][j1]; clipfix[2] += dirwt * hilite_dir[dir * 4 + 2][i1][j1]; @@ -1060,56 +1057,51 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b Yhi = 1.f / (hilite_dir4[0][j1][i1] + hilite_dir4[1][j1][i1] + hilite_dir4[2][j1][i1]); if (Yhi < 2.f) { - float dirwt = 1.f / (1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir4[0][j1][i1] * Yhi) + + const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir4[0][j1][i1] * Yhi) + SQR(rgb_blend[1] - hilite_dir4[1][j1][i1] * Yhi) + - SQR(rgb_blend[2] - hilite_dir4[2][j1][i1] * Yhi))); - totwt += dirwt; - dirwt /= (hilite_dir4[3][j1][i1] + epsilon); + SQR(rgb_blend[2] - hilite_dir4[2][j1][i1] * Yhi))) * (hilite_dir4[3][j1][i1] + epsilon)); + totwt = true; clipfix[0] += dirwt * hilite_dir4[0][j1][i1]; clipfix[1] += dirwt * hilite_dir4[1][j1][i1]; clipfix[2] += dirwt * hilite_dir4[2][j1][i1]; } - if(totwt == 0.f) { + if (UNLIKELY(!totwt)) { continue; } - clipfix[0] /= totwt; - clipfix[1] /= totwt; - clipfix[2] /= totwt; - //now correct clipped channels if (pixel[0] > max_f[0] && pixel[1] > max_f[1] && pixel[2] > max_f[2]) { //all channels clipped - float Y = (0.299 * clipfix[0] + 0.587 * clipfix[1] + 0.114 * clipfix[2]); + const float Y = 0.299f * clipfix[0] + 0.587f * clipfix[1] + 0.114f * clipfix[2]; - float factor = whitept / Y; + const float factor = whitept / Y; red[i + miny][j + minx] = clipfix[0] * factor; green[i + miny][j + minx] = clipfix[1] * factor; blue[i + miny][j + minx] = clipfix[2] * factor; } else {//some channels clipped - float notclipped[3] = {pixel[0] <= max_f[0] ? 1.f : 0.f, pixel[1] <= max_f[1] ? 1.f : 0.f, pixel[2] <= max_f[2] ? 1.f : 0.f}; + const float notclipped[3] = {pixel[0] <= max_f[0] ? 1.f : 0.f, pixel[1] <= max_f[1] ? 1.f : 0.f, pixel[2] <= max_f[2] ? 1.f : 0.f}; if (notclipped[0] == 0.f) { //red clipped - red[i + miny][j + minx] = max(red[i + miny][j + minx], (clipfix[0] * ((notclipped[1] * pixel[1] + notclipped[2] * pixel[2]) / - (notclipped[1] * clipfix[1] + notclipped[2] * clipfix[2] + epsilon)))); + red[i + miny][j + minx] = max(pixel[0], clipfix[0] * ((notclipped[1] * pixel[1] + notclipped[2] * pixel[2]) / + (notclipped[1] * clipfix[1] + notclipped[2] * clipfix[2] + epsilon))); } if (notclipped[1] == 0.f) { //green clipped - green[i + miny][j + minx] = max(green[i + miny][j + minx], (clipfix[1] * ((notclipped[2] * pixel[2] + notclipped[0] * pixel[0]) / - (notclipped[2] * clipfix[2] + notclipped[0] * clipfix[0] + epsilon)))); + green[i + miny][j + minx] = max(pixel[1], clipfix[1] * ((notclipped[2] * pixel[2] + notclipped[0] * pixel[0]) / + (notclipped[2] * clipfix[2] + notclipped[0] * clipfix[0] + epsilon))); } if (notclipped[2] == 0.f) { //blue clipped - blue[i + miny][j + minx] = max(blue[i + miny][j + minx], (clipfix[2] * ((notclipped[0] * pixel[0] + notclipped[1] * pixel[1]) / - (notclipped[0] * clipfix[0] + notclipped[1] * clipfix[1] + epsilon)))); + blue[i + miny][j + minx] = max(pixel[2], clipfix[2] * ((notclipped[0] * pixel[0] + notclipped[1] * pixel[1]) / + (notclipped[0] * clipfix[0] + notclipped[1] * clipfix[1] + epsilon))); } } - Y = (0.299 * red[i + miny][j + minx] + 0.587 * green[i + miny][j + minx] + 0.114 * blue[i + miny][j + minx]); + Y = 0.299f * red[i + miny][j + minx] + 0.587f * green[i + miny][j + minx] + 0.114f * blue[i + miny][j + minx]; if (Y > whitept) { - float factor = whitept / Y; + const float factor = whitept / Y; red[i + miny][j + minx] *= factor; green[i + miny][j + minx] *= factor; @@ -1117,8 +1109,9 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } } } +std::cout << "progress : " << progress << std::endl; - if(plistener) { + if (plistener) { plistener->setProgress(1.00); } From 0b1ba37c759a7417a4fa88f5643f8a5466def6b8 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 9 Jul 2019 19:40:08 +0200 Subject: [PATCH 046/222] color propagation: fix segfault whan there is nothing to reconstruct --- rtengine/hilite_recon.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 7fe527a78..15077b92a 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -406,6 +406,10 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } + if (minx > maxx || miny > maxy) { // nothing to reconstruct + return; + } + if (plistener) { progress += 0.05; plistener->setProgress(progress); From 3f9c232f18b172367e2e43501a1db18ff24513dc Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 9 Jul 2019 23:15:38 +0200 Subject: [PATCH 047/222] hilite_recon.cc --- rtengine/hilite_recon.cc | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 15077b92a..a0a8cb83d 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -3,9 +3,11 @@ // Highlight reconstruction // // copyright (c) 2008-2011 Emil Martinec +// copyright (c) 2019 Ingo Weyrich // // // code dated: June 16, 2011 +// code dated: July 09. 2019, speedups by Ingo Weyrich // // hilite_recon.cc is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -424,16 +426,6 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu const int blurHeight = maxy - miny + 1; const int bufferWidth = blurWidth + ((16 - (blurWidth % 16)) & 15); - std::cout << "minx : " << minx << std::endl; - std::cout << "maxx : " << maxx << std::endl; - std::cout << "miny : " << miny << std::endl; - std::cout << "maxy : " << maxy << std::endl; - - std::cout << "blurWidth : " << blurWidth << std::endl; - std::cout << "bufferWidth : " << bufferWidth << std::endl; - - std::cout << "Corrected area reduced by factor: " << (((float)width * height) / (bufferWidth * blurHeight)) << std::endl; - std::cout << "Peak memory usage reduced from ~" << (30ul * ((size_t)width * (size_t)height)) / (1024*1024) << " Mb to ~" << (30ul * ((size_t)bufferWidth * (size_t)blurHeight)) / (1024*1024) << " Mb" << std::endl; multi_array2D channelblur(bufferWidth, blurHeight, 0, 48); array2D temp(bufferWidth, blurHeight); // allocate temporary buffer @@ -929,7 +921,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // now reconstruct clipped channels using color ratios -StopWatch Stop1("last loop"); + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -1113,7 +1105,6 @@ StopWatch Stop1("last loop"); } } } -std::cout << "progress : " << progress << std::endl; if (plistener) { plistener->setProgress(1.00); From 856b437983bbf26dea19a2f92989d898488715ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Wed, 10 Jul 2019 13:16:03 +0200 Subject: [PATCH 048/222] Some minor code cleanups --- rtengine/hilite_recon.cc | 423 ++++++++++++++++++++------------------- 1 file changed, 221 insertions(+), 202 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index a0a8cb83d..c6c540e10 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -7,7 +7,7 @@ // // // code dated: June 16, 2011 -// code dated: July 09. 2019, speedups by Ingo Weyrich +// code dated: July 09, 2019, speedups by Ingo Weyrich // // hilite_recon.cc is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,17 +25,20 @@ //////////////////////////////////////////////////////////////// #include - -#include #include +#include + #include "array2D.h" +#include "opthelper.h" #include "rawimagesource.h" #include "rt_math.h" -#include "opthelper.h" + #define BENCHMARK #include "StopWatch.h" -namespace { +namespace +{ + void boxblur2(const float* const* src, float** dst, float** temp, int startY, int startX, int H, int W, int bufferW, int box) { constexpr int numCols = 16; @@ -46,27 +49,24 @@ void boxblur2(const float* const* src, float** dst, float** temp, int startY, in #ifdef _OPENMP #pragma omp parallel for #endif - - for (int row = 0; row < H; row++) { + for (int row = 0; row < H; ++row) { int len = box + 1; temp[row][0] = src[row + startY][startX] / len; - for (int j = 1; j <= box; j++) { + for (int j = 1; j <= box; ++j) { temp[row][0] += src[row + startY][j + startX] / len; } - for (int col = 1; col <= box; col++) { + for (int col = 1; col <= box; ++col, ++len) { temp[row][col] = (temp[row][col - 1] * len + src[row + startY][col + box + startX]) / (len + 1); - len ++; } - for (int col = box + 1; col < W - box; col++) { + for (int col = box + 1; col < W - box; ++col) { temp[row][col] = temp[row][col - 1] + (src[row + startY][col + box + startX] - src[row + startY][col - box - 1 + startX]) / len; } - for (int col = W - box; col < W; col++) { + for (int col = W - box; col < W; ++col, --len) { temp[row][col] = (temp[row][col - 1] * len - src[row + startY][col - box - 1 + startX]) / (len - 1); - len --; } } @@ -81,45 +81,50 @@ void boxblur2(const float* const* src, float** dst, float** temp, int startY, in #endif for (int col = 0; col < bufferW - numCols + 1; col += numCols) { float len = box + 1; - for (int n = 0; n < numCols; n++) { + + for (int n = 0; n < numCols; ++n) { tempvalN[n] = temp[0][col + n] / len; } - for (int i = 1; i <= box; i++) { - for (int n = 0; n < numCols; n++) { + + for (int i = 1; i <= box; ++i) { + for (int n = 0; n < numCols; ++n) { tempvalN[n] += temp[i][col + n] / len; } } - for (int n = 0; n < numCols; n++) { + + for (int n = 0; n < numCols; ++n) { dst[0][col + n] = tempvalN[n]; } - for (int row = 1; row <= box; row++) { - for (int n = 0; n < numCols; n++) { + + for (int row = 1; row <= box; ++row, ++len) { + for (int n = 0; n < numCols; ++n) { tempvalN[n] = (tempvalN[n] * len + temp[(row + box)][col + n]) / (len + 1); dst[row][col + n] = tempvalN[n]; } - len ++; - } - const float rlen = 1.f / len; - for (int row = box + 1; row < H - box; row++) { - for (int n = 0; n < numCols; n++) { - tempvalN[n] = tempvalN[n] + (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; - dst[row][col + n] = tempvalN[n]; - } } - for (int row = H - box; row < H; row++) { - for (int n = 0; n < numCols; n++) { + const float rlen = 1.f / len; + + for (int row = box + 1; row < H - box; ++row) { + for (int n = 0; n < numCols; ++n) { + tempvalN[n] += (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; + dst[row][col + n] = tempvalN[n]; + } + } + + for (int row = H - box; row < H; ++row, --len) { + for (int n = 0; n < numCols; ++n) { tempvalN[n] = (dst[(row - 1)][col + n] * len - temp[(row - box - 1)][col + n]) / (len - 1); dst[row][col + n] = tempvalN[n]; } - len --; } } } } -void boxblur_resamp(const float * const *src, float **dst, float ** temp, int H, int W, int box, int samp ) +void boxblur_resamp(const float* const* src, float** dst, float** temp, int H, int W, int box, int samp) { + assert(samp != 0); #ifdef _OPENMP #pragma omp parallel @@ -128,33 +133,29 @@ void boxblur_resamp(const float * const *src, float **dst, float ** temp, int H, #ifdef _OPENMP #pragma omp for #endif - //box blur image channel; box size = 2*box+1 //horizontal blur - for (int row = 0; row < H; row++) - { + for (int row = 0; row < H; ++row) { int len = box + 1; float tempval = src[row][0] / len; - for (int j = 1; j <= box; j++) { + for (int j = 1; j <= box; ++j) { tempval += src[row][j] / len; } temp[row][0] = tempval; - for (int col = 1; col <= box; col++) { + for (int col = 1; col <= box; ++col, ++len) { tempval = (tempval * len + src[row][col + box]) / (len + 1); if (col % samp == 0) { temp[row][col / samp] = tempval; } - - len ++; } - float oneByLen = 1.f / (float)len; + const float oneByLen = 1.f / static_cast(len); - for (int col = box + 1; col < W - box; col++) { + for (int col = box + 1; col < W - box; ++col) { tempval = tempval + (src[row][col + box] - src[row][col - box - 1]) * oneByLen; if (col % samp == 0) { @@ -162,84 +163,81 @@ void boxblur_resamp(const float * const *src, float **dst, float ** temp, int H, } } - for (int col = W - box; col < W; col++) { + for (int col = W - box; col < W; ++col, --len) { tempval = (tempval * len - src[row][col - box - 1]) / (len - 1); if (col % samp == 0) { temp[row][col / samp] = tempval; } - - len --; } } } constexpr int numCols = 8; // process numCols columns at once for better L1 CPU cache usage + #ifdef _OPENMP #pragma omp parallel #endif { float tempvalN[numCols] ALIGNED64; + #ifdef _OPENMP #pragma omp for nowait #endif - //vertical blur for (int col = 0; col < (W / samp) - (numCols - 1); col += numCols) { float len = box + 1; - for (int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; ++n) { tempvalN[n] = temp[0][col + n] / len; } - for (int i = 1; i <= box; i++) { - for (int n = 0; n < numCols; n++) { + for (int i = 1; i <= box; ++i) { + for (int n = 0; n < numCols; ++n) { tempvalN[n] += temp[i][col + n] / len; } } - for (int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; ++n) { dst[0][col + n] = tempvalN[n]; } - for (int row = 1; row <= box; row++) { - for (int n = 0; n < numCols; n++) { + for (int row = 1; row <= box; ++row, ++len) { + for (int n = 0; n < numCols; ++n) { tempvalN[n] = (tempvalN[n] * len + temp[(row + box)][col + n]) / (len + 1); } if (row % samp == 0) { - for (int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; ++n) { dst[row / samp][col + n] = tempvalN[n]; } } - - len ++; } + const float rlen = 1.f / len; - for (int row = box + 1; row < H - box; row++) { - for (int n = 0; n < numCols; n++) { - tempvalN[n] = tempvalN[n] + (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; + + for (int row = box + 1; row < H - box; ++row) { + for (int n = 0; n < numCols; ++n) { + tempvalN[n] += (temp[(row + box)][col + n] - temp[(row - box - 1)][col + n]) * rlen; } if (row % samp == 0) { - for (int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; ++n) { dst[row / samp][col + n] = tempvalN[n]; } } } - for (int row = H - box; row < H; row++) { - for (int n = 0; n < numCols; n++) { + for (int row = H - box; row < H; ++row, --len) { + for (int n = 0; n < numCols; ++n) { tempvalN[n] = (tempvalN[n] * len - temp[(row - box - 1)][col + n]) / (len - 1); } if (row % samp == 0) { - for (int n = 0; n < numCols; n++) { + for (int n = 0; n < numCols; ++n) { dst[row / samp][col + n] = tempvalN[n]; } } - - len --; } } @@ -250,42 +248,38 @@ void boxblur_resamp(const float * const *src, float **dst, float ** temp, int H, { //vertical blur - for (int col = (W / samp) - ((W / samp) % numCols); col < W / samp; col++) { + for (int col = (W / samp) - ((W / samp) % numCols); col < W / samp; ++col) { int len = box + 1; float tempval = temp[0][col] / len; - for (int i = 1; i <= box; i++) { + for (int i = 1; i <= box; ++i) { tempval += temp[i][col] / len; } dst[0][col] = tempval; - for (int row = 1; row <= box; row++) { + for (int row = 1; row <= box; ++row, ++len) { tempval = (tempval * len + temp[(row + box)][col]) / (len + 1); if (row % samp == 0) { dst[row / samp][col] = tempval; } - - len ++; } - for (int row = box + 1; row < H - box; row++) { - tempval = tempval + (temp[(row + box)][col] - temp[(row - box - 1)][col]) / len; + for (int row = box + 1; row < H - box; ++row) { + tempval += (temp[(row + box)][col] - temp[(row - box - 1)][col]) / len; if (row % samp == 0) { dst[row / samp][col] = tempval; } } - for (int row = H - box; row < H; row++) { + for (int row = H - box; row < H; ++row, --len) { tempval = (tempval * len - temp[(row - box - 1)][col]) / (len - 1); if (row % samp == 0) { dst[row / samp][col] = tempval; } - - len --; } } } @@ -293,20 +287,20 @@ void boxblur_resamp(const float * const *src, float **dst, float ** temp, int H, } } + namespace rtengine { extern const Settings* settings; - -void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blue) +void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue) { BENCHFUN double progress = 0.0; if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_HLREC"); - plistener->setProgress (progress); + plistener->setProgressStr("PROGRESSBAR_HLREC"); + plistener->setProgress(progress); } const int height = H; @@ -321,29 +315,35 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu //%%%%%%%%%%%%%%%%%%%% //for blend algorithm: constexpr float blendthresh = 1.0; - constexpr int ColorCount = 3; // Transform matrixes rgb>lab and back - constexpr float trans[ColorCount][ColorCount] = - { { 1.f, 1.f, 1.f }, { 1.7320508f, -1.7320508f, 0.f }, { -1.f, -1.f, 2.f } }; - constexpr float itrans[ColorCount][ColorCount] = - { { 1.f, 0.8660254f, -0.5f }, { 1.f, -0.8660254f, -0.5f }, { 1.f, 0.f, 1.f } }; + constexpr float trans[3][3] = { + {1.f, 1.f, 1.f}, + {1.7320508f, -1.7320508f, 0.f}, + {-1.f, -1.f, 2.f} + }; + constexpr float itrans[3][3] = { + {1.f, 0.8660254f, -0.5f}, + {1.f, -0.8660254f, -0.5f}, + {1.f, 0.f, 1.f} + }; - if (settings->verbose) - for (int c = 0; c < 3; c++) { + if (settings->verbose) { + for (int c = 0; c < 3; ++c) { printf("chmax[%d] : %f\tclmax[%d] : %f\tratio[%d] : %f\n", c, chmax[c], c, clmax[c], c, chmax[c] / clmax[c]); } + } float factor[3]; - for (int c = 0; c < ColorCount; c++) { + for (int c = 0; c < 3; ++c) { factor[c] = chmax[c] / clmax[c]; } - float minFactor = min(factor[0], factor[1], factor[2]); + const float minFactor = min(factor[0], factor[1], factor[2]); if (minFactor > 1.f) { // all 3 channels clipped // calculate clip factor per channel - for (int c = 0; c < ColorCount; c++) { + for (int c = 0; c < 3; ++c) { factor[c] /= minFactor; } @@ -351,7 +351,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu int maxpos = 0; float maxValNew = 0.f; - for (int c = 0; c < ColorCount; c++) { + for (int c = 0; c < 3; ++c) { if (chmax[c] / factor[c] > maxValNew) { maxValNew = chmax[c] / factor[c]; maxpos = c; @@ -360,24 +360,26 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu const float clipFactor = clmax[maxpos] / maxValNew; - if (clipFactor < maxpct) - + if (clipFactor < maxpct) { // if max clipFactor < maxpct (0.95) adjust per channel factors - for (int c = 0; c < ColorCount; c++) { + for (int c = 0; c < 3; ++c) { factor[c] *= (maxpct / clipFactor); } + } } else { factor[0] = factor[1] = factor[2] = 1.f; } - if (settings->verbose) - for (int c = 0; c < ColorCount; c++) { + if (settings->verbose) { + for (int c = 0; c < 3; ++c) { printf("correction factor[%d] : %f\n", c, factor[c]); } + } - float max_f[3], thresh[3]; + float max_f[3]; + float thresh[3]; - for (int c = 0; c < ColorCount; c++) { + for (int c = 0; c < 3; ++c) { thresh[c] = chmax[c] * threshpct / factor[c]; max_f[c] = chmax[c] * maxpct / factor[c]; } @@ -386,11 +388,13 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu const float clippt = min(max_f[0], max_f[1], max_f[2]); const float medpt = max_f[0] + max_f[1] + max_f[2] - whitept - clippt; const float blendpt = blendthresh * clippt; + float medFactor[3]; - for (int c = 0; c < ColorCount; c++) { - medFactor[c] = max(1.0f, max_f[c] / medpt) / (-blendpt); + for (int c = 0; c < 3; ++c) { + medFactor[c] = max(1.0f, max_f[c] / medpt) / -blendpt; } + int minx = width - 1; int maxx = 0; int miny = height - 1; @@ -456,13 +460,13 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp parallel for #endif - - for (int i = 0; i < blurHeight; i++) - for (int j = 0; j < blurWidth; j++) { + for (int i = 0; i < blurHeight; ++i) { + for (int j = 0; j < blurWidth; ++j) { channelblur[0][i][j] = fabsf(channelblur[0][i][j] - red[i + miny][j + minx]) + fabsf(channelblur[1][i][j] - green[i + miny][j + minx]) + fabsf(channelblur[2][i][j] - blue[i + miny][j + minx]); } + } - for (int c = 1; c < 3; c++) { + for (int c = 1; c < 3; ++c) { channelblur[c].free(); //free up some memory } @@ -478,31 +482,36 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu plistener->setProgress(progress); } - double hipass_sum = 0.f; + double hipass_sum = 0.0; int hipass_norm = 0; // set up which pixels are clipped or near clipping #ifdef _OPENMP #pragma omp parallel for reduction(+:hipass_sum,hipass_norm) schedule(dynamic,16) #endif - - for (int i = 0; i < blurHeight; i++) { - for (int j = 0; j < blurWidth; j++) { - //if one or more channels is highlight but none are blown, add to highlight accumulator - if ((red[i + miny][j + minx] > thresh[0] || green[i + miny][j + minx] > thresh[1] || blue[i + miny][j + minx] > thresh[2]) && - (red[i + miny][j + minx] < max_f[0] && green[i + miny][j + minx] < max_f[1] && blue[i + miny][j + minx] < max_f[2])) { - + for (int i = 0; i < blurHeight; ++i) { + for (int j = 0; j < blurWidth; ++j) { + if ( + ( + red[i + miny][j + minx] > thresh[0] + || green[i + miny][j + minx] > thresh[1] + || blue[i + miny][j + minx] > thresh[2] + ) + && red[i + miny][j + minx] < max_f[0] + && green[i + miny][j + minx] < max_f[1] + && blue[i + miny][j + minx] < max_f[2] + ) { + // if one or more channels is highlight but none are blown, add to highlight accumulator hipass_sum += channelblur[0][i][j]; - hipass_norm ++; + ++hipass_norm; hilite_full[0][i][j] = red[i + miny][j + minx]; hilite_full[1][i][j] = green[i + miny][j + minx]; hilite_full[2][i][j] = blue[i + miny][j + minx]; hilite_full[3][i][j] = 1.f; - } } - }//end of filling highlight array + } const float hipass_ave = 2.f * hipass_sum / (hipass_norm + epsilon); @@ -526,9 +535,8 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - - for (int i = 0; i < blurHeight; i++) { - for (int j = 0; j < blurWidth; j++) { + for (int i = 0; i < blurHeight; ++i) { + for (int j = 0; j < blurWidth; ++j) { if (channelblur[0][i][j] > hipass_ave) { //too much variation hilite_full[0][i][j] = hilite_full[1][i][j] = hilite_full[2][i][j] = hilite_full[3][i][j] = 0.f; @@ -545,17 +553,17 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu channelblur[0].free(); //free up some memory hilite_full4.free(); //free up some memory - int hfh = (blurHeight - (blurHeight % pitch)) / pitch; - int hfw = (blurWidth - (blurWidth % pitch)) / pitch; + const int hfh = (blurHeight - blurHeight % pitch) / pitch; + const int hfw = (blurWidth - blurWidth % pitch) / pitch; multi_array2D hilite(hfw + 1, hfh + 1, ARRAY2D_CLEAR_DATA, 48); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // blur and resample highlight data; range=size of blur, pitch=sample spacing - array2D temp2((blurWidth / pitch) + ((blurWidth % pitch) == 0 ? 0 : 1), blurHeight); + array2D temp2(blurWidth / pitch + (blurWidth % pitch == 0 ? 0 : 1), blurHeight); - for (int m = 0; m < 4; m++) { + for (int m = 0; m < 4; ++m) { boxblur_resamp(hilite_full[m], hilite[m], temp2, blurHeight, blurWidth, range, pitch); if (plistener) { @@ -566,7 +574,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu temp2.free(); - for (int c = 0; c < 4; c++) { + for (int c = 0; c < 4; ++c) { hilite_full[c].free(); //free up some memory } @@ -582,8 +590,8 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu //fill gaps in highlight map by directional extension //raster scan from four corners - for (int j = 1; j < hfw - 1; j++) { - for (int i = 2; i < hfh - 2; i++) { + for (int j = 1; j < hfw - 1; ++j) { + for (int i = 2; i < hfh - 2; ++i) { //from left if (hilite[3][i][j] > epsilon) { hilite_dir0[3][j][i] = 1.f; @@ -609,7 +617,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } - for (int i = 2; i < hfh - 2; i++) { + for (int i = 2; i < hfh - 2; ++i) { if (hilite[3][i][hfw - 2] <= epsilon) { hilite_dir4[3][hfw - 1][i] = hilite_dir0[3][hfw - 2][i]; } @@ -622,10 +630,9 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp for nowait #endif - - for (int c = 0; c < 3; c++) { - for (int j = 1; j < hfw - 1; j++) { - for (int i = 2; i < hfh - 2; i++) { + for (int c = 0; c < 3; ++c) { + for (int j = 1; j < hfw - 1; ++j) { + for (int i = 2; i < hfh - 2; ++i) { //from left if (hilite[3][i][j] > epsilon) { hilite_dir0[c][j][i] = hilite[c][i][j] / hilite[3][i][j]; @@ -652,7 +659,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } - for (int i = 2; i < hfh - 2; i++) { + for (int i = 2; i < hfh - 2; ++i) { if (hilite[3][i][hfw - 2] <= epsilon) { hilite_dir4[c][hfw - 1][i] = hilite_dir0[c][hfw - 2][i]; } @@ -663,8 +670,8 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #pragma omp single #endif { - for (int j = hfw - 2; j > 0; j--) { - for (int i = 2; i < hfh - 2; i++) { + for (int j = hfw - 2; j > 0; --j) { + for (int i = 2; i < hfh - 2; ++i) { //from right if (hilite[3][i][j] > epsilon) { hilite_dir4[3][j][i] = 1.f; @@ -682,7 +689,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } - for (int i = 2; i < hfh - 2; i++) { + for (int i = 2; i < hfh - 2; ++i) { if (hilite[3][i][0] <= epsilon) { hilite_dir[0 + 3][i - 2][0] += hilite_dir4[3][0][i]; hilite_dir[4 + 3][i + 2][0] += hilite_dir4[3][0][i]; @@ -712,10 +719,9 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp for nowait #endif - - for (int c = 0; c < 3; c++) { - for (int j = hfw - 2; j > 0; j--) { - for (int i = 2; i < hfh - 2; i++) { + for (int c = 0; c < 3; ++c) { + for (int j = hfw - 2; j > 0; --j) { + for (int i = 2; i < hfh - 2; ++i) { //from right if (hilite[3][i][j] > epsilon) { hilite_dir4[c][j][i] = hilite[c][i][j] / hilite[3][i][j]; @@ -734,7 +740,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } - for (int i = 2; i < hfh - 2; i++) { + for (int i = 2; i < hfh - 2; ++i) { if (hilite[3][i][0] <= epsilon) { hilite_dir[0 + c][i - 2][0] += hilite_dir4[c][0][i]; hilite_dir[4 + c][i + 2][0] += hilite_dir4[c][0][i]; @@ -756,8 +762,8 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #pragma omp single #endif { - for (int i = 1; i < hfh - 1; i++) - for (int j = 2; j < hfw - 2; j++) { + for (int i = 1; i < hfh - 1; ++i) + for (int j = 2; j < hfw - 2; ++j) { //from top if (hilite[3][i][j] > epsilon) { hilite_dir[0 + 3][i][j] = 1.f; @@ -766,7 +772,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } - for (int j = 2; j < hfw - 2; j++) { + for (int j = 2; j < hfw - 2; ++j) { if (hilite[3][hfh - 2][j] <= epsilon) { hilite_dir[4 + 3][hfh - 1][j] += hilite_dir[0 + 3][hfh - 2][j]; } @@ -785,10 +791,9 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp for nowait #endif - - for (int c = 0; c < 3; c++) { - for (int i = 1; i < hfh - 1; i++) { - for (int j = 2; j < hfw - 2; j++) { + for (int c = 0; c < 3; ++c) { + for (int i = 1; i < hfh - 1; ++i) { + for (int j = 2; j < hfw - 2; ++j) { //from top if (hilite[3][i][j] > epsilon) { hilite_dir[0 + c][i][j] = hilite[c][i][j] / hilite[3][i][j]; @@ -799,7 +804,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } - for (int j = 2; j < hfw - 2; j++) { + for (int j = 2; j < hfw - 2; ++j) { if (hilite[3][hfh - 2][j] <= epsilon) { hilite_dir[4 + c][hfh - 1][j] += hilite_dir[0 + c][hfh - 2][j]; } @@ -810,8 +815,8 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp single #endif - for (int i = hfh - 2; i > 0; i--) - for (int j = 2; j < hfw - 2; j++) { + for (int i = hfh - 2; i > 0; --i) { + for (int j = 2; j < hfw - 2; ++j) { //from bottom if (hilite[3][i][j] > epsilon) { hilite_dir[4 + 3][i][j] = 1.f; @@ -820,6 +825,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } } + } if (plistener) { progress += 0.05; @@ -829,10 +835,9 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp parallel for #endif - - for (int c = 0; c < 4; c++) { - for (int i = hfh - 2; i > 0; i--) { - for (int j = 2; j < hfw - 2; j++) { + for (int c = 0; c < 4; ++c) { + for (int i = hfh - 2; i > 0; --i) { + for (int j = 2; j < hfw - 2; ++j) { //from bottom if (hilite[3][i][j] > epsilon) { hilite_dir[4 + c][i][j] = hilite[c][i][j] / hilite[3][i][j]; @@ -850,20 +855,22 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } //fill in edges - for (int dir = 0; dir < 2; dir++) { - for (int i = 1; i < hfh - 1; i++) - for (int c = 0; c < 4; c++) { + for (int dir = 0; dir < 2; ++dir) { + for (int i = 1; i < hfh - 1; ++i) { + for (int c = 0; c < 4; ++c) { hilite_dir[dir * 4 + c][i][0] = hilite_dir[dir * 4 + c][i][1]; hilite_dir[dir * 4 + c][i][hfw - 1] = hilite_dir[dir * 4 + c][i][hfw - 2]; } + } - for (int j = 1; j < hfw - 1; j++) - for (int c = 0; c < 4; c++) { + for (int j = 1; j < hfw - 1; ++j) { + for (int c = 0; c < 4; ++c) { hilite_dir[dir * 4 + c][0][j] = hilite_dir[dir * 4 + c][1][j]; hilite_dir[dir * 4 + c][hfh - 1][j] = hilite_dir[dir * 4 + c][hfh - 2][j]; } + } - for (int c = 0; c < 4; c++) { + for (int c = 0; c < 4; ++c) { hilite_dir[dir * 4 + c][0][0] = hilite_dir[dir * 4 + c][1][0] = hilite_dir[dir * 4 + c][0][1] = hilite_dir[dir * 4 + c][1][1] = hilite_dir[dir * 4 + c][2][2]; hilite_dir[dir * 4 + c][0][hfw - 1] = hilite_dir[dir * 4 + c][1][hfw - 1] = hilite_dir[dir * 4 + c][0][hfw - 2] = hilite_dir[dir * 4 + c][1][hfw - 2] = hilite_dir[dir * 4 + c][2][hfw - 3]; hilite_dir[dir * 4 + c][hfh - 1][0] = hilite_dir[dir * 4 + c][hfh - 2][0] = hilite_dir[dir * 4 + c][hfh - 1][1] = hilite_dir[dir * 4 + c][hfh - 2][1] = hilite_dir[dir * 4 + c][hfh - 3][2]; @@ -871,38 +878,42 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } } - for (int i = 1; i < hfh - 1; i++) - for (int c = 0; c < 4; c++) { + for (int i = 1; i < hfh - 1; ++i) { + for (int c = 0; c < 4; ++c) { hilite_dir0[c][0][i] = hilite_dir0[c][1][i]; hilite_dir0[c][hfw - 1][i] = hilite_dir0[c][hfw - 2][i]; } + } - for (int j = 1; j < hfw - 1; j++) - for (int c = 0; c < 4; c++) { + for (int j = 1; j < hfw - 1; ++j) { + for (int c = 0; c < 4; ++c) { hilite_dir0[c][j][0] = hilite_dir0[c][j][1]; hilite_dir0[c][j][hfh - 1] = hilite_dir0[c][j][hfh - 2]; } + } - for (int c = 0; c < 4; c++) { + for (int c = 0; c < 4; ++c) { hilite_dir0[c][0][0] = hilite_dir0[c][0][1] = hilite_dir0[c][1][0] = hilite_dir0[c][1][1] = hilite_dir0[c][2][2]; hilite_dir0[c][hfw - 1][0] = hilite_dir0[c][hfw - 1][1] = hilite_dir0[c][hfw - 2][0] = hilite_dir0[c][hfw - 2][1] = hilite_dir0[c][hfw - 3][2]; hilite_dir0[c][0][hfh - 1] = hilite_dir0[c][0][hfh - 2] = hilite_dir0[c][1][hfh - 1] = hilite_dir0[c][1][hfh - 2] = hilite_dir0[c][2][hfh - 3]; hilite_dir0[c][hfw - 1][hfh - 1] = hilite_dir0[c][hfw - 1][hfh - 2] = hilite_dir0[c][hfw - 2][hfh - 1] = hilite_dir0[c][hfw - 2][hfh - 2] = hilite_dir0[c][hfw - 3][hfh - 3]; } - for (int i = 1; i < hfh - 1; i++) - for (int c = 0; c < 4; c++) { + for (int i = 1; i < hfh - 1; ++i) { + for (int c = 0; c < 4; ++c) { hilite_dir4[c][0][i] = hilite_dir4[c][1][i]; hilite_dir4[c][hfw - 1][i] = hilite_dir4[c][hfw - 2][i]; } + } - for (int j = 1; j < hfw - 1; j++) - for (int c = 0; c < 4; c++) { + for (int j = 1; j < hfw - 1; ++j) { + for (int c = 0; c < 4; ++c) { hilite_dir4[c][j][0] = hilite_dir4[c][j][1]; hilite_dir4[c][j][hfh - 1] = hilite_dir4[c][j][hfh - 2]; } + } - for (int c = 0; c < 4; c++) { + for (int c = 0; c < 4; ++c) { hilite_dir4[c][0][0] = hilite_dir4[c][0][1] = hilite_dir4[c][1][0] = hilite_dir4[c][1][1] = hilite_dir4[c][2][2]; hilite_dir4[c][hfw - 1][0] = hilite_dir4[c][hfw - 1][1] = hilite_dir4[c][hfw - 2][0] = hilite_dir4[c][hfw - 2][1] = hilite_dir4[c][hfw - 3][2]; hilite_dir4[c][0][hfh - 1] = hilite_dir4[c][0][hfh - 2] = hilite_dir4[c][1][hfh - 1] = hilite_dir4[c][1][hfh - 2] = hilite_dir4[c][2][hfh - 3]; @@ -915,7 +926,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu } //free up some memory - for (int c = 0; c < 4; c++) { + for (int c = 0; c < 4; ++c) { hilite[c].free(); } @@ -925,47 +936,52 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif + for (int i = 0; i < blurHeight; ++i) { + const int i1 = min((i - i % pitch) / pitch, hfh - 1); - for (int i = 0; i < blurHeight; i++) { - const int i1 = min((i - (i % pitch)) / pitch, hfh - 1); - - for (int j = 0; j < blurWidth; j++) { - - const float pixel[3] = {red[i + miny][j + minx], green[i + miny][j + minx], blue[i + miny][j + minx]}; + for (int j = 0; j < blurWidth; ++j) { + const float pixel[3] = { + red[i + miny][j + minx], + green[i + miny][j + minx], + blue[i + miny][j + minx] + }; if (pixel[0] < max_f[0] && pixel[1] < max_f[1] && pixel[2] < max_f[2]) { continue; //pixel not clipped } - const int j1 = min((j - (j % pitch)) / pitch, hfw - 1); + const int j1 = min((j - j % pitch) / pitch, hfw - 1); //estimate recovered values using modified HLRecovery_blend algorithm - float rgb[ColorCount], rgb_blend[ColorCount] = {}, cam[2][ColorCount], lab[2][ColorCount], sum[2]; - - // Copy input pixel to rgb so it's easier to access in loops - rgb[0] = pixel[0]; - rgb[1] = pixel[1]; - rgb[2] = pixel[2]; + float rgb[3] = { + pixel[0], + pixel[1], + pixel[2] + };// Copy input pixel to rgb so it's easier to access in loops + float rgb_blend[3] = {}; + float cam[2][3]; + float lab[2][3]; + float sum[2]; // Initialize cam with raw input [0] and potentially clipped input [1] - for (int c = 0; c < ColorCount; c++) { + for (int c = 0; c < 3; ++c) { cam[0][c] = rgb[c]; cam[1][c] = min(cam[0][c], clippt); } // Calculate the lightness correction ratio (chratio) - for (int i2 = 0; i2 < 2; i2++) { - for (int c = 0; c < ColorCount; c++) { + for (int i2 = 0; i2 < 2; ++i2) { + for (int c = 0; c < 3; ++c) { lab[i2][c] = 0; - for (int j = 0; j < ColorCount; j++) { + for (int j = 0; j < 3; ++j) { lab[i2][c] += trans[c][j] * cam[i2][j]; } } sum[i2] = 0.f; - for (int c = 1; c < ColorCount; c++) { + for (int c = 1; c < 3; ++c) { sum[i2] += SQR(lab[i2][c]); } } @@ -976,36 +992,36 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu const float chratio = sqrtf(sum[1] / sum[0]); // Apply ratio to lightness in lab space - for (int c = 1; c < ColorCount; c++) { + for (int c = 1; c < 3; ++c) { lab[0][c] *= chratio; } // Transform back from lab to RGB - for (int c = 0; c < ColorCount; c++) { - cam[0][c] = 0; + for (int c = 0; c < 3; ++c) { + cam[0][c] = 0.f; - for (int j = 0; j < ColorCount; j++) { + for (int j = 0; j < 3; ++j) { cam[0][c] += itrans[c][j] * lab[0][j]; } } - for (int c = 0; c < ColorCount; c++) { - rgb[c] = cam[0][c] / ColorCount; + for (int c = 0; c < 3; ++c) { + rgb[c] = cam[0][c] / 3; } // Copy converted pixel back if (pixel[0] > blendpt) { - const float rfrac = max(0.f, min(1.f, medFactor[0] * (pixel[0] - blendpt))); + const float rfrac = LIM01(medFactor[0] * (pixel[0] - blendpt)); rgb_blend[0] = rfrac * rgb[0] + (1.f - rfrac) * pixel[0]; } if (pixel[1] > blendpt) { - const float gfrac = max(0.f, min(1.f, medFactor[1] * (pixel[1] - blendpt))); + const float gfrac = LIM01(medFactor[1] * (pixel[1] - blendpt)); rgb_blend[1] = gfrac * rgb[1] + (1.f - gfrac) * pixel[1]; } if (pixel[2] > blendpt) { - const float bfrac = max(0.f, min(1.f, medFactor[2] * (pixel[2] - blendpt))); + const float bfrac = LIM01(medFactor[2] * (pixel[2] - blendpt)); rgb_blend[2] = bfrac * rgb[2] + (1.f - bfrac) * pixel[2]; } @@ -1019,7 +1035,7 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu float Y = epsilon + rgb_blend[0] + rgb_blend[1] + rgb_blend[2]; - for (int c = 0; c < ColorCount; c++) { + for (int c = 0; c < 3; ++c) { rgb_blend[c] /= Y; } @@ -1035,13 +1051,13 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu clipfix[2] = dirwt * hilite_dir0[2][j1][i1]; } - for (int dir = 0; dir < 2; dir++) { - const float Yhi = 1.f / ( hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]); + for (int dir = 0; dir < 2; ++dir) { + const float Yhi2 = 1.f / ( hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]); - if (Yhi < 2.f) { - const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir[dir * 4 + 0][i1][j1] * Yhi) + - SQR(rgb_blend[1] - hilite_dir[dir * 4 + 1][i1][j1] * Yhi) + - SQR(rgb_blend[2] - hilite_dir[dir * 4 + 2][i1][j1] * Yhi))) * (hilite_dir[dir * 4 + 3][i1][j1] + epsilon)); + if (Yhi2 < 2.f) { + const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir[dir * 4 + 0][i1][j1] * Yhi2) + + SQR(rgb_blend[1] - hilite_dir[dir * 4 + 1][i1][j1] * Yhi2) + + SQR(rgb_blend[2] - hilite_dir[dir * 4 + 2][i1][j1] * Yhi2))) * (hilite_dir[dir * 4 + 3][i1][j1] + epsilon)); totwt = true; clipfix[0] += dirwt * hilite_dir[dir * 4 + 0][i1][j1]; clipfix[1] += dirwt * hilite_dir[dir * 4 + 1][i1][j1]; @@ -1076,7 +1092,11 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu green[i + miny][j + minx] = clipfix[1] * factor; blue[i + miny][j + minx] = clipfix[2] * factor; } else {//some channels clipped - const float notclipped[3] = {pixel[0] <= max_f[0] ? 1.f : 0.f, pixel[1] <= max_f[1] ? 1.f : 0.f, pixel[2] <= max_f[2] ? 1.f : 0.f}; + const float notclipped[3] = { + pixel[0] <= max_f[0] ? 1.f : 0.f, + pixel[1] <= max_f[1] ? 1.f : 0.f, + pixel[2] <= max_f[2] ? 1.f : 0.f + }; if (notclipped[0] == 0.f) { //red clipped red[i + miny][j + minx] = max(pixel[0], clipfix[0] * ((notclipped[1] * pixel[1] + notclipped[2] * pixel[2]) / @@ -1112,6 +1132,5 @@ void RawImageSource::HLRecovery_inpaint (float** red, float** green, float** blu }// end of HLReconstruction - } From 494aa99323086517a40e1618d7dc76eb46d890ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 12 Jul 2019 08:10:30 +0200 Subject: [PATCH 049/222] Fix missing include guards --- rtengine/dfmanager.h | 10 +++++++--- rtengine/ffmanager.h | 10 +++++++--- rtengine/iccjpeg.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h index 2e55c3c22..541981492 100644 --- a/rtengine/dfmanager.h +++ b/rtengine/dfmanager.h @@ -16,10 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include -#include -#include +#pragma once + #include +#include +#include + +#include + #include "pixelsmap.h" #include "rawimage.h" diff --git a/rtengine/ffmanager.h b/rtengine/ffmanager.h index 9068216ef..43fb2f368 100644 --- a/rtengine/ffmanager.h +++ b/rtengine/ffmanager.h @@ -16,10 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include -#include -#include +#pragma once + #include +#include +#include + +#include + #include "rawimage.h" namespace rtengine diff --git a/rtengine/iccjpeg.h b/rtengine/iccjpeg.h index ce715948d..5197d1602 100644 --- a/rtengine/iccjpeg.h +++ b/rtengine/iccjpeg.h @@ -15,6 +15,7 @@ * with ICC profiles exceeding 64K bytes in size. See iccprofile.c * for details. */ +#pragma once #include /* needed to define "FILE", "NULL" */ #include "jpeglib.h" From 7257aee2351a71e768ab3cb4b94f75952ec181f5 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 12 Jul 2019 12:56:47 +0200 Subject: [PATCH 050/222] DCPStore: use std::string instead of slow Glib::ustring --- rtengine/dcp.cc | 28 +++++++++++----------------- rtengine/dcp.h | 4 ++-- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 1c99b682c..56855b604 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -1833,8 +1833,7 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) && lastdot <= sname.size() - 4 && !sname.casefold().compare(lastdot, 4, ".dcp") ) { - const Glib::ustring cam_short_name = sname.substr(0, lastdot).uppercase(); - file_std_profiles[cam_short_name] = fname; // They will be loaded and cached on demand + file_std_profiles[sname.substr(0, lastdot).casefold_collate_key()] = fname; // They will be loaded and cached on demand } } else { // Directory @@ -1845,11 +1844,10 @@ void DCPStore::init(const Glib::ustring& rt_profile_dir, bool loadAll) for (const auto& alias : getAliases(rt_profile_dir)) { const Glib::ustring alias_name = Glib::ustring(alias.first).uppercase(); - const Glib::ustring real_name = Glib::ustring(alias.second).uppercase(); - const std::map::const_iterator real = file_std_profiles.find(real_name); + const std::map::const_iterator real = file_std_profiles.find(Glib::ustring(alias.second).casefold_collate_key()); if (real != file_std_profiles.end()) { - file_std_profiles[alias_name] = real->second; + file_std_profiles[alias_name.casefold_collate_key()] = real->second; } } } @@ -1871,19 +1869,19 @@ bool DCPStore::isValidDCPFileName(const Glib::ustring& filename) const DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const { + const auto key = filename.casefold_collate_key(); MyMutex::MyLock lock(mutex); + const std::map::const_iterator iter = profile_cache.find(key); - const std::map::iterator r = profile_cache.find(filename); - - if (r != profile_cache.end()) { - return r->second; + if (iter != profile_cache.end()) { + return iter->second; } DCPProfile* const res = new DCPProfile(filename); if (res->isValid()) { // Add profile - profile_cache[filename] = res; + profile_cache[key] = res; if (options.rtSettings.verbose) { printf("DCP profile '%s' loaded from disk\n", filename.c_str()); } @@ -1896,13 +1894,9 @@ DCPProfile* DCPStore::getProfile(const Glib::ustring& filename) const DCPProfile* DCPStore::getStdProfile(const Glib::ustring& requested_cam_short_name) const { - const Glib::ustring name = requested_cam_short_name.uppercase(); - - // Warning: do NOT use map.find(), since it does not seem to work reliably here - for (const auto& file_std_profile : file_std_profiles) { - if (file_std_profile.first == name) { - return getProfile(file_std_profile.second); - } + const std::map::const_iterator iter = file_std_profiles.find(requested_cam_short_name.casefold_collate_key()); + if (iter != file_std_profiles.end()) { + return getProfile(iter->second); } // profile not found, looking if we're in loadAll=false mode diff --git a/rtengine/dcp.h b/rtengine/dcp.h index dc6915d26..48b881661 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -169,10 +169,10 @@ private: std::vector profileDir; // these contain standard profiles from RT. keys are all in uppercase, file path is value - std::map file_std_profiles; + std::map file_std_profiles; // Maps file name to profile as cache - mutable std::map profile_cache; + mutable std::map profile_cache; }; } From d1c9a5f989629700f3fefa8aeb872f3cafbb54cc Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 12 Jul 2019 13:46:45 +0200 Subject: [PATCH 051/222] Removed timing code --- rtengine/hilite_recon.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index c6c540e10..b0a7e6229 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -33,9 +33,6 @@ #include "rawimagesource.h" #include "rt_math.h" -#define BENCHMARK -#include "StopWatch.h" - namespace { @@ -295,7 +292,6 @@ extern const Settings* settings; void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue) { - BENCHFUN double progress = 0.0; if (plistener) { From 72ae120bd101f636d301676503dbf2fd10f6c20c Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 14 Jul 2019 15:03:08 +0200 Subject: [PATCH 052/222] FileCatalog::reparseDirectory(): speedup --- rtgui/filecatalog.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index fcccaac3a..f00c50f3d 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -37,6 +37,9 @@ #include "batchqueue.h" #include "placesbrowser.h" +#define BENCHMARK +#include "../rtengine/StopWatch.h" + using namespace std; #define CHECKTIME 2000 @@ -1672,7 +1675,7 @@ void FileCatalog::filterChanged () void FileCatalog::reparseDirectory () { - +BENCHFUN if (selectedDirectory.empty()) { return; } @@ -1704,17 +1707,15 @@ void FileCatalog::reparseDirectory () } // check if a new file has been added + // build a set of collate-keys for faster search + std::set oldNames; + for (size_t j = 0; j < fileNameList.size(); j++) { + oldNames.insert(fileNameList[j].collate_key()); + } + for (size_t i = 0; i < nfileNameList.size(); i++) { - bool found = false; - - for (size_t j = 0; j < fileNameList.size(); j++) - if (nfileNameList[i] == fileNameList[j]) { - found = true; - break; - } - - if (!found) { - checkAndAddFile (Gio::File::create_for_parse_name (nfileNameList[i])); + if (oldNames.count(nfileNameList[i].collate_key()) == 0) { + checkAndAddFile (Gio::File::create_for_parse_name(nfileNameList[i])); _refreshProgressBar (); } } From 67e94e41c8f4435893d1b6405041c9a522594706 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 14 Jul 2019 15:23:28 +0200 Subject: [PATCH 053/222] FileCatalog::getFileList(): speedup --- rtgui/filecatalog.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index f00c50f3d..8070adc27 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -566,44 +566,44 @@ void FileCatalog::closeDir () redrawAll (); } -std::vector FileCatalog::getFileList () +std::vector FileCatalog::getFileList() { + BENCHFUN std::vector names; - std::set extensions; + std::set extensions; for (const auto& parsedExt : options.parsedExtensions) { - extensions.emplace (parsedExt.lowercase ()); + extensions.emplace(parsedExt.lowercase()); } try { - auto dir = Gio::File::create_for_path (selectedDirectory); + const auto dir = Gio::File::create_for_path(selectedDirectory); - auto enumerator = dir->enumerate_children ("standard::name"); + auto enumerator = dir->enumerate_children("standard::name"); while (true) { try { - auto file = enumerator->next_file (); + const auto file = enumerator->next_file(); if (!file) { break; } - const Glib::ustring fname = file->get_name (); + const Glib::ustring fname = file->get_name(); - auto lastdot = fname.find_last_of ('.'); + const auto lastdot = fname.find_last_of ('.'); if (lastdot >= fname.length () - 1) { continue; } - const auto fext = fname.substr (lastdot + 1).lowercase (); - if (extensions.count (fext) == 0) { + if (extensions.count(fname.substr(lastdot + 1).lowercase()) == 0) { continue; } - names.emplace_back (Glib::build_filename (selectedDirectory, fname)); + names.emplace_back(Glib::build_filename(selectedDirectory, fname)); } catch (Glib::Exception& exception) { if (options.rtSettings.verbose) { - std::cerr << exception.what () << std::endl; + std::cerr << exception.what() << std::endl; } } } From 42a9d8d404297307223dcee2ec47f791fbe67528 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 15 Jul 2019 21:43:51 +0200 Subject: [PATCH 054/222] Added a space to test LGTM --- rtgui/filebrowser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index b208a854d..60cf639ee 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -38,7 +38,7 @@ class FileBrowserEntry; class FileBrowserListener { public: - virtual ~FileBrowserListener() = default; + virtual ~FileBrowserListener() = default; virtual void filterApplied() = 0; virtual void openRequested(const std::vector& tbe) = 0; virtual void developRequested(const std::vector& tbe, bool fastmode) = 0; From 3130fe7ca30bcae1cce060fb743fac6176dbb0bc Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 15 Jul 2019 23:50:03 +0200 Subject: [PATCH 055/222] Remove the space I added with last commit to test LGTM --- rtgui/filebrowser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index 60cf639ee..b208a854d 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -38,7 +38,7 @@ class FileBrowserEntry; class FileBrowserListener { public: - virtual ~FileBrowserListener() = default; + virtual ~FileBrowserListener() = default; virtual void filterApplied() = 0; virtual void openRequested(const std::vector& tbe) = 0; virtual void developRequested(const std::vector& tbe, bool fastmode) = 0; From d68b33effcd4d999fc32eeef1ae448bfd6420cc8 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 16 Jul 2019 20:07:29 +0200 Subject: [PATCH 056/222] filecatalog: further speedups; also remember last copy/move destination --- rtgui/filecatalog.cc | 214 +++++++++++++++++++------------------------ rtgui/filecatalog.h | 2 +- rtgui/options.cc | 33 ++----- rtgui/options.h | 7 +- 4 files changed, 112 insertions(+), 144 deletions(-) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 8070adc27..57555fd76 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -571,16 +571,13 @@ std::vector FileCatalog::getFileList() BENCHFUN std::vector names; - std::set extensions; - for (const auto& parsedExt : options.parsedExtensions) { - extensions.emplace(parsedExt.lowercase()); - } + const std::set& extensions = options.parsedExtensionsSet; try { const auto dir = Gio::File::create_for_path(selectedDirectory); - auto enumerator = dir->enumerate_children("standard::name"); + auto enumerator = dir->enumerate_children("standard::name,standard::type,standard::is-hidden"); while (true) { try { @@ -589,18 +586,26 @@ std::vector FileCatalog::getFileList() break; } + if (file->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { + continue; + } + + if (!options.fbShowHidden && file->is_hidden()) { + continue; + } + const Glib::ustring fname = file->get_name(); + const auto lastdot = fname.find_last_of('.'); - const auto lastdot = fname.find_last_of ('.'); - if (lastdot >= fname.length () - 1) { + if (lastdot >= fname.length() - 1) { continue; } - if (extensions.count(fname.substr(lastdot + 1).lowercase()) == 0) { + if (extensions.find(fname.substr(lastdot + 1).lowercase()) == extensions.end()) { continue; } - names.emplace_back(Glib::build_filename(selectedDirectory, fname)); + names.push_back(Glib::build_filename(selectedDirectory, fname)); } catch (Glib::Exception& exception) { if (options.rtSettings.verbose) { std::cerr << exception.what() << std::endl; @@ -621,7 +626,7 @@ std::vector FileCatalog::getFileList() void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { - +BENCHFUN try { Glib::RefPtr dir = Gio::File::create_for_path (dirname); @@ -629,7 +634,7 @@ void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring return; } - closeDir (); + closeDir(); previewsToLoad = 0; previewsLoaded = 0; @@ -639,16 +644,14 @@ void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring } selectedDirectory = dir->get_parse_name(); - //printf("FileCatalog::dirSelected selectedDirectory = %s\n",selectedDirectory.c_str()); - BrowsePath->set_text (selectedDirectory); - buttonBrowsePath->set_image (*iRefreshWhite); - fileNameList = getFileList (); + + BrowsePath->set_text(selectedDirectory); + buttonBrowsePath->set_image(*iRefreshWhite); + fileNameList = getFileList(); for (unsigned int i = 0; i < fileNameList.size(); i++) { - Glib::RefPtr f = Gio::File::create_for_path(fileNameList[i]); - - if (f->get_parse_name() != openfile) { // if we opened a file at the beginning don't add it again - checkAndAddFile (f); + if (openfile.empty() || fileNameList[i] != openfile) { // if we opened a file at the beginning don't add it again + addFile(fileNameList[i]); } } @@ -699,34 +702,33 @@ void FileCatalog::_refreshProgressBar () // In tab mode, no progress bar at all // Also mention that this progress bar only measures the FIRST pass (quick thumbnails) // The second, usually longer pass is done multithreaded down in the single entries and is NOT measured by this - if (!inTabMode) { + if (!inTabMode && (!previewsToLoad || std::floor(100.f * previewsLoaded / previewsToLoad) != std::floor(100.f * (previewsLoaded - 1) / previewsToLoad))) { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected - Gtk::Notebook *nb = (Gtk::Notebook *)(filepanel->get_parent()); - Gtk::Grid* grid = Gtk::manage (new Gtk::Grid ()); + Gtk::Grid* grid = Gtk::manage(new Gtk::Grid()); Gtk::Label *label = nullptr; - if (!previewsToLoad ) { - grid->attach_next_to(*Gtk::manage (new RTImage ("folder-closed.png")), options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT, 1, 1); + if (!previewsToLoad) { + grid->attach_next_to(*Gtk::manage(new RTImage("folder-closed.png")), options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT, 1, 1); int filteredCount = min(fileBrowser->getNumFiltered(), previewsLoaded); - label = Gtk::manage (new Gtk::Label (M("MAIN_FRAME_FILEBROWSER") + - (filteredCount != previewsLoaded ? " [" + Glib::ustring::format(filteredCount) + "/" : " (") - + Glib::ustring::format(previewsLoaded) + - (filteredCount != previewsLoaded ? "]" : ")"))); + label = Gtk::manage(new Gtk::Label(M("MAIN_FRAME_FILEBROWSER") + + (filteredCount != previewsLoaded ? " [" + Glib::ustring::format(filteredCount) + "/" : " (") + + Glib::ustring::format(previewsLoaded) + + (filteredCount != previewsLoaded ? "]" : ")"))); } else { - grid->attach_next_to(*Gtk::manage (new RTImage ("magnifier.png")), options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT, 1, 1); - label = Gtk::manage (new Gtk::Label (M("MAIN_FRAME_FILEBROWSER") + " [" + Glib::ustring::format(std::fixed, std::setprecision(0), std::setw(3), (double)previewsLoaded / previewsToLoad * 100 ) + "%]" )); + grid->attach_next_to(*Gtk::manage(new RTImage("magnifier.png")), options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT, 1, 1); + label = Gtk::manage(new Gtk::Label(M("MAIN_FRAME_FILEBROWSER") + " [" + Glib::ustring::format(std::fixed, std::setprecision(0), std::setw(3), (double)previewsLoaded / previewsToLoad * 100 ) + "%]" )); filepanel->loadingThumbs("", (double)previewsLoaded / previewsToLoad); } - if( options.mainNBVertical ) { + if (options.mainNBVertical) { label->set_angle(90); } grid->attach_next_to(*label, options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT, 1, 1); - grid->set_tooltip_markup (M("MAIN_FRAME_FILEBROWSER_TOOLTIP")); - grid->show_all (); + grid->set_tooltip_markup(M("MAIN_FRAME_FILEBROWSER_TOOLTIP")); + grid->show_all(); if (nb) { nb->set_tab_label(*filepanel, *grid); @@ -1008,12 +1010,16 @@ void FileCatalog::copyMoveRequested(const std::vector& tbe, b Gtk::FileChooserDialog fc (getToplevelWindow (this), fc_title, Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER ); fc.add_button( M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); fc.add_button( M("GENERAL_OK"), Gtk::RESPONSE_OK); - // open dialog at the 1-st file's path - fc.set_filename(tbe[0]->filename); + if (!options.lastCopyMovePath.empty() && Glib::file_test(options.lastCopyMovePath, Glib::FILE_TEST_IS_DIR)) { + fc.set_current_folder(options.lastCopyMovePath); + } else { + // open dialog at the 1-st file's path + fc.set_current_folder(Glib::path_get_dirname(tbe[0]->filename)); + } //!!! TODO prevent dialog closing on "enter" key press if( fc.run() == Gtk::RESPONSE_OK ) { - Glib::ustring dest_Dir = fc.get_current_folder(); + options.lastCopyMovePath = fc.get_current_folder(); // iterate through selected files for (unsigned int i = 0; i < tbe.size(); i++) { @@ -1030,10 +1036,10 @@ void FileCatalog::copyMoveRequested(const std::vector& tbe, b Glib::ustring fname_Ext = getExtension(fname); // construct destination File Paths - Glib::ustring dest_fPath = Glib::build_filename (dest_Dir, fname); + Glib::ustring dest_fPath = Glib::build_filename (options.lastCopyMovePath, fname); Glib::ustring dest_fPath_param = dest_fPath + paramFileExtension; - if (moveRequested && (src_Dir == dest_Dir)) { + if (moveRequested && (src_Dir == options.lastCopyMovePath)) { continue; } @@ -1088,7 +1094,7 @@ void FileCatalog::copyMoveRequested(const std::vector& tbe, b // adjust destination fname to avoid conflicts (append "_", preserve extension) Glib::ustring dest_fname = Glib::ustring::compose("%1%2%3%4%5", fname_noExt, "_", i_copyindex, ".", fname_Ext); // re-construct destination File Paths - dest_fPath = Glib::build_filename (dest_Dir, dest_fname); + dest_fPath = Glib::build_filename (options.lastCopyMovePath, dest_fname); dest_fPath_param = dest_fPath + paramFileExtension; i_copyindex++; } @@ -1680,47 +1686,46 @@ BENCHFUN return; } - if (!Glib::file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) { - closeDir (); + if (!Glib::file_test(selectedDirectory, Glib::FILE_TEST_IS_DIR)) { + closeDir(); return; } - std::vector nfileNameList = getFileList (); - // check if a thumbnailed file has been deleted - const std::vector& t = fileBrowser->getEntries (); + const std::vector& t = fileBrowser->getEntries(); std::vector fileNamesToDel; - for (size_t i = 0; i < t.size(); i++) - if (!Glib::file_test (t[i]->filename, Glib::FILE_TEST_EXISTS)) { - fileNamesToDel.push_back (t[i]->filename); + for (const auto& entry : t) { + if (!Glib::file_test(entry->filename, Glib::FILE_TEST_EXISTS)) { + fileNamesToDel.push_back(entry->filename); } - - for (size_t i = 0; i < fileNamesToDel.size(); i++) { - delete fileBrowser->delEntry (fileNamesToDel[i]); - cacheMgr->deleteEntry (fileNamesToDel[i]); - previewsLoaded--; } - if (!fileNamesToDel.empty ()) { + for (const auto& toDelete : fileNamesToDel) { + delete fileBrowser->delEntry(toDelete); + cacheMgr->deleteEntry(toDelete); + --previewsLoaded; + } + + if (!fileNamesToDel.empty()) { _refreshProgressBar(); } // check if a new file has been added // build a set of collate-keys for faster search std::set oldNames; - for (size_t j = 0; j < fileNameList.size(); j++) { - oldNames.insert(fileNameList[j].collate_key()); + for (const auto& oldName : fileNameList) { + oldNames.insert(oldName.collate_key()); } - for (size_t i = 0; i < nfileNameList.size(); i++) { - if (oldNames.count(nfileNameList[i].collate_key()) == 0) { - checkAndAddFile (Gio::File::create_for_parse_name(nfileNameList[i])); - _refreshProgressBar (); + fileNameList = getFileList(); + for (const auto& newName : fileNameList) { + if (oldNames.find(newName.collate_key()) == oldNames.end()) { + addFile(newName); + _refreshProgressBar(); } } - fileNameList = nfileNameList; } void FileCatalog::on_dir_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, bool internal) @@ -1737,85 +1742,55 @@ void FileCatalog::on_dir_changed (const Glib::RefPtr& file, const Gli } } -void FileCatalog::checkAndAddFile (Glib::RefPtr file) +void FileCatalog::addFile (const Glib::ustring& fName) { - - if (!file) { - return; - } - - try { - - const auto info = file->query_info("standard::*"); - - if (!info || info->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { - return; - } - - if (!options.fbShowHidden && info->is_hidden()) { - return; - } - - Glib::ustring ext; - - const auto lastdot = info->get_name().find_last_of('.'); - - if (lastdot != Glib::ustring::npos) { - ext = info->get_name().substr(lastdot + 1); - } - - if (!options.is_extention_enabled(ext)) { - return; - } - - previewLoader->add(selectedDirectoryId, file->get_parse_name(), this); + if (!fName.empty()) { + previewLoader->add(selectedDirectoryId, fName, this); previewsToLoad++; - - } catch(Gio::Error&) {} + } } void FileCatalog::addAndOpenFile (const Glib::ustring& fname) { - auto file = Gio::File::create_for_path (fname); + auto file = Gio::File::create_for_path(fname); if (!file ) { return; } - if (!file->query_exists ()) { + if (!file->query_exists()) { return; } try { - auto info = file->query_info (); + const auto info = file->query_info(); if (!info) { return; } - Glib::ustring ext; - - auto lastdot = info->get_name().find_last_of ('.'); + const auto lastdot = info->get_name().find_last_of('.'); if (lastdot != Glib::ustring::npos) { - ext = info->get_name ().substr (lastdot + 1); - } - - if (!options.is_extention_enabled(ext)) { + if (!options.is_extention_enabled(info->get_name().substr(lastdot + 1))) { + return; + } + } else { return; } + // if supported, load thumbnail first - const auto tmb = cacheMgr->getEntry (file->get_parse_name ()); + const auto tmb = cacheMgr->getEntry(file->get_parse_name()); if (!tmb) { return; } - FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name ()); - previewReady (selectedDirectoryId, entry); + FileBrowserEntry* entry = new FileBrowserEntry(tmb, file->get_parse_name()); + previewReady(selectedDirectoryId, entry); // open the file - tmb->increaseRef (); + tmb->increaseRef(); idle_register.add( [this, tmb]() -> bool { @@ -1830,27 +1805,30 @@ void FileCatalog::addAndOpenFile (const Glib::ustring& fname) void FileCatalog::emptyTrash () { - const std::vector t = fileBrowser->getEntries (); + const auto& t = fileBrowser->getEntries(); std::vector toDel; - for (size_t i = 0; i < t.size(); i++) - if ((static_cast(t[i]))->thumbnail->getStage() == 1) { - toDel.push_back (static_cast(t[i])); + for (const auto entry : t) { + if ((static_cast(entry))->thumbnail->getStage() == 1) { + toDel.push_back(static_cast(entry)); } - - deleteRequested (toDel, false, false); - trashChanged(); + } + if (toDel.size() > 0) { + deleteRequested(toDel, false, false); + trashChanged(); + } } bool FileCatalog::trashIsEmpty () { - const std::vector t = fileBrowser->getEntries (); - for (size_t i = 0; i < t.size(); i++) - if ((static_cast(t[i]))->thumbnail->getStage() == 1) { + const auto& t = fileBrowser->getEntries(); + + for (const auto entry : t) { + if ((static_cast(entry))->thumbnail->getStage() == 1) { return false; } - + } return true; } diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 4c0d13e51..2f3054bcf 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -141,7 +141,7 @@ private: IdleRegister idle_register; void addAndOpenFile (const Glib::ustring& fname); - void checkAndAddFile (Glib::RefPtr info); + void addFile (const Glib::ustring& fName); std::vector getFileList (); BrowserFilter getFilter (); void trashChanged (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 2437f5313..640aa0243 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -369,6 +369,7 @@ void Options::setDefaults() multiUser = true; profilePath = "profiles"; loadSaveProfilePath = ""; // will be corrected in load as otherwise construction fails + lastCopyMovePath = ""; version = "0.0.0.0"; // temporary value; will be correctly set in RTWindow::on_realize thumbSize = 160; thumbSizeTab = 160; @@ -412,6 +413,7 @@ void Options::setDefaults() favorites.clear(); parseExtensionsEnabled.clear(); parsedExtensions.clear(); + parsedExtensionsSet.clear(); renameUseTemplates = false; renameTemplates.clear(); thumbnailZoomRatios.clear(); @@ -648,10 +650,12 @@ Options* Options::copyFrom(Options* other) void Options::filterOutParsedExtensions() { parsedExtensions.clear(); + parsedExtensionsSet.clear(); for (unsigned int i = 0; i < parseExtensions.size(); i++) if (parseExtensionsEnabled[i]) { parsedExtensions.push_back(parseExtensions[i].lowercase()); + parsedExtensionsSet.emplace(parseExtensions[i].lowercase()); } } @@ -1836,6 +1840,7 @@ void Options::readFromFile(Glib::ustring fname) safeDirGet(keyFile, "Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); safeDirGet(keyFile, "Dialogs", "LastLensProfileDir", lastLensProfileDir); safeDirGet(keyFile, "Dialogs", "LastICCProfCreatorDir", lastICCProfCreatorDir); + safeDirGet(keyFile, "Dialogs", "LastCopyMovePath", lastCopyMovePath); if (keyFile.has_key("Dialogs", "GimpPluginShowInfoDialog")) { gimpPluginShowInfoDialog = keyFile.get_boolean("Dialogs", "GimpPluginShowInfoDialog"); @@ -2229,6 +2234,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); keyFile.set_string("Dialogs", "LastLensProfileDir", lastLensProfileDir); keyFile.set_string("Dialogs", "LastICCProfCreatorDir", lastICCProfCreatorDir); + keyFile.set_string("Dialogs", "LastCopyMovePath", lastCopyMovePath); keyFile.set_boolean("Dialogs", "GimpPluginShowInfoDialog", gimpPluginShowInfoDialog); keyFile.set_string("Lensfun", "DBDirectory", rtSettings.lensfunDbDirectory); @@ -2464,36 +2470,17 @@ bool Options::is_parse_extention(Glib::ustring fname) /* * return true if fname ends with one of the retained image file extensions */ -bool Options::has_retained_extention(Glib::ustring fname) +bool Options::has_retained_extention(const Glib::ustring& fname) { - - Glib::ustring ext = getExtension(fname).lowercase(); - - if (!ext.empty()) { - // there is an extension to the filename - - // look out if it has one of the retained extensions - for (unsigned int i = 0; i < parsedExtensions.size(); i++) { - if (ext == parsedExtensions[i]) { - return true; - } - } - } - - return false; + return parsedExtensionsSet.find(getExtension(fname).lowercase()) != parsedExtensionsSet.end(); } /* * return true if ext is an enabled extension */ -bool Options::is_extention_enabled(Glib::ustring ext) +bool Options::is_extention_enabled(const Glib::ustring& ext) { - for (int j = 0; j < (int)parseExtensions.size(); j++) - if (parseExtensions[j].casefold() == ext.casefold()) { - return j >= (int)parseExtensionsEnabled.size() || parseExtensionsEnabled[j]; - } - - return false; + return parsedExtensionsSet.find(ext.lowercase()) != parsedExtensionsSet.end(); } Glib::ustring Options::getUserProfilePath() diff --git a/rtgui/options.h b/rtgui/options.h index 304a1e220..d1d14a11f 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -19,6 +19,7 @@ #ifndef _OPTIONS_ #define _OPTIONS_ +#include #include #include "../rtengine/rtengine.h" #include @@ -174,6 +175,7 @@ public: Glib::ustring startupPath; Glib::ustring profilePath; // can be an absolute or relative path; depending on this value, bundled profiles may not be found bool useBundledProfiles; // only used if multiUser == true + Glib::ustring lastCopyMovePath; Glib::ustring loadSaveProfilePath; Glib::ustring lastSaveAsPath; int saveAsDialogWidth; @@ -259,6 +261,7 @@ public: std::vector parseExtensions; // List containing all extensions type std::vector parseExtensionsEnabled; // List of bool to retain extension or not std::vector parsedExtensions; // List containing all retained extensions (lowercase) + std::set parsedExtensionsSet; // Set containing all retained extensions (lowercase) std::vector tpOpen; bool autoSaveTpOpen; //std::vector crvOpen; @@ -422,8 +425,8 @@ public: Glib::ustring getGlobalProfilePath(); Glib::ustring findProfilePath (Glib::ustring &profName); bool is_parse_extention (Glib::ustring fname); - bool has_retained_extention (Glib::ustring fname); - bool is_extention_enabled (Glib::ustring ext); + bool has_retained_extention (const Glib::ustring& fname); + bool is_extention_enabled (const Glib::ustring& ext); bool is_defProfRawMissing(); bool is_bundledDefProfRawMissing(); bool is_defProfImgMissing(); From 85aacaddf285c7c8eb4cb60f4085457103e8e71e Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Wed, 17 Jul 2019 00:53:36 +0200 Subject: [PATCH 057/222] Minor whitespace fix --- rtengine/rtthumbnail.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 4b0baa685..2a35176e6 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1167,7 +1167,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT Imagefloat* baseImg = resizeTo (rwidth, rheight, interp, thumbImg); - if(isRaw && params.filmNegative.enabled) { + if (isRaw && params.filmNegative.enabled) { processFilmNegative(params, baseImg, rwidth, rheight, rmi, gmi, bmi); } From cd597ec3865a9e2df224a52ef9a5d1cb4179d54c Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 17 Jul 2019 12:13:48 +0200 Subject: [PATCH 058/222] raw crop for Sony ILCE-7RM4 (Sony A7R IV) --- rtengine/camconst.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 97a14f66e..894414f8a 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2437,6 +2437,11 @@ Camera constants: "pdaf_offset" : 31 }, + { // Quality C, + "make_model": "Sony ILCE-7RM4", + "raw_crop": [ 0, 0, 9568, 0 ] // full raw frame 9600x6376 - 32 rightmost columns are garbage + }, + { // Quality B, color matrix copied from a7rm2 "make_model": "Sony ILCE-9", "dcraw_matrix": [ 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 ], // DNG_v9.12 D65 From a0f2040816d8c41d60efd43c3927e2a1eac60a84 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 17 Jul 2019 21:23:17 +0200 Subject: [PATCH 059/222] Small cleanup Removed unused key TP_FILMNEGATIVE_REF_SPOTS. Style fix in language string. generateTranslationDiffs Film Negative values in History use newlines to reduce required width. Removed benchmark code. --- rtdata/languages/Catala | 6 +++--- rtdata/languages/Chinese (Simplified) | 6 +++--- rtdata/languages/Czech | 9 +++++++++ rtdata/languages/Deutsch | 13 ++++++------- rtdata/languages/English (UK) | 6 +++--- rtdata/languages/English (US) | 6 +++--- rtdata/languages/Espanol | 9 +++++++++ rtdata/languages/Francais | 9 +++++++++ rtdata/languages/Italiano | 6 +++--- rtdata/languages/Japanese | 9 +++++++++ rtdata/languages/Magyar | 6 +++--- rtdata/languages/Nederlands | 6 +++--- rtdata/languages/Polish | 6 +++--- rtdata/languages/Portugues | 9 +++++++++ rtdata/languages/Portugues (Brasil) | 6 +++--- rtdata/languages/Russian | 6 +++--- rtdata/languages/Serbian (Cyrilic Characters) | 6 +++--- rtdata/languages/Swedish | 6 +++--- rtdata/languages/default | 5 ++--- rtengine/filmnegativeproc.cc | 2 +- rtengine/filmnegativethumb.cc | 3 +-- rtgui/filmnegative.cc | 2 +- 22 files changed, 92 insertions(+), 50 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index fb5104f95..8b2bc5992 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1449,6 +1449,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_EQUALIZER;Wavelet levels +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_GRADIENT;Graduated filter @@ -1854,12 +1855,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index 34e87dc1e..b01c39d84 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1487,6 +1487,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !OPTIONS_DEFRAW_MISSING;The default profile for raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\n"%1" will be used instead. !PARTIALPASTE_ADVANCEDGROUP;Advanced Settings !PARTIALPASTE_DEHAZE;Haze removal +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_LOCALCONTRAST;Local contrast !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1801,12 +1802,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 5df69dd3a..ce16e057f 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -2323,4 +2323,13 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index cd62a8f3b..f2245cfff 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -241,6 +241,8 @@ FILEBROWSER_POPUPRANK2;Bewertung 2 ** FILEBROWSER_POPUPRANK3;Bewertung 3 *** FILEBROWSER_POPUPRANK4;Bewertung 4 **** FILEBROWSER_POPUPRANK5;Bewertung 5 ***** +FILEBROWSER_POPUPREMOVE;Unwiderruflich löschen +FILEBROWSER_POPUPREMOVEINCLPROC;Unwiderruflich löschen\n(einschl. aller Dateien der Stabelverarbeitung) FILEBROWSER_POPUPRENAME;Umbenennen FILEBROWSER_POPUPSELECTALL;Alle auswählen FILEBROWSER_POPUPTRASH;In den Papierkorb verschieben @@ -267,6 +269,7 @@ FILEBROWSER_SHOWDIRHINT;Alle Filter zurücksetzen.\nTaste: d FILEBROWSER_SHOWEDITEDHINT;Nur bearbeitete Bilder anzeigen.\nTaste: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Nur unbearbeitete Bilder anzeigen.\nTaste: 6 FILEBROWSER_SHOWEXIFINFO;Bildinformationen ein-/ausblenden.\n\nIm Multi-Reitermodus:\nTaste: i\nIm Ein-Reitermodus:\nTaste: Alt + i +FILEBROWSER_SHOWNOTTRASHHINT;Nur Bilder außerhalb des Papierkorbs anzeigen. FILEBROWSER_SHOWORIGINALHINT;Zeige nur das Originalbild.\n\nWenn mehrere Bilder mit dem gleichen Dateinamen und unterschiedlichen Dateitypen existieren, ist das Originalbild das Bild, welches in der Liste "Dateitypen anzeigen" unter Einstellungen > Dateiverwaltung als erstes gefunden wird. FILEBROWSER_SHOWRANK1HINT;Nur mit 1 Stern bewertete Bilder anzeigen.\nTaste: 1 FILEBROWSER_SHOWRANK2HINT;Nur mit 2 Sternen bewertete Bilder anzeigen.\nTaste: 2 @@ -2362,16 +2365,12 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -FILEBROWSER_POPUPREMOVE;Unwiderruflich löschen -FILEBROWSER_POPUPREMOVEINCLPROC;Unwiderruflich löschen\n(einschl. aller Dateien der Stabelverarbeitung) -FILEBROWSER_SHOWNOTTRASHHINT;Nur Bilder außerhalb des Papierkorbs anzeigen. - !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative !HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!PARTIALPASTE_FILMNEGATIVE;Film Negative !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index a8639c296..503e63860 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -1066,6 +1066,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PARTIALPASTE_EVERYTHING;Everything !PARTIALPASTE_EXIFCHANGES;Exif !PARTIALPASTE_EXPOSURE;Exposure +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection !PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius @@ -1668,12 +1669,11 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 19535166e..52caa23e4 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -985,6 +985,7 @@ !PARTIALPASTE_EVERYTHING;Everything !PARTIALPASTE_EXIFCHANGES;Exif !PARTIALPASTE_EXPOSURE;Exposure +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection !PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius @@ -1639,12 +1640,11 @@ !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol index 15a4d81f5..c91bd4a6b 100644 --- a/rtdata/languages/Espanol +++ b/rtdata/languages/Espanol @@ -2321,10 +2321,13 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius !MAIN_FRAME_PLACES_DEL;Remove !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic @@ -2342,6 +2345,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location !TP_CROP_PPI;PPI +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_MODE_HEADER;Lens Profile diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index d7141f8b2..2c5017a6e 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -2266,7 +2266,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !MAIN_FRAME_PLACES_DEL;Remove +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... !PROGRESSBAR_HLREC;Highlight reconstruction... @@ -2275,6 +2278,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location !TP_CROP_PPI;PPI +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_MODE_HEADER;Lens Profile diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 63eb2bd66..977277a73 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -1654,6 +1654,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_EQUALIZER;Wavelet levels +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_LOCALCONTRAST;Local contrast @@ -1906,12 +1907,11 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 2cec023e5..316133b3a 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -2312,5 +2312,14 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !QUEUE_LOCATION_TITLE;Output Location +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 20b87789d..26f1b1aa0 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1387,6 +1387,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_EQUALIZER;Wavelet levels +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_GRADIENT;Graduated filter @@ -1819,12 +1820,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 04a270d49..43afc8efa 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -2121,6 +2121,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !OPTIONS_DEFRAW_MISSING;The default profile for raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\n"%1" will be used instead. !PARTIALPASTE_ADVANCEDGROUP;Advanced Settings !PARTIALPASTE_DEHAZE;Haze removal +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_LOCALCONTRAST;Local contrast !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -2233,12 +2234,11 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_CUSTOM;Custom !TP_ICM_WORKING_TRC_GAMMA;Gamma diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index ad3dc62ee..528b6a198 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1735,6 +1735,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PARTIALPASTE_ADVANCEDGROUP;Advanced Settings !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_EQUALIZER;Wavelet levels +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_LOCALCONTRAST;Local contrast !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1932,12 +1933,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_EXPOSURE_TCMODE_LUMINANCE;Luminance !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index 7e5713093..e68f93e56 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -2264,7 +2264,10 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !FILEBROWSER_POPUPREMOVE;Delete permanently !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !MAIN_FRAME_PLACES_DEL;Remove +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_GREENEQUIL;Green equilibration... @@ -2274,6 +2277,12 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !PROGRESSBAR_RAWCACORR;Raw CA correction... !QUEUE_LOCATION_TITLE;Output Location !TP_CROP_PPI;PPI +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_MODE_HEADER;Lens Profile diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index eb9bfe56f..c7cc2dfe7 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -2261,6 +2261,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative !HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !MAIN_FRAME_PLACES_DEL;Remove +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. !PROGRESSBAR_DECODING;Decoding... @@ -2274,12 +2275,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_COLORTONING_LABREGION_POWER;Power !TP_CROP_PPI;PPI !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 653f41dce..a33458ef6 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -1777,6 +1777,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_EQUALIZER;Wavelet levels +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1977,12 +1978,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index f26e03350..98d74a5dd 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1638,6 +1638,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_DEHAZE;Haze removal !PARTIALPASTE_EQUALIZER;Wavelet levels +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_LOCALCONTRAST;Local contrast @@ -1905,12 +1906,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 22c1710b5..17bf0299f 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -1974,6 +1974,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PARTIALPASTE_ADVANCEDGROUP;Advanced Settings !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_DEHAZE;Haze removal +!PARTIALPASTE_FILMNEGATIVE;Film Negative !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_LOCALCONTRAST;Local contrast !PARTIALPASTE_METADATA;Metadata mode @@ -2120,12 +2121,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. !TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Green exponent -!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_GREEN;Reference exponent (contrast) +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. !TP_FILMNEGATIVE_LABEL;Film Negative !TP_FILMNEGATIVE_PICK;Pick white and black spots !TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. diff --git a/rtdata/languages/default b/rtdata/languages/default index ab85f16e6..e8392db6b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -984,8 +984,8 @@ PARTIALPASTE_EQUALIZER;Wavelet levels PARTIALPASTE_EVERYTHING;Everything PARTIALPASTE_EXIFCHANGES;Exif PARTIALPASTE_EXPOSURE;Exposure -PARTIALPASTE_FILMSIMULATION;Film simulation PARTIALPASTE_FILMNEGATIVE;Film Negative +PARTIALPASTE_FILMSIMULATION;Film simulation PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type @@ -1640,11 +1640,10 @@ TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points TP_EXPOS_WHITEPOINT_LABEL;Raw White Points TP_FILMNEGATIVE_BLUE;Blue ratio TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -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_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. TP_FILMNEGATIVE_LABEL;Film Negative TP_FILMNEGATIVE_PICK;Pick white and black spots TP_FILMNEGATIVE_RED;Red ratio -TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots TP_FILMSIMULATION_LABEL;Film Simulation TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 58d87d103..12f19fba9 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -175,7 +175,7 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ static_cast(-params.greenExp), static_cast(-params.blueRatio * params.greenExp) }; - + MyTime t1, t2, t3,t4, t5; t1.set(); diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc index 610781872..8c7564b86 100644 --- a/rtengine/filmnegativethumb.cc +++ b/rtengine/filmnegativethumb.cc @@ -41,7 +41,6 @@ void rtengine::Thumbnail::processFilmNegative( const int rwidth, const int rheight, float &rmi, float &gmi, float &bmi ) { - StopWatch stop1("Thumbnail film negative", true); // Channel exponents const float rexp = -params.filmNegative.redRatio * params.filmNegative.greenExp; @@ -128,4 +127,4 @@ void rtengine::Thumbnail::processFilmNegative( bline[j] = CLIP(bmult * pow_F(bline[j], bexp)); } } -} \ No newline at end of file +} diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 598c9463a..2145f46b1 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -189,7 +189,7 @@ void FilmNegative::adjusterChanged(Adjuster* a, double newval) listener->panelChanged( evFilmNegativeExponents, Glib::ustring::compose( - "Ref=%1 ; R=%2 ; B=%3", + "Ref=%1\nR=%2\nB=%3", greenExp->getValue(), redRatio->getValue(), blueRatio->getValue() From bbdd774afb0dcf5c6a8c7fe74eef1eda9ef0097d Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 17 Jul 2019 21:29:24 +0200 Subject: [PATCH 060/222] Further speedups for filebrowser --- rtgui/filebrowser.cc | 19 ++++++++++--------- rtgui/thumbbrowserbase.cc | 26 +++++++++++++------------- rtgui/thumbbrowserbase.h | 4 ++-- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index a270e5af8..cc215e70a 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -592,15 +592,16 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) { entry->selected = false; entry->drawable = false; - entry->framed = editedFiles.find (entry->filename) != editedFiles.end(); + entry->framed = editedFiles.find(entry->filename) != editedFiles.end(); // add button set to the thumbbrowserentry - entry->addButtonSet (new FileThumbnailButtonSet (entry)); - entry->getThumbButtonSet()->setRank (entry->thumbnail->getRank()); - entry->getThumbButtonSet()->setColorLabel (entry->thumbnail->getColorLabel()); - entry->getThumbButtonSet()->setInTrash (entry->thumbnail->getStage()); - entry->getThumbButtonSet()->setButtonListener (this); - entry->resize (getThumbnailHeight()); + entry->addButtonSet(new FileThumbnailButtonSet(entry)); + entry->getThumbButtonSet()->setRank(entry->thumbnail->getRank()); + entry->getThumbButtonSet()->setColorLabel(entry->thumbnail->getColorLabel()); + entry->getThumbButtonSet()->setInTrash(entry->thumbnail->getStage()); + entry->getThumbButtonSet()->setButtonListener(this); + entry->resize(getThumbnailHeight()); + entry->filtered = !checkFilter(entry); // find place in abc order { @@ -619,9 +620,9 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) entry ); - initEntry (entry); + initEntry(entry); } - redraw (); + redraw(false); } FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 334f00e51..1ae0cdf98 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -563,7 +563,7 @@ void ThumbBrowserBase::configScrollBars () } } -void ThumbBrowserBase::arrangeFiles() +void ThumbBrowserBase::arrangeFiles(bool checkfilter) { MYREADERLOCK(l, entryRW); @@ -572,17 +572,17 @@ void ThumbBrowserBase::arrangeFiles() //GThreadLock lock; int rowHeight = 0; - - for (unsigned int i = 0; i < fd.size(); i++) { - // apply filter - fd[i]->filtered = !checkFilter (fd[i]); + for (const auto entry : fd) { + if (checkfilter) { + // apply filter + entry->filtered = !checkFilter(entry); + } // compute size of the items - if (!fd[i]->filtered && fd[i]->getMinimalHeight() > rowHeight) { - rowHeight = fd[i]->getMinimalHeight (); + if (!entry->filtered) { + rowHeight = std::max(entry->getMinimalHeight(), rowHeight); } } - if (arrangement == TB_Horizontal) { numOfCols = 1; @@ -667,9 +667,9 @@ void ThumbBrowserBase::arrangeFiles() } if (ct < fd.size()) { - fd[ct]->setPosition(currx, curry, colWidths[i % numOfCols], rowHeight); + fd[ct]->setPosition(currx, curry, colWidths[i], rowHeight); fd[ct]->drawable = true; - currx += colWidths[i % numOfCols]; + currx += colWidths[i]; } } @@ -970,12 +970,12 @@ bool ThumbBrowserBase::Internal::on_scroll_event (GdkEventScroll* event) } -void ThumbBrowserBase::redraw () +void ThumbBrowserBase::redraw (bool checkfilter) { GThreadLock lock; - arrangeFiles (); - queue_draw (); + arrangeFiles(checkfilter); + queue_draw(); } void ThumbBrowserBase::zoomChanged (bool zoomIn) diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index dcda30f92..ae561db43 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -179,7 +179,7 @@ protected: std::set editedFiles; - void arrangeFiles (); + void arrangeFiles (bool checkfilter = true); void zoomChanged (bool zoomIn); public: @@ -201,7 +201,7 @@ public: return fd; } void on_style_updated () override; - void redraw (); // arrange files and draw area + void redraw (bool checkfilter = true); // arrange files and draw area void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshQuickThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshEditedState (const std::set& efiles); From 2ca9f7f94d94a808670fb81a13e3945084a023b9 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 17 Jul 2019 22:10:46 +0200 Subject: [PATCH 061/222] Further small speedup for filebrowser --- rtgui/lwbuttonset.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/rtgui/lwbuttonset.cc b/rtgui/lwbuttonset.cc index 6265c1039..1337c0ea5 100644 --- a/rtgui/lwbuttonset.cc +++ b/rtgui/lwbuttonset.cc @@ -18,7 +18,7 @@ */ #include "lwbuttonset.h" -LWButtonSet::LWButtonSet () : aw(0), ah(0), ax(0), ay(0) +LWButtonSet::LWButtonSet () : aw(0), ah(0), ax(-1), ay(-1) { } @@ -42,20 +42,21 @@ void LWButtonSet::getMinimalDimensions (int& w, int& h) w = 0; h = 0; - for (size_t i = 0; i < buttons.size(); i++) { + for (const auto entry : buttons) { int bw, bh; - buttons[i]->getSize (bw, bh); + entry->getSize(bw, bh); w += bw; - - if (bh > h) { - h = bh; - } + h = std::max(bh, h); } } void LWButtonSet::arrangeButtons (int x, int y, int w, int h) { + if (x == ax && y == ay && w == aw && ((h == -1 && ah == 0) || h == ah )) { + return; + } + int mw, mh; getMinimalDimensions (mw, mh); From 5f8799d48e8233ae13386e2c1b8942b8b1fa10c5 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 18 Jul 2019 11:18:45 +0200 Subject: [PATCH 062/222] Store buttonset tooltips in static memory, saves about 700 byte per thumbnail --- rtgui/batchqueuebuttonset.cc | 13 +++-- rtgui/batchqueuebuttonset.h | 4 ++ rtgui/cropwindow.cc | 24 ++++++++-- rtgui/cropwindow.h | 6 +++ rtgui/filethumbnailbuttonset.cc | 84 ++++++++++++++------------------- rtgui/filethumbnailbuttonset.h | 16 ++++--- rtgui/lwbutton.cc | 31 ++++++------ rtgui/lwbutton.h | 18 +++---- 8 files changed, 110 insertions(+), 86 deletions(-) diff --git a/rtgui/batchqueuebuttonset.cc b/rtgui/batchqueuebuttonset.cc index f5be480e8..b42d3c773 100644 --- a/rtgui/batchqueuebuttonset.cc +++ b/rtgui/batchqueuebuttonset.cc @@ -27,6 +27,10 @@ Cairo::RefPtr BatchQueueButtonSet::cancelIcon; Cairo::RefPtr BatchQueueButtonSet::headIcon; Cairo::RefPtr BatchQueueButtonSet::tailIcon; +Glib::ustring BatchQueueButtonSet::moveHeadToolTip; +Glib::ustring BatchQueueButtonSet::moveEndToolTip; +Glib::ustring BatchQueueButtonSet::cancelJobToolTip; + BatchQueueButtonSet::BatchQueueButtonSet (BatchQueueEntry* myEntry) { @@ -34,10 +38,13 @@ BatchQueueButtonSet::BatchQueueButtonSet (BatchQueueEntry* myEntry) cancelIcon = Cairo::RefPtr(new RTSurface("cancel-small.png")); headIcon = Cairo::RefPtr(new RTSurface("goto-start-small.png")); tailIcon = Cairo::RefPtr(new RTSurface("goto-end-small.png")); + moveHeadToolTip = M("FILEBROWSER_POPUPMOVEHEAD"); + moveEndToolTip = M("FILEBROWSER_POPUPMOVEEND"); + cancelJobToolTip = M("FILEBROWSER_POPUPCANCELJOB"); iconsLoaded = true; } - add (new LWButton (headIcon, 8, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEHEAD"))); - add (new LWButton (tailIcon, 9, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEEND"))); - add (new LWButton (cancelIcon, 10, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPCANCELJOB"))); + add(new LWButton(headIcon, 8, myEntry, LWButton::Left, LWButton::Center, &moveHeadToolTip)); + add(new LWButton(tailIcon, 9, myEntry, LWButton::Left, LWButton::Center, &moveEndToolTip)); + add(new LWButton(cancelIcon, 10, myEntry, LWButton::Right, LWButton::Center, &cancelJobToolTip)); } diff --git a/rtgui/batchqueuebuttonset.h b/rtgui/batchqueuebuttonset.h index 66dab91a1..e97819719 100644 --- a/rtgui/batchqueuebuttonset.h +++ b/rtgui/batchqueuebuttonset.h @@ -34,6 +34,10 @@ public: static Cairo::RefPtr headIcon; static Cairo::RefPtr tailIcon; + static Glib::ustring moveHeadToolTip; + static Glib::ustring moveEndToolTip; + static Glib::ustring cancelJobToolTip; + explicit BatchQueueButtonSet (BatchQueueEntry* myEntry); }; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 4b2c1a6cc..b29aa5eeb 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -38,6 +38,13 @@ using namespace rtengine; +bool CropWindow::initialized = false; + +Glib::ustring CropWindow::zoomOuttt; +Glib::ustring CropWindow::zoomIntt; +Glib::ustring CropWindow::zoom100tt; +Glib::ustring CropWindow::closett; + CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow) : ObjectMOBuffer(parent), state(SNormal), press_x(0), press_y(0), action_x(0), action_y(0), pickedObject(-1), pickModifierKey(0), rot_deg(0), onResizeArea(false), deleted(false), fitZoomEnabled(true), fitZoom(false), cursor_type(CSArrow), /*isLowUpdatePriority(isLowUpdatePriority_),*/ hoveredPicker(nullptr), cropLabel(Glib::ustring("100%")), @@ -61,11 +68,18 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet titleHeight = ih; - bZoomOut = new LWButton (Cairo::RefPtr(new RTSurface("magnifier-minus-small.png")), 0, nullptr, LWButton::Left, LWButton::Center, "Zoom Out"); - bZoomIn = new LWButton (Cairo::RefPtr(new RTSurface("magnifier-plus-small.png")), 1, nullptr, LWButton::Left, LWButton::Center, "Zoom In"); - bZoom100 = new LWButton (Cairo::RefPtr(new RTSurface("magnifier-1to1-small.png")), 2, nullptr, LWButton::Left, LWButton::Center, "Zoom 100/%"); - //bZoomFit = new LWButton (Cairo::RefPtr(new RTSurface("magnifier-fit.png")), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit"); - bClose = new LWButton (Cairo::RefPtr(new RTSurface("cancel-small.png")), 4, nullptr, LWButton::Right, LWButton::Center, "Close"); + if (!initialized) { + zoomOuttt = "Zoom Out"; + zoomIntt = "Zoom In"; + zoom100tt = "Zoom 100/%"; + closett = "Close"; + initialized = true; + } + bZoomOut = new LWButton(Cairo::RefPtr(new RTSurface("magnifier-minus-small.png")), 0, nullptr, LWButton::Left, LWButton::Center, &zoomOuttt); + bZoomIn = new LWButton(Cairo::RefPtr(new RTSurface("magnifier-plus-small.png")), 1, nullptr, LWButton::Left, LWButton::Center, &zoomIntt); + bZoom100 = new LWButton(Cairo::RefPtr(new RTSurface("magnifier-1to1-small.png")), 2, nullptr, LWButton::Left, LWButton::Center, &zoom100tt); + //bZoomFit = new LWButton (Cairo::RefPtr(new RTSurface("magnifier-fit.png")), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit"); + bClose = new LWButton(Cairo::RefPtr(new RTSurface("cancel-small.png")), 4, nullptr, LWButton::Right, LWButton::Center, &closett); buttonSet.add (bZoomOut); buttonSet.add (bZoomIn); diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 287cbf1ef..6e2097d3b 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -47,6 +47,12 @@ public: class ImageArea; class CropWindow : public LWButtonListener, public CropDisplayHandler, public EditCoordSystem, public ObjectMOBuffer { + static bool initialized; + + static Glib::ustring zoomOuttt; + static Glib::ustring zoomIntt; + static Glib::ustring zoom100tt; + static Glib::ustring closett; // state management ImgEditState state; // current state of user (see enum State) diff --git a/rtgui/filethumbnailbuttonset.cc b/rtgui/filethumbnailbuttonset.cc index 455ed8555..4c7d8743d 100644 --- a/rtgui/filethumbnailbuttonset.cc +++ b/rtgui/filethumbnailbuttonset.cc @@ -29,12 +29,14 @@ Cairo::RefPtr FileThumbnailButtonSet::unRankIcon; Cairo::RefPtr FileThumbnailButtonSet::trashIcon; Cairo::RefPtr FileThumbnailButtonSet::unTrashIcon; Cairo::RefPtr FileThumbnailButtonSet::processIcon; -Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_0; -Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_1; -Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_2; -Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_3; -Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_4; -Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_5; +std::array, 6> FileThumbnailButtonSet::colorLabelIcon; + +Glib::ustring FileThumbnailButtonSet::processToolTip; +Glib::ustring FileThumbnailButtonSet::unrankToolTip; +Glib::ustring FileThumbnailButtonSet::trashToolTip; +Glib::ustring FileThumbnailButtonSet::untrashToolTip; +Glib::ustring FileThumbnailButtonSet::colorLabelToolTip; +std::array FileThumbnailButtonSet::rankToolTip; FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) { @@ -46,73 +48,57 @@ FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) trashIcon = Cairo::RefPtr(new RTSurface("trash-small.png")); unTrashIcon = Cairo::RefPtr(new RTSurface("trash-remove-small.png")); processIcon = Cairo::RefPtr(new RTSurface("gears-small.png")); + colorLabelIcon[0] = Cairo::RefPtr(new RTSurface("circle-empty-gray-small.png")); + colorLabelIcon[1] = Cairo::RefPtr(new RTSurface("circle-red-small.png")); + colorLabelIcon[2] = Cairo::RefPtr(new RTSurface("circle-yellow-small.png")); + colorLabelIcon[3] = Cairo::RefPtr(new RTSurface("circle-green-small.png")); + colorLabelIcon[4] = Cairo::RefPtr(new RTSurface("circle-blue-small.png")); + colorLabelIcon[5] = Cairo::RefPtr(new RTSurface("circle-purple-small.png")); + + processToolTip = M("FILEBROWSER_POPUPPROCESS"); + unrankToolTip = M("FILEBROWSER_UNRANK_TOOLTIP"); + trashToolTip = M("FILEBROWSER_POPUPTRASH"); + untrashToolTip = M("FILEBROWSER_POPUPUNTRASH"); + colorLabelToolTip = M("FILEBROWSER_COLORLABEL_TOOLTIP"); + rankToolTip[0] = M("FILEBROWSER_RANK1_TOOLTIP"); + rankToolTip[1] = M("FILEBROWSER_RANK2_TOOLTIP"); + rankToolTip[2] = M("FILEBROWSER_RANK3_TOOLTIP"); + rankToolTip[3] = M("FILEBROWSER_RANK4_TOOLTIP"); + rankToolTip[4] = M("FILEBROWSER_RANK5_TOOLTIP"); - colorLabelIcon_0 = Cairo::RefPtr(new RTSurface("circle-empty-gray-small.png")); - colorLabelIcon_1 = Cairo::RefPtr(new RTSurface("circle-red-small.png")); - colorLabelIcon_2 = Cairo::RefPtr(new RTSurface("circle-yellow-small.png")); - colorLabelIcon_3 = Cairo::RefPtr(new RTSurface("circle-green-small.png")); - colorLabelIcon_4 = Cairo::RefPtr(new RTSurface("circle-blue-small.png")); - colorLabelIcon_5 = Cairo::RefPtr(new RTSurface("circle-purple-small.png"));; iconsLoaded = true; } - add (new LWButton (processIcon, 6, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPPROCESS"))); - add (new LWButton (unRankIcon, 0, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_UNRANK_TOOLTIP"))); + add(new LWButton(processIcon, 6, myEntry, LWButton::Left, LWButton::Center, &processToolTip)); + add(new LWButton(unRankIcon, 0, myEntry, LWButton::Left, LWButton::Center, &unrankToolTip)); for (int i = 0; i < 5; i++) { - add (new LWButton (rankIcon, i + 1, myEntry, LWButton::Left)); + add(new LWButton(rankIcon, i + 1, myEntry, LWButton::Left, LWButton::Center, &rankToolTip[i])); } - add (new LWButton (trashIcon, 7, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPTRASH"))); - - add (new LWButton (colorLabelIcon_0, 8, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_COLORLABEL_TOOLTIP"))); - - buttons[2]->setToolTip (M("FILEBROWSER_RANK1_TOOLTIP")); - buttons[3]->setToolTip (M("FILEBROWSER_RANK2_TOOLTIP")); - buttons[4]->setToolTip (M("FILEBROWSER_RANK3_TOOLTIP")); - buttons[5]->setToolTip (M("FILEBROWSER_RANK4_TOOLTIP")); - buttons[6]->setToolTip (M("FILEBROWSER_RANK5_TOOLTIP")); + add(new LWButton(trashIcon, 7, myEntry, LWButton::Right, LWButton::Center, &trashToolTip)); + add(new LWButton(colorLabelIcon[0], 8, myEntry, LWButton::Right, LWButton::Center, &colorLabelToolTip)); } void FileThumbnailButtonSet::setRank (int stars) { for (int i = 1; i <= 5; i++) { - buttons[i + 1]->setIcon (i <= stars ? rankIcon : gRankIcon); + buttons[i + 1]->setIcon(i <= stars ? rankIcon : gRankIcon); } } void FileThumbnailButtonSet::setColorLabel (int colorLabel) { - if (colorLabel == 0) { - buttons[8]->setIcon (colorLabelIcon_0); //transparent label - } - - if (colorLabel == 1) { - buttons[8]->setIcon (colorLabelIcon_1); - } - - if (colorLabel == 2) { - buttons[8]->setIcon (colorLabelIcon_2); - } - - if (colorLabel == 3) { - buttons[8]->setIcon (colorLabelIcon_3); - } - - if (colorLabel == 4) { - buttons[8]->setIcon (colorLabelIcon_4); - } - - if (colorLabel == 5) { - buttons[8]->setIcon (colorLabelIcon_5); + if (colorLabel >= 0 && colorLabel <= 5) { + buttons[8]->setIcon(colorLabelIcon[colorLabel]); } } void FileThumbnailButtonSet::setInTrash (bool inTrash) { - buttons[7]->setIcon (inTrash ? unTrashIcon : trashIcon); - buttons[7]->setToolTip (inTrash ? M("FILEBROWSER_POPUPUNTRASH") : M("FILEBROWSER_POPUPTRASH")); + buttons[7]->setIcon(inTrash ? unTrashIcon : trashIcon); + buttons[7]->setToolTip(inTrash ? &untrashToolTip : &trashToolTip); } diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h index 57811addd..13265b8c0 100644 --- a/rtgui/filethumbnailbuttonset.h +++ b/rtgui/filethumbnailbuttonset.h @@ -19,6 +19,8 @@ #ifndef _FILETHUMBNAILBUTTONSET_ #define _FILETHUMBNAILBUTTONSET_ +#include + #include "lwbuttonset.h" #include #include "filebrowserentry.h" @@ -38,12 +40,14 @@ public: static Cairo::RefPtr unTrashIcon; static Cairo::RefPtr processIcon; - static Cairo::RefPtr colorLabelIcon_0; - static Cairo::RefPtr colorLabelIcon_1; - static Cairo::RefPtr colorLabelIcon_2; - static Cairo::RefPtr colorLabelIcon_3; - static Cairo::RefPtr colorLabelIcon_4; - static Cairo::RefPtr colorLabelIcon_5; + static std::array, 6> colorLabelIcon; + + static Glib::ustring processToolTip; + static Glib::ustring unrankToolTip; + static Glib::ustring trashToolTip; + static Glib::ustring untrashToolTip; + static Glib::ustring colorLabelToolTip; + static std::array rankToolTip; explicit FileThumbnailButtonSet (FileBrowserEntry* myEntry); void setRank (int stars); diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc index 48843a02e..02041ea0c 100644 --- a/rtgui/lwbutton.cc +++ b/rtgui/lwbutton.cc @@ -19,7 +19,7 @@ #include "lwbutton.h" #include "guiutils.h" -LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha, Alignment va, Glib::ustring tooltip) +LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha, Alignment va, Glib::ustring* tooltip) : xpos(0), ypos(0), halign(ha), valign(va), icon(i), bgr(0.0), bgg(0.0), bgb(0.0), fgr(0.0), fgg(0.0), fgb(0.0), state(Normal), listener(nullptr), actionCode(aCode), actionData(aData), toolTip(tooltip) { @@ -31,7 +31,7 @@ LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignmen } } -void LWButton::getSize (int& minw, int& minh) +void LWButton::getSize (int& minw, int& minh) const { minw = w; @@ -45,7 +45,7 @@ void LWButton::setPosition (int x, int y) ypos = y; } -void LWButton::getPosition (int& x, int& y) +void LWButton::getPosition (int& x, int& y) const { x = xpos; @@ -65,7 +65,7 @@ void LWButton::setIcon (Cairo::RefPtr i) } } -Cairo::RefPtr LWButton::getIcon () +Cairo::RefPtr LWButton::getIcon () const { return icon; @@ -82,7 +82,7 @@ void LWButton::setColors (const Gdk::RGBA& bg, const Gdk::RGBA& fg) fgb = fg.get_blue (); } -bool LWButton::inside (int x, int y) +bool LWButton::inside (int x, int y) const { return x > xpos && x < xpos + w && y > ypos && y < ypos + h; @@ -210,24 +210,27 @@ void LWButton::redraw (Cairo::RefPtr context) } } -void LWButton::getAlignment (Alignment& ha, Alignment& va) +void LWButton::getAlignment (Alignment& ha, Alignment& va) const { ha = halign; va = valign; } -Glib::ustring LWButton::getToolTip (int x, int y) +Glib::ustring LWButton::getToolTip (int x, int y) const { - - if (inside (x, y)) { - return toolTip; - } else { - return ""; - } + if (inside(x, y)) { + if (toolTip) { + return *toolTip; + } else { + return ""; + } + } else { + return ""; + } } -void LWButton::setToolTip (const Glib::ustring& tooltip) +void LWButton::setToolTip (Glib::ustring* tooltip) { toolTip = tooltip; diff --git a/rtgui/lwbutton.h b/rtgui/lwbutton.h index 4ab34f265..aec875d55 100644 --- a/rtgui/lwbutton.h +++ b/rtgui/lwbutton.h @@ -49,26 +49,26 @@ private: LWButtonListener* listener; int actionCode; void* actionData; - Glib::ustring toolTip; + Glib::ustring* toolTip; public: - LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha = Left, Alignment va = Center, Glib::ustring tooltip = ""); + LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha = Left, Alignment va = Center, Glib::ustring* tooltip = nullptr); - void getSize (int& minw, int& minh); - void getAlignment (Alignment& ha, Alignment& va); + void getSize (int& minw, int& minh) const; + void getAlignment (Alignment& ha, Alignment& va) const; void setPosition (int x, int y); - void getPosition (int& x, int& y); - bool inside (int x, int y); + void getPosition (int& x, int& y) const; + bool inside (int x, int y) const; void setIcon (Cairo::RefPtr i); - Cairo::RefPtr getIcon (); + Cairo::RefPtr getIcon () const; void setColors (const Gdk::RGBA& bg, const Gdk::RGBA& fg); - void setToolTip (const Glib::ustring& tooltip); + void setToolTip (Glib::ustring* tooltip); bool motionNotify (int x, int y); bool pressNotify (int x, int y); bool releaseNotify (int x, int y); - Glib::ustring getToolTip (int x, int y); + Glib::ustring getToolTip (int x, int y) const; void setButtonListener (LWButtonListener* bl) { From b4cb60567369a27c33201ab8e5e397103c7e39bd Mon Sep 17 00:00:00 2001 From: TooWaBoo Date: Thu, 18 Jul 2019 17:58:18 +0200 Subject: [PATCH 063/222] Update Deutsch locale --- rtdata/languages/Deutsch | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index f2245cfff..63595e328 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -82,6 +82,7 @@ #81 15.04.2019 Erweiterung (TooWaBoo) RT 5.6 #82 25.05.2019 Erweiterung (TooWaBoo) RT 5.6 #83 06.07.2019 Erweiterung (TooWaBoo) RT 5.6 +#84 18.07.2019 Erweiterung (TooWaBoo) RT 5.6 ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen @@ -2365,12 +2366,12 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values -!PARTIALPASTE_FILMNEGATIVE;Film Negative -!TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. -!TP_FILMNEGATIVE_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red ratio +HISTORY_MSG_FILMNEGATIVE_ENABLED;(Filmnegativ) +HISTORY_MSG_FILMNEGATIVE_VALUES;(Filmnegativ) - Werte +PARTIALPASTE_FILMNEGATIVE;Filmnegativ +TP_FILMNEGATIVE_BLUE;Blauverhältnis +TP_FILMNEGATIVE_GREEN;Bezugsexponent (Kontrast) +TP_FILMNEGATIVE_GUESS_TOOLTIP;Berechnet die Exponenten durch Auswahl zweier neutraler\nReferenzpunkte im Bild. Weiß (Hellgrau) und Schwarz (Dunkelgrau).\nDie Reihenfolge spielt keine Rolle. Die Exponenten werden aktualisiert,\nnachdem der zweite Punkt ausgewählt wurde. +TP_FILMNEGATIVE_LABEL;Filmnegativ +TP_FILMNEGATIVE_PICK;Weißen und schwarzen Bereich auswählen +TP_FILMNEGATIVE_RED;Rotverhältnis From 14025dd15fbce9a01b2826913b54dc2b9d2d921a Mon Sep 17 00:00:00 2001 From: TooWaBoo Date: Thu, 18 Jul 2019 18:07:09 +0200 Subject: [PATCH 064/222] Fix History view of values --- rtgui/filmnegative.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 2145f46b1..3464f7e46 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -269,7 +269,7 @@ bool FilmNegative::button1Pressed(int modifierKey) listener->panelChanged( evFilmNegativeExponents, Glib::ustring::compose( - "Ref=%1 ; R=%2 ; B=%3", + "Ref=%1\nR=%2\nB=%3", greenExp->getValue(), redRatio->getValue(), blueRatio->getValue() From 4d2807172c2097761d029474ec9fb19cf46adacf Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 19 Jul 2019 00:50:12 +0200 Subject: [PATCH 065/222] filecatalog/filebrowser: further speedup --- rtgui/lwbuttonset.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/lwbuttonset.cc b/rtgui/lwbuttonset.cc index 1337c0ea5..99d3dce7c 100644 --- a/rtgui/lwbuttonset.cc +++ b/rtgui/lwbuttonset.cc @@ -53,7 +53,7 @@ void LWButtonSet::getMinimalDimensions (int& w, int& h) void LWButtonSet::arrangeButtons (int x, int y, int w, int h) { - if (x == ax && y == ay && w == aw && ((h == -1 && ah == 0) || h == ah )) { + if (x == ax && y == ay && w == aw && (h == -1 || h == ah )) { return; } From d9c93e77ae9a29aedaf4ccd145eae97059e22d0a Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 19 Jul 2019 23:45:02 +0200 Subject: [PATCH 066/222] filecatalog/filebrowser: further optimizations --- rtgui/batchqueueentry.cc | 6 +-- rtgui/batchqueueentry.h | 6 +-- rtgui/filebrowserentry.cc | 47 ++++++++---------- rtgui/filebrowserentry.h | 6 +-- rtgui/filecatalog.cc | 11 ++--- rtgui/inspector.h | 2 +- rtgui/rtimage.cc | 3 +- rtgui/thumbbrowserentrybase.cc | 34 +++++-------- rtgui/thumbbrowserentrybase.h | 90 ++++++++++++++++------------------ 9 files changed, 89 insertions(+), 116 deletions(-) diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index d52fe4305..a5dfb6dde 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -148,7 +148,7 @@ void BatchQueueEntry::removeButtonSet () buttonSet = nullptr; } -std::vector > BatchQueueEntry::getIconsOnImageArea () +std::vector> BatchQueueEntry::getIconsOnImageArea () { std::vector > ret; @@ -160,7 +160,7 @@ std::vector > BatchQueueEntry::getIconsOnImageArea () return ret; } -void BatchQueueEntry::getIconSize (int& w, int& h) +void BatchQueueEntry::getIconSize (int& w, int& h) const { w = savedAsIcon->get_width (); @@ -168,7 +168,7 @@ void BatchQueueEntry::getIconSize (int& w, int& h) } -Glib::ustring BatchQueueEntry::getToolTip (int x, int y) +Glib::ustring BatchQueueEntry::getToolTip (int x, int y) const { // get the parent class' tooltip first Glib::ustring tooltip = ThumbBrowserEntryBase::getToolTip(x, y); diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index f3e8c1336..d13dfe827 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -68,9 +68,9 @@ public: void removeButtonSet (); - std::vector > getIconsOnImageArea () override; - void getIconSize (int& w, int& h) override; - Glib::ustring getToolTip (int x, int y) override; + std::vector> getIconsOnImageArea () override; + void getIconSize (int& w, int& h) const override; + Glib::ustring getToolTip (int x, int y) const override; // bqentryupdatelistener interface void updateImage (guint8* img, int w, int h, int origw, int origh, guint8* newOPreview) override; diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 0fa5694de..4b1764824 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -119,39 +119,37 @@ void FileBrowserEntry::calcThumbnailSize () } } -std::vector > FileBrowserEntry::getIconsOnImageArea () +std::vector> FileBrowserEntry::getIconsOnImageArea () { - - std::vector > ret; - if (!thumbnail) { - return ret; + return {}; } + std::vector> ret; + if (thumbnail->hasProcParams() && editedIcon) { - ret.push_back (editedIcon); + ret.push_back(editedIcon); } if (thumbnail->isRecentlySaved() && recentlySavedIcon) { - ret.push_back (recentlySavedIcon); + ret.push_back(recentlySavedIcon); } if (thumbnail->isEnqueued () && enqueuedIcon) { - ret.push_back (enqueuedIcon); + ret.push_back(enqueuedIcon); } return ret; } -std::vector > FileBrowserEntry::getSpecificityIconsOnImageArea () +std::vector> FileBrowserEntry::getSpecificityIconsOnImageArea () { - - std::vector > ret; - if (!thumbnail) { - return ret; + return {}; } + std::vector> ret; + if (thumbnail->isHDR() && hdr) { ret.push_back (hdr); } @@ -188,7 +186,7 @@ void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr c) } } -void FileBrowserEntry::getIconSize (int& w, int& h) +void FileBrowserEntry::getIconSize (int& w, int& h) const { w = editedIcon->get_width (); @@ -286,34 +284,29 @@ void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rten bool FileBrowserEntry::motionNotify (int x, int y) { - bool b = ThumbBrowserEntryBase::motionNotify (x, y); + const bool b = ThumbBrowserEntryBase::motionNotify(x, y); - int ix = x - startx - ofsX; - int iy = y - starty - ofsY; + const int ix = x - startx - ofsX; + const int iy = y - starty - ofsY; Inspector* inspector = parent->getInspector(); if (inspector && inspector->isActive() && !parent->isInTabMode()) { - rtengine::Coord2D coord(-1., -1.); - getPosInImgSpace(x, y, coord); + const rtengine::Coord2D coord(getPosInImgSpace(x, y)); if (coord.x != -1.) { if (!wasInside) { inspector->switchImage(filename); + wasInside = true; } - - wasInside = true; inspector->mouseMove(coord, 0); } else { - if (wasInside) { - wasInside = false; - rtengine::Coord2D coord(-1, -1); - } + wasInside = false; } } - if (inside (x, y)) { - updateCursor (ix, iy); + if (inside(x, y)) { + updateCursor(ix, iy); } if (state == SRotateSelecting) { diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 3a3d32977..5122de55f 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -93,9 +93,9 @@ public: void refreshQuickThumbnailImage () override; void calcThumbnailSize () override; - std::vector > getIconsOnImageArea () override; - std::vector > getSpecificityIconsOnImageArea () override; - void getIconSize (int& w, int& h) override; + std::vector> getIconsOnImageArea () override; + std::vector> getSpecificityIconsOnImageArea () override; + void getIconSize (int& w, int& h) const override; // thumbnaillistener interface void procParamsChanged (Thumbnail* thm, int whoChangedIt) override; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 57555fd76..dbe540cb4 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -37,9 +37,6 @@ #include "batchqueue.h" #include "placesbrowser.h" -#define BENCHMARK -#include "../rtengine/StopWatch.h" - using namespace std; #define CHECKTIME 2000 @@ -568,7 +565,7 @@ void FileCatalog::closeDir () std::vector FileCatalog::getFileList() { - BENCHFUN + std::vector names; const std::set& extensions = options.parsedExtensionsSet; @@ -626,9 +623,9 @@ std::vector FileCatalog::getFileList() void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { -BENCHFUN + try { - Glib::RefPtr dir = Gio::File::create_for_path (dirname); + const Glib::RefPtr dir = Gio::File::create_for_path(dirname); if (!dir) { return; @@ -1681,7 +1678,7 @@ void FileCatalog::filterChanged () void FileCatalog::reparseDirectory () { -BENCHFUN + if (selectedDirectory.empty()) { return; } diff --git a/rtgui/inspector.h b/rtgui/inspector.h index d5ed327b8..86ad9114e 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -87,7 +87,7 @@ public: /** @brief Get the on/off state */ - bool isActive() + bool isActive() const { return active; }; diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 6a289ead6..cd687f252 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -197,8 +197,7 @@ void RTImage::updateImages() Glib::RefPtr RTImage::createPixbufFromFile (const Glib::ustring& fileName) { Cairo::RefPtr imgSurf = createImgSurfFromFile(fileName); - Glib::RefPtr pixbuf = Gdk::Pixbuf::create(imgSurf, 0, 0, imgSurf->get_width(), imgSurf->get_height()); - return pixbuf; + return Gdk::Pixbuf::create(imgSurf, 0, 0, imgSurf->get_width(), imgSurf->get_height()); } Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::ustring& fileName) diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index ed34c65c7..2960ccf70 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -157,9 +157,6 @@ ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname) : collate_name(getPaddedName(dispname).casefold_collate_key()), thumbnail(nullptr), filename(fname), - shortname(dispname), - exifline(""), - datetimeline(""), selected(false), drawable(false), filtered(false), @@ -439,7 +436,6 @@ void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) Gtk::Widget* w = parent->getDrawingArea (); // calculate dimensions of the text based fields - dispname = shortname; Glib::RefPtr context = w->get_pango_context () ; context->set_font_description (w->get_style_context()->get_font()); @@ -449,7 +445,7 @@ void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) Pango::FontDescription fontd = context->get_font_description (); fontd.set_weight (Pango::WEIGHT_BOLD); context->set_font_description (fontd); - Glib::RefPtr fn = w->create_pango_layout(shortname); + Glib::RefPtr fn = w->create_pango_layout(dispname); fn->get_pixel_size (fnlabw, fnlabh); // calculate cummulated height of all info fields @@ -672,16 +668,15 @@ void ThumbBrowserEntryBase::setOffset (int x, int y) } } -bool ThumbBrowserEntryBase::inside (int x, int y) +bool ThumbBrowserEntryBase::inside (int x, int y) const { return x > ofsX + startx && x < ofsX + startx + exp_width && y > ofsY + starty && y < ofsY + starty + exp_height; } -void ThumbBrowserEntryBase::getPosInImgSpace (int x, int y, rtengine::Coord2D &coord) +rtengine::Coord2D ThumbBrowserEntryBase::getPosInImgSpace (int x, int y) const { - - coord.x = coord.y = -1.; + rtengine::Coord2D coord(-1., -1.); if (preview) { x -= ofsX + startx; @@ -692,15 +687,16 @@ void ThumbBrowserEntryBase::getPosInImgSpace (int x, int y, rtengine::Coord2D &c coord.y = double(y - prey) / double(preh); } } + return coord; } -bool ThumbBrowserEntryBase::insideWindow (int x, int y, int w, int h) +bool ThumbBrowserEntryBase::insideWindow (int x, int y, int w, int h) const { return !(ofsX + startx > x + w || ofsX + startx + exp_width < x || ofsY + starty > y + h || ofsY + starty + exp_height < y); } -std::vector > ThumbBrowserEntryBase::getIconsOnImageArea() +std::vector> ThumbBrowserEntryBase::getIconsOnImageArea() { return std::vector >(); } @@ -710,12 +706,6 @@ std::vector > ThumbBrowserEntryBase::getSpecificityIco return std::vector >(); } -void ThumbBrowserEntryBase::getIconSize(int& w, int& h) -{ - w = 0; - h = 0; -} - bool ThumbBrowserEntryBase::motionNotify (int x, int y) { @@ -734,12 +724,12 @@ bool ThumbBrowserEntryBase::releaseNotify (int button, int type, int bstate, int return buttonSet ? buttonSet->releaseNotify (x, y) : false; } -Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) +Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) const { - Glib::ustring tooltip = ""; + Glib::ustring tooltip; if (buttonSet) { - tooltip = buttonSet->getToolTip (x, y); + tooltip = buttonSet->getToolTip(x, y); } // Always show the filename in the tooltip since the filename in the thumbnail could be truncated. @@ -748,11 +738,11 @@ Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) tooltip = dispname; if (withFilename < WFNAME_FULL) { - if (options.fbShowDateTime && datetimeline != "") { + if (options.fbShowDateTime && !datetimeline.empty()) { tooltip += Glib::ustring("\n") + datetimeline; } - if (options.fbShowBasicExif && exifline != "") { + if (options.fbShowBasicExif && !exifline.empty()) { tooltip += Glib::ustring("\n") + exifline; } } diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index 8237b7c6b..12e64c60d 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _THUMBNAILBROWSERENTRYBASE_ -#define _THUMBNAILBROWSERENTRYBASE_ +#pragma once #include @@ -82,8 +81,8 @@ protected: Glib::RefPtr backBuffer; bool bbSelected, bbFramed; guint8* bbPreview; - std::vector > bbIcons; - std::vector > bbSpecificityIcons; + std::vector> bbIcons; + std::vector> bbSpecificityIcons; CursorShape cursor_type; void drawFrame (Cairo::RefPtr cr, const Gdk::RGBA& bg, const Gdk::RGBA& fg); @@ -101,7 +100,6 @@ public: // thumbnail preview properties: Glib::ustring filename; - Glib::ustring shortname; Glib::ustring exifline; Glib::ustring datetimeline; @@ -117,61 +115,61 @@ public: bool updatepriority; eWithFilename withFilename; - explicit ThumbBrowserEntryBase (const Glib::ustring& fname); - virtual ~ThumbBrowserEntryBase (); + explicit ThumbBrowserEntryBase (const Glib::ustring& fname); + virtual ~ThumbBrowserEntryBase (); void setParent (ThumbBrowserBase* l) { parent = l; } - void updateBackBuffer (); - void resize (int h); - virtual void draw (Cairo::RefPtr cc); + void updateBackBuffer (); + void resize (int h); + virtual void draw (Cairo::RefPtr cc); - void addButtonSet (LWButtonSet* bs); - int getMinimalHeight () + void addButtonSet (LWButtonSet* bs); + int getMinimalHeight () const { return height; } - int getMinimalWidth () + int getMinimalWidth () const { return width; } - int getEffectiveWidth () const + int getEffectiveWidth () const { return exp_width; } - int getEffectiveHeight () const + int getEffectiveHeight () const { return exp_height; } - int getPreviewHeight () const + int getPreviewHeight () const { return preh; } - int getStartX () const + int getStartX () const { return startx; } - int getStartY () const + int getStartY () const { return starty; } - int getX () const + int getX () const { return ofsX + startx; } - int getY () const + int getY () const { return ofsY + starty; } - bool inside (int x, int y); - void getPosInImgSpace (int x, int y, rtengine::Coord2D &coord); - bool insideWindow (int x, int y, int w, int h); - void setPosition (int x, int y, int w, int h); + bool inside (int x, int y) const; + rtengine::Coord2D getPosInImgSpace (int x, int y) const; + bool insideWindow (int x, int y, int w, int h) const; + void setPosition (int x, int y, int w, int h); void setOffset (int x, int y); bool operator <(const ThumbBrowserEntryBase& other) const @@ -179,33 +177,29 @@ public: return collate_name < other.collate_name; } - ThumbBrowserEntryBase* getOriginal () const; - void setOriginal (ThumbBrowserEntryBase* original); - - virtual void refreshThumbnailImage () {} + virtual void refreshThumbnailImage () = 0; virtual void refreshQuickThumbnailImage () {} - virtual void calcThumbnailSize () {} + virtual void calcThumbnailSize () = 0; virtual void drawProgressBar (Glib::RefPtr win, const Gdk::RGBA& foregr, const Gdk::RGBA& backgr, int x, int w, int y, int h) {} - virtual std::vector > getIconsOnImageArea (); - virtual std::vector > getSpecificityIconsOnImageArea (); - virtual void getIconSize (int& w, int& h); + virtual std::vector> getIconsOnImageArea (); + virtual std::vector> getSpecificityIconsOnImageArea (); + virtual void getIconSize (int& w, int& h) const = 0; + + virtual bool motionNotify (int x, int y); + virtual bool pressNotify (int button, int type, int bstate, int x, int y); + virtual bool releaseNotify (int button, int type, int bstate, int x, int y); + virtual Glib::ustring getToolTip (int x, int y) const; + + inline ThumbBrowserEntryBase* getOriginal() const + { + return original; + } + + inline void setOriginal(ThumbBrowserEntryBase* original) + { + this->original = original; + } - virtual bool motionNotify (int x, int y); - virtual bool pressNotify (int button, int type, int bstate, int x, int y); - virtual bool releaseNotify (int button, int type, int bstate, int x, int y); - virtual Glib::ustring getToolTip (int x, int y); }; - -inline ThumbBrowserEntryBase* ThumbBrowserEntryBase::getOriginal() const -{ - return original; -} - -inline void ThumbBrowserEntryBase::setOriginal(ThumbBrowserEntryBase* original) -{ - this->original = original; -} - -#endif From 0493e674741924bc10b5ecc1ff33966af2dc94e3 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 20 Jul 2019 11:44:38 +0200 Subject: [PATCH 067/222] nuke empty adjusterAutoToggled functions --- rtgui/adjuster.h | 2 +- rtgui/bayerpreprocess.cc | 4 ---- rtgui/bayerpreprocess.h | 1 - rtgui/bayerrawexposure.cc | 4 ---- rtgui/bayerrawexposure.h | 1 - rtgui/blackwhite.cc | 4 ---- rtgui/blackwhite.h | 1 - rtgui/cacorrection.cc | 4 ---- rtgui/cacorrection.h | 1 - rtgui/chmixer.cc | 4 ---- rtgui/chmixer.h | 1 - rtgui/colortoning.cc | 4 ---- rtgui/colortoning.h | 1 - rtgui/defringe.cc | 4 ---- rtgui/defringe.h | 1 - rtgui/dehaze.h | 1 - rtgui/diagonalcurveeditorsubgroup.cc | 4 ---- rtgui/diagonalcurveeditorsubgroup.h | 1 - rtgui/dirpyrdenoise.cc | 4 ---- rtgui/dirpyrdenoise.h | 1 - rtgui/dirpyrequalizer.cc | 4 ---- rtgui/dirpyrequalizer.h | 1 - rtgui/distortion.cc | 4 ---- rtgui/distortion.h | 1 - rtgui/epd.cc | 4 ---- rtgui/epd.h | 1 - rtgui/fattaltonemap.cc | 4 ---- rtgui/fattaltonemap.h | 1 - rtgui/filmnegative.cc | 4 ---- rtgui/filmnegative.h | 1 - rtgui/filmsimulation.cc | 4 ---- rtgui/filmsimulation.h | 1 - rtgui/gradient.cc | 4 ---- rtgui/gradient.h | 1 - rtgui/iccprofilecreator.cc | 4 ---- rtgui/iccprofilecreator.h | 1 - rtgui/icmpanel.cc | 4 ---- rtgui/icmpanel.h | 1 - rtgui/impulsedenoise.cc | 4 ---- rtgui/impulsedenoise.h | 1 - rtgui/labcurve.cc | 4 ---- rtgui/labcurve.h | 1 - rtgui/localcontrast.cc | 4 ---- rtgui/localcontrast.h | 1 - rtgui/pcvignette.cc | 4 ---- rtgui/pcvignette.h | 1 - rtgui/perspective.cc | 4 ---- rtgui/perspective.h | 1 - rtgui/preprocess.cc | 4 ---- rtgui/preprocess.h | 1 - rtgui/prsharpening.cc | 4 ---- rtgui/prsharpening.h | 1 - rtgui/rawcacorrection.cc | 4 ---- rtgui/rawcacorrection.h | 1 - rtgui/rawexposure.cc | 4 ---- rtgui/rawexposure.h | 1 - rtgui/resize.cc | 4 ---- rtgui/resize.h | 1 - rtgui/retinex.cc | 4 ---- rtgui/retinex.h | 1 - rtgui/rotate.cc | 4 ---- rtgui/rotate.h | 1 - rtgui/saveformatpanel.cc | 4 ---- rtgui/saveformatpanel.h | 1 - rtgui/shadowshighlights.cc | 4 ---- rtgui/shadowshighlights.h | 1 - rtgui/sharpenedge.cc | 4 ---- rtgui/sharpenedge.h | 1 - rtgui/sharpening.cc | 4 ---- rtgui/sharpening.h | 1 - rtgui/sharpenmicro.cc | 4 ---- rtgui/sharpenmicro.h | 1 - rtgui/softlight.cc | 6 ------ rtgui/softlight.h | 1 - rtgui/tonecurve.cc | 4 ---- rtgui/tonecurve.h | 1 - rtgui/vibrance.cc | 4 ---- rtgui/vibrance.h | 1 - rtgui/vignetting.cc | 4 ---- rtgui/vignetting.h | 1 - rtgui/wavelet.cc | 4 ---- rtgui/wavelet.h | 1 - rtgui/whitebalance.cc | 4 ---- rtgui/whitebalance.h | 1 - rtgui/xtransrawexposure.cc | 4 ---- rtgui/xtransrawexposure.h | 1 - 86 files changed, 1 insertion(+), 214 deletions(-) diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h index f57129bf1..f3f256940 100644 --- a/rtgui/adjuster.h +++ b/rtgui/adjuster.h @@ -30,7 +30,7 @@ class AdjusterListener public: virtual ~AdjusterListener() = default; virtual void adjusterChanged (Adjuster* a, double newval) = 0; - virtual void adjusterAutoToggled (Adjuster* a, bool newval) = 0; + virtual void adjusterAutoToggled (Adjuster* a, bool newval) {} }; typedef double(*double2double_fun)(double val); diff --git a/rtgui/bayerpreprocess.cc b/rtgui/bayerpreprocess.cc index 35f36e83e..0ba60d045 100644 --- a/rtgui/bayerpreprocess.cc +++ b/rtgui/bayerpreprocess.cc @@ -143,10 +143,6 @@ void BayerPreProcess::adjusterChanged(Adjuster* a, double newval) } } -void BayerPreProcess::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void BayerPreProcess::setBatchMode(bool batchMode) { ToolPanel::setBatchMode(batchMode); diff --git a/rtgui/bayerpreprocess.h b/rtgui/bayerpreprocess.h index e06a46d31..f50ac90bb 100644 --- a/rtgui/bayerpreprocess.h +++ b/rtgui/bayerpreprocess.h @@ -47,7 +47,6 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void hotDeadPixelChanged(); void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd); diff --git a/rtgui/bayerrawexposure.cc b/rtgui/bayerrawexposure.cc index f9027c09f..12158c774 100644 --- a/rtgui/bayerrawexposure.cc +++ b/rtgui/bayerrawexposure.cc @@ -152,10 +152,6 @@ void BayerRAWExposure::adjusterChanged(Adjuster* a, double newval) } } -void BayerRAWExposure::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void BayerRAWExposure::checkBoxToggled (CheckBox* c, CheckValue newval) { if (c == PextwoGreen) { diff --git a/rtgui/bayerrawexposure.h b/rtgui/bayerrawexposure.h index 08d415838..e955afc12 100644 --- a/rtgui/bayerrawexposure.h +++ b/rtgui/bayerrawexposure.h @@ -43,7 +43,6 @@ public: void setBatchMode (bool batchMode) override; void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void checkBoxToggled (CheckBox* c, CheckValue newval) override; void setAdjusterBehavior (bool pexblackadd); void trimValues (rtengine::procparams::ProcParams* pp) override; diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index 3d5deb8f2..2b97188e2 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -1150,10 +1150,6 @@ void BlackWhite::adjusterChanged(Adjuster* a, double newval) } } -void BlackWhite::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void BlackWhite::updateRGBLabel () { if (!batchMode) { diff --git a/rtgui/blackwhite.h b/rtgui/blackwhite.h index dd45a7729..242926924 100644 --- a/rtgui/blackwhite.h +++ b/rtgui/blackwhite.h @@ -55,7 +55,6 @@ public: void updateRGBLabel (); void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void setAdjusterBehavior (bool bwadd, bool bwgadd); void trimValues (rtengine::procparams::ProcParams* pp) override; void enabledcc_toggled (); diff --git a/rtgui/cacorrection.cc b/rtgui/cacorrection.cc index c91eec145..5b66dd6c3 100644 --- a/rtgui/cacorrection.cc +++ b/rtgui/cacorrection.cc @@ -101,10 +101,6 @@ void CACorrection::adjusterChanged (Adjuster* a, double newval) } } -void CACorrection::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void CACorrection::setAdjusterBehavior (bool badd) { diff --git a/rtgui/cacorrection.h b/rtgui/cacorrection.h index 198037060..4fa85038c 100644 --- a/rtgui/cacorrection.h +++ b/rtgui/cacorrection.h @@ -40,7 +40,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void setAdjusterBehavior (bool badd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; diff --git a/rtgui/chmixer.cc b/rtgui/chmixer.cc index 4a3411e8b..82e885f08 100644 --- a/rtgui/chmixer.cc +++ b/rtgui/chmixer.cc @@ -182,10 +182,6 @@ void ChMixer::adjusterChanged(Adjuster* a, double newval) } } -void ChMixer::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void ChMixer::enabledChanged() { if (listener) { diff --git a/rtgui/chmixer.h b/rtgui/chmixer.h index 7e372cbc2..a0fff9b26 100644 --- a/rtgui/chmixer.h +++ b/rtgui/chmixer.h @@ -42,7 +42,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void setAdjusterBehavior (bool rgbadd); void trimValues (rtengine::procparams::ProcParams* pp) override; void enabledChanged() override; diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 7ca9a7305..e164739e5 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -1372,10 +1372,6 @@ void ColorToning::adjusterChanged(Adjuster* a, double newval) } } -void ColorToning::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void ColorToning::setBatchMode (bool batchMode) { ToolPanel::setBatchMode (batchMode); diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h index abb44d09c..faba1e383 100644 --- a/rtgui/colortoning.h +++ b/rtgui/colortoning.h @@ -33,7 +33,6 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void trimValues (rtengine::procparams::ProcParams* pp) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool satOpacityAdd, bool strprotectAdd, bool balanceAdd); void neutral_pressed (); //void neutralCurves_pressed (); diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc index 7d29b8c8f..03bf648dd 100644 --- a/rtgui/defringe.cc +++ b/rtgui/defringe.cc @@ -164,10 +164,6 @@ void Defringe::adjusterChanged(Adjuster* a, double newval) } } -void Defringe::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Defringe::enabledChanged () { diff --git a/rtgui/defringe.h b/rtgui/defringe.h index 1aa6cc303..c02fd8d6a 100644 --- a/rtgui/defringe.h +++ b/rtgui/defringe.h @@ -50,7 +50,6 @@ public: void curveChanged () override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; diff --git a/rtgui/dehaze.h b/rtgui/dehaze.h index 322e0bf0c..66720a9fd 100644 --- a/rtgui/dehaze.h +++ b/rtgui/dehaze.h @@ -48,6 +48,5 @@ public: void enabledChanged() override; void showDepthMapChanged(); void setAdjusterBehavior(bool strengthAdd); - void adjusterAutoToggled(Adjuster* a, bool newval) override {} }; diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index 86ff26bb4..9e2406309 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -1246,10 +1246,6 @@ void DiagonalCurveEditorSubGroup::adjusterChanged(Adjuster* a, double newval) parent->curveChanged (); } -void DiagonalCurveEditorSubGroup::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - /* * Listener called when the mouse is over a parametric curve's slider */ diff --git a/rtgui/diagonalcurveeditorsubgroup.h b/rtgui/diagonalcurveeditorsubgroup.h index 39cc86973..54f424dc6 100644 --- a/rtgui/diagonalcurveeditorsubgroup.h +++ b/rtgui/diagonalcurveeditorsubgroup.h @@ -105,7 +105,6 @@ protected: const std::vector getCurveFromGUI (int type) override; void shcChanged () override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; bool adjusterEntered (GdkEventCrossing* ev, int ac); bool adjusterLeft (GdkEventCrossing* ev, int ac); void setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4); diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index c60c06243..c3528d5dd 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -988,10 +988,6 @@ void DirPyrDenoise::adjusterChanged(Adjuster* a, double newval) } } -void DirPyrDenoise::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void DirPyrDenoise::enabledChanged () { diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index de7dee800..7bdaff853 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -51,7 +51,6 @@ public: void autoOpenCurve () override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void medianChanged (); void chromaChanged (double autchroma, double autred, double autblue) override; diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index 5f557c0f1..be6f9c97b 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -373,10 +373,6 @@ void DirPyrEqualizer::adjusterChanged(Adjuster* a, double newval) } } -void DirPyrEqualizer::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void DirPyrEqualizer::enabledChanged () { diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index d7903116b..4eb110428 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -65,7 +65,6 @@ public: void trimValues (rtengine::procparams::ProcParams* pp) override; void cbdlMethodChanged(); void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged() override; void gamutlabToggled (); void lumaneutralPressed (); diff --git a/rtgui/distortion.cc b/rtgui/distortion.cc index 0ac067ba8..3620dbc21 100644 --- a/rtgui/distortion.cc +++ b/rtgui/distortion.cc @@ -95,10 +95,6 @@ void Distortion::adjusterChanged(Adjuster* a, double newval) } } -void Distortion::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Distortion::setBatchMode (bool batchMode) { diff --git a/rtgui/distortion.h b/rtgui/distortion.h index ce1e81046..a279913cb 100644 --- a/rtgui/distortion.h +++ b/rtgui/distortion.h @@ -43,7 +43,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void setAdjusterBehavior (bool vadd); void trimValues (rtengine::procparams::ProcParams* pp) override; void idPressed (); diff --git a/rtgui/epd.cc b/rtgui/epd.cc index 4b7cca10a..ab6341866 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -159,10 +159,6 @@ void EdgePreservingDecompositionUI::adjusterChanged(Adjuster* a, double newval) } } -void EdgePreservingDecompositionUI::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void EdgePreservingDecompositionUI::enabledChanged () { if (listener) { diff --git a/rtgui/epd.h b/rtgui/epd.h index f2073a976..6b44d9147 100644 --- a/rtgui/epd.h +++ b/rtgui/epd.h @@ -42,7 +42,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void setAdjusterBehavior (bool stAdd, bool gAdd, bool esAdd, bool scAdd, bool rAdd); }; diff --git a/rtgui/fattaltonemap.cc b/rtgui/fattaltonemap.cc index 85d835cc7..032df6f40 100644 --- a/rtgui/fattaltonemap.cc +++ b/rtgui/fattaltonemap.cc @@ -119,10 +119,6 @@ void FattalToneMapping::adjusterChanged(Adjuster* a, double newval) } } -void FattalToneMapping::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void FattalToneMapping::enabledChanged () { if (listener) { diff --git a/rtgui/fattaltonemap.h b/rtgui/fattaltonemap.h index 76e850c4e..e6eafb605 100644 --- a/rtgui/fattaltonemap.h +++ b/rtgui/fattaltonemap.h @@ -42,7 +42,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void setAdjusterBehavior(bool amountAdd, bool thresholdAdd, bool anchorAdd); }; diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 3464f7e46..6e93b2364 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -200,10 +200,6 @@ void FilmNegative::adjusterChanged(Adjuster* a, double newval) } } -void FilmNegative::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void FilmNegative::enabledChanged() { if (listener) { diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 7de1bd56a..e967f535c 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -55,7 +55,6 @@ public: void setBatchMode(bool batchMode) override; void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged() override; void setFilmNegProvider(FilmNegProvider* provider); diff --git a/rtgui/filmsimulation.cc b/rtgui/filmsimulation.cc index 734b46c34..6b40bb586 100644 --- a/rtgui/filmsimulation.cc +++ b/rtgui/filmsimulation.cc @@ -115,10 +115,6 @@ void FilmSimulation::adjusterChanged(Adjuster* a, double newval) } } -void FilmSimulation::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void FilmSimulation::setBatchMode( bool batchMode ) { ToolPanel::setBatchMode( batchMode ); diff --git a/rtgui/filmsimulation.h b/rtgui/filmsimulation.h index c55662757..b5c9ffa6b 100644 --- a/rtgui/filmsimulation.h +++ b/rtgui/filmsimulation.h @@ -56,7 +56,6 @@ public: FilmSimulation(); void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void setBatchMode(bool batchMode) override; void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index 4961597bb..d7b2cb7c2 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -269,10 +269,6 @@ void Gradient::adjusterChanged(Adjuster* a, double newval) } } -void Gradient::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Gradient::enabledChanged () { diff --git a/rtgui/gradient.h b/rtgui/gradient.h index 8aa4a5339..05a267a0d 100644 --- a/rtgui/gradient.h +++ b/rtgui/gradient.h @@ -43,7 +43,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void setAdjusterBehavior (bool degreeadd, bool featheradd, bool strengthadd, bool centeradd); void trimValues (rtengine::procparams::ProcParams* pp) override; diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index e5172c7e7..0ab1ac61d 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -389,10 +389,6 @@ void ICCProfileCreator::adjusterChanged(Adjuster* a, double newval) } } -void ICCProfileCreator::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void ICCProfileCreator::primariesChanged() { if (primaries->get_active_row_number() > 0) { diff --git a/rtgui/iccprofilecreator.h b/rtgui/iccprofilecreator.h index 23e5b86c8..5265d5ab2 100644 --- a/rtgui/iccprofilecreator.h +++ b/rtgui/iccprofilecreator.h @@ -92,7 +92,6 @@ private: void illuminantChanged(); void trcPresetsChanged(); void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; static std::vector getGamma(); Glib::ustring getPrimariesPresetName(const Glib::ustring &preset); void getPrimaries(const Glib::ustring &preset, double *p, ColorTemp &temp); diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index ba8bf9cef..ca025ec75 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -701,10 +701,6 @@ void ICMPanel::adjusterChanged(Adjuster* a, double newval) } } -void ICMPanel::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void ICMPanel::wpChanged() { if (listener) { diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index b1106b6e1..a03bd6fa7 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -126,7 +126,6 @@ public: void setBatchMode(bool batchMode) override; void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void wpChanged(); void wtrcinChanged(); diff --git a/rtgui/impulsedenoise.cc b/rtgui/impulsedenoise.cc index 9203ce8a7..d4ecebfb5 100644 --- a/rtgui/impulsedenoise.cc +++ b/rtgui/impulsedenoise.cc @@ -88,10 +88,6 @@ void ImpulseDenoise::adjusterChanged(Adjuster* a, double newval) } } -void ImpulseDenoise::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void ImpulseDenoise::enabledChanged () { if (listener) { diff --git a/rtgui/impulsedenoise.h b/rtgui/impulsedenoise.h index 79484dc65..ae6aaa6a8 100644 --- a/rtgui/impulsedenoise.h +++ b/rtgui/impulsedenoise.h @@ -40,7 +40,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void setAdjusterBehavior (bool threshadd); diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index f458fa717..4b25c1e4f 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -567,10 +567,6 @@ void LCurve::adjusterChanged(Adjuster* a, double newval) } } -void LCurve::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void LCurve::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index b727cca84..db75a686a 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -77,7 +77,6 @@ public: void curveChanged (CurveEditor* ce) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void avoidcolorshift_toggled (); void lcredsk_toggled(); diff --git a/rtgui/localcontrast.cc b/rtgui/localcontrast.cc index 93b67657d..cc4922a65 100644 --- a/rtgui/localcontrast.cc +++ b/rtgui/localcontrast.cc @@ -134,10 +134,6 @@ void LocalContrast::adjusterChanged(Adjuster* a, double newval) } } -void LocalContrast::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void LocalContrast::enabledChanged () { if (listener) { diff --git a/rtgui/localcontrast.h b/rtgui/localcontrast.h index efe7a18f0..529c95c89 100644 --- a/rtgui/localcontrast.h +++ b/rtgui/localcontrast.h @@ -47,7 +47,6 @@ public: void setBatchMode(bool batchMode) override; void adjusterChanged(Adjuster *a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged() override; void setAdjusterBehavior(bool radiusAdd, bool amountAdd, bool darknessAdd, bool lightnessAdd); }; diff --git a/rtgui/pcvignette.cc b/rtgui/pcvignette.cc index 303ae5cfb..9c141d618 100644 --- a/rtgui/pcvignette.cc +++ b/rtgui/pcvignette.cc @@ -93,10 +93,6 @@ void PCVignette::adjusterChanged(Adjuster* a, double newval) } } -void PCVignette::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void PCVignette::enabledChanged () { diff --git a/rtgui/pcvignette.h b/rtgui/pcvignette.h index 98d42a477..ce41ab75f 100644 --- a/rtgui/pcvignette.h +++ b/rtgui/pcvignette.h @@ -26,7 +26,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void setAdjusterBehavior (bool strengthadd, bool featheradd, bool roundnessadd); void trimValues (rtengine::procparams::ProcParams* pp) override; diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index db2f32248..752b2289b 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -98,10 +98,6 @@ void PerspCorrection::adjusterChanged(Adjuster* a, double newval) } } -void PerspCorrection::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void PerspCorrection::setAdjusterBehavior (bool badd) { diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 8038120fa..77fedc84a 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -40,7 +40,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void setAdjusterBehavior (bool badd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc index 92cd06bc1..07e378832 100644 --- a/rtgui/preprocess.cc +++ b/rtgui/preprocess.cc @@ -101,10 +101,6 @@ void PreProcess::adjusterChanged(Adjuster* a, double newval) } } -void PreProcess::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void PreProcess::hotPixelChanged () { if (batchMode) { diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h index 58cc2c2de..ced119d7d 100644 --- a/rtgui/preprocess.h +++ b/rtgui/preprocess.h @@ -48,7 +48,6 @@ public: void hotPixelChanged(); void deadPixelChanged(); void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; //void adjusterChanged (Adjuster* a, double newval); diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc index c7c2ddf9f..b12da977d 100644 --- a/rtgui/prsharpening.cc +++ b/rtgui/prsharpening.cc @@ -350,10 +350,6 @@ void PrSharpening::adjusterChanged (Adjuster* a, double newval) } } -void PrSharpening::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void PrSharpening::enabledChanged () { if (listener) { diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h index 0bceca856..d8a27c188 100644 --- a/rtgui/prsharpening.h +++ b/rtgui/prsharpening.h @@ -65,7 +65,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void edgesonly_toggled (); void halocontrol_toggled (); diff --git a/rtgui/rawcacorrection.cc b/rtgui/rawcacorrection.cc index a6b624562..003d8b629 100644 --- a/rtgui/rawcacorrection.cc +++ b/rtgui/rawcacorrection.cc @@ -144,10 +144,6 @@ void RAWCACorr::adjusterChanged(Adjuster* a, double newval) } } -void RAWCACorr::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void RAWCACorr::checkBoxToggled (CheckBox* c, CheckValue newval) { if (c == caAutocorrect) { diff --git a/rtgui/rawcacorrection.h b/rtgui/rawcacorrection.h index 13db1d1e3..ab80bd3ea 100644 --- a/rtgui/rawcacorrection.h +++ b/rtgui/rawcacorrection.h @@ -50,7 +50,6 @@ public: void trimValues (rtengine::procparams::ProcParams* pp) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void checkBoxToggled (CheckBox* c, CheckValue newval) override; }; diff --git a/rtgui/rawexposure.cc b/rtgui/rawexposure.cc index 599c8fd12..f8885eb76 100644 --- a/rtgui/rawexposure.cc +++ b/rtgui/rawexposure.cc @@ -76,10 +76,6 @@ void RAWExposure::adjusterChanged(Adjuster* a, double newval) } } -void RAWExposure::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void RAWExposure::setBatchMode(bool batchMode) { ToolPanel::setBatchMode (batchMode); diff --git a/rtgui/rawexposure.h b/rtgui/rawexposure.h index f34776d19..95a15ade2 100644 --- a/rtgui/rawexposure.h +++ b/rtgui/rawexposure.h @@ -41,7 +41,6 @@ public: void setBatchMode (bool batchMode) override; void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void setAdjusterBehavior (bool pexposadd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 106715a17..3789d4693 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -273,10 +273,6 @@ void Resize::adjusterChanged(Adjuster* a, double newval) } } -void Resize::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - int Resize::getComputedWidth() { diff --git a/rtgui/resize.h b/rtgui/resize.h index 3c599808d..3bcfe3f84 100644 --- a/rtgui/resize.h +++ b/rtgui/resize.h @@ -46,7 +46,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void entryWChanged (); void entryHChanged (); void appliesToChanged (); diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 544ace535..e074d7e9c 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -1362,10 +1362,6 @@ void Retinex::adjusterChanged(Adjuster* a, double newval) } } -void Retinex::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Retinex::autoOpenCurve () { cdshape->openIfNonlinear(); diff --git a/rtgui/retinex.h b/rtgui/retinex.h index 8703ec607..1be511cb3 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -104,7 +104,6 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void trimValues (rtengine::procparams::ProcParams* pp) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void autoOpenCurve () override; void medianmapChanged (); void minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) override; diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc index 9f5d665d5..822443cf8 100644 --- a/rtgui/rotate.cc +++ b/rtgui/rotate.cc @@ -96,10 +96,6 @@ void Rotate::adjusterChanged(Adjuster* a, double newval) } } -void Rotate::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Rotate::straighten (double deg) { diff --git a/rtgui/rotate.h b/rtgui/rotate.h index c23807361..c3d18fecb 100644 --- a/rtgui/rotate.h +++ b/rtgui/rotate.h @@ -44,7 +44,6 @@ public: void straighten (double deg); void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void setAdjusterBehavior (bool rotadd); void trimValues (rtengine::procparams::ProcParams* pp) override; void selectStraightPressed (); diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc index de2240fc6..483565446 100644 --- a/rtgui/saveformatpanel.cc +++ b/rtgui/saveformatpanel.cc @@ -218,7 +218,3 @@ void SaveFormatPanel::adjusterChanged(Adjuster* a, double newval) listener->formatChanged(sf_templates[act].second.format); } } - -void SaveFormatPanel::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index 48fa97e13..e25210b97 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -60,7 +60,6 @@ public: void formatChanged (); void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; }; #endif diff --git a/rtgui/shadowshighlights.cc b/rtgui/shadowshighlights.cc index 6fdf6f2f3..f58790051 100644 --- a/rtgui/shadowshighlights.cc +++ b/rtgui/shadowshighlights.cc @@ -172,10 +172,6 @@ void ShadowsHighlights::adjusterChanged (Adjuster* a, double newval) } } -void ShadowsHighlights::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void ShadowsHighlights::enabledChanged () { diff --git a/rtgui/shadowshighlights.h b/rtgui/shadowshighlights.h index e04e2000a..5e56e0766 100644 --- a/rtgui/shadowshighlights.h +++ b/rtgui/shadowshighlights.h @@ -46,7 +46,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void setAdjusterBehavior (bool hadd, bool sadd); diff --git a/rtgui/sharpenedge.cc b/rtgui/sharpenedge.cc index 968cb75ad..9d6466543 100644 --- a/rtgui/sharpenedge.cc +++ b/rtgui/sharpenedge.cc @@ -147,10 +147,6 @@ void SharpenEdge::adjusterChanged(Adjuster* a, double newval) } } -void SharpenEdge::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void SharpenEdge::setBatchMode(bool batchMode) { passes->showEditedCB (); diff --git a/rtgui/sharpenedge.h b/rtgui/sharpenedge.h index 8bf5647ed..a08c63b8a 100644 --- a/rtgui/sharpenedge.h +++ b/rtgui/sharpenedge.h @@ -51,7 +51,6 @@ public: void trimValues (rtengine::procparams::ProcParams* pp) override; void setAdjusterBehavior (bool amountadd, bool passadd); void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void enabledChanged () override; void chanthree_toggled (); diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index 8a7b8e591..e698872dd 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -356,10 +356,6 @@ void Sharpening::adjusterChanged(Adjuster* a, double newval) } } -void Sharpening::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Sharpening::adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) { } diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index 75ea083c9..b9f093aae 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -68,7 +68,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged () override; void edgesonly_toggled (); void halocontrol_toggled (); diff --git a/rtgui/sharpenmicro.cc b/rtgui/sharpenmicro.cc index 0b4142677..1d765652b 100644 --- a/rtgui/sharpenmicro.cc +++ b/rtgui/sharpenmicro.cc @@ -156,10 +156,6 @@ void SharpenMicro::adjusterChanged(Adjuster* a, double newval) } } -void SharpenMicro::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void SharpenMicro::setBatchMode(bool batchMode) { amount->showEditedCB (); diff --git a/rtgui/sharpenmicro.h b/rtgui/sharpenmicro.h index 6dfccea85..8cb95b806 100644 --- a/rtgui/sharpenmicro.h +++ b/rtgui/sharpenmicro.h @@ -54,7 +54,6 @@ public: void trimValues (rtengine::procparams::ProcParams* pp) override; void setAdjusterBehavior (bool amountadd, bool contrastadd, bool uniformityadd); void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void enabledChanged () override; void matrix_toggled (); diff --git a/rtgui/softlight.cc b/rtgui/softlight.cc index 0054f8f6d..90c3890cd 100644 --- a/rtgui/softlight.cc +++ b/rtgui/softlight.cc @@ -89,12 +89,6 @@ void SoftLight::adjusterChanged(Adjuster* a, double newval) } } - -void SoftLight::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - - void SoftLight::enabledChanged () { if (listener) { diff --git a/rtgui/softlight.h b/rtgui/softlight.h index a036592e4..f6ed8370d 100644 --- a/rtgui/softlight.h +++ b/rtgui/softlight.h @@ -41,7 +41,6 @@ public: void setBatchMode(bool batchMode) override; void adjusterChanged(Adjuster *a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged() override; void setAdjusterBehavior(bool strengthAdd); }; diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 91b268e9c..e0e475b4e 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -645,10 +645,6 @@ void ToneCurve::adjusterChanged(Adjuster* a, double newval) } } -void ToneCurve::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void ToneCurve::neutral_pressed () { // This method deselects auto levels and HL reconstruction auto diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index 29b484137..512dd4d5f 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -104,7 +104,6 @@ public: float blendPipetteValues (CurveEditor *ce, float chan1, float chan2, float chan3) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void neutral_pressed (); void autolevels_toggled (); void clip_changed (); diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc index 0069576e0..82944bb81 100644 --- a/rtgui/vibrance.cc +++ b/rtgui/vibrance.cc @@ -290,10 +290,6 @@ void Vibrance::adjusterChanged(Adjuster* a, double newval) } } -void Vibrance::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Vibrance::adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) { } diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h index ed3e10059..81d811f14 100644 --- a/rtgui/vibrance.h +++ b/rtgui/vibrance.h @@ -61,7 +61,6 @@ public: void trimValues (rtengine::procparams::ProcParams* pp) override; void setAdjusterBehavior (bool pastelsadd, bool saturatedadd); void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void curveChanged () override; void autoOpenCurve () override; diff --git a/rtgui/vignetting.cc b/rtgui/vignetting.cc index 799a4cff7..87a835625 100644 --- a/rtgui/vignetting.cc +++ b/rtgui/vignetting.cc @@ -129,10 +129,6 @@ void Vignetting::adjusterChanged(Adjuster* a, double newval) } } -void Vignetting::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Vignetting::setAdjusterBehavior (bool amountadd, bool radiusadd, bool strengthadd, bool centeradd) { diff --git a/rtgui/vignetting.h b/rtgui/vignetting.h index 5432b6178..edd818431 100644 --- a/rtgui/vignetting.h +++ b/rtgui/vignetting.h @@ -43,7 +43,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void setAdjusterBehavior (bool amountadd, bool radiusadd, bool strengthadd, bool centeradd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 942608414..bc59de087 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -2513,10 +2513,6 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) } } -void Wavelet::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void Wavelet::enabledUpdateUI () { if (!batchMode) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 90a72f623..4df743fa7 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -46,7 +46,6 @@ public: bool wavComputed_ (); void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; void autoOpenCurve () override; void curveChanged (CurveEditor* ce) override; void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 3c3382bc3..761dc5e04 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -434,10 +434,6 @@ void WhiteBalance::adjusterChanged(Adjuster* a, double newval) } } -void WhiteBalance::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void WhiteBalance::optChanged () { Gtk::TreeModel::Row row = getActiveMethod(); diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 2db46b7af..52c4b7f8c 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -107,7 +107,6 @@ public: void spotPressed (); void spotSizeChanged (); void adjusterChanged(Adjuster* a, double newval) override; - void adjusterAutoToggled(Adjuster* a, bool newval) override; int getSize (); void setWBProvider (WBProvider* p) { diff --git a/rtgui/xtransrawexposure.cc b/rtgui/xtransrawexposure.cc index 93f6ee202..c4f7d7059 100644 --- a/rtgui/xtransrawexposure.cc +++ b/rtgui/xtransrawexposure.cc @@ -110,10 +110,6 @@ void XTransRAWExposure::adjusterChanged(Adjuster* a, double newval) } } -void XTransRAWExposure::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void XTransRAWExposure::setBatchMode(bool batchMode) { ToolPanel::setBatchMode (batchMode); diff --git a/rtgui/xtransrawexposure.h b/rtgui/xtransrawexposure.h index 75bdbd0e2..54b3de767 100644 --- a/rtgui/xtransrawexposure.h +++ b/rtgui/xtransrawexposure.h @@ -43,7 +43,6 @@ public: void setBatchMode (bool batchMode) override; void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged (Adjuster* a, double newval) override; - void adjusterAutoToggled (Adjuster* a, bool newval) override; void setAdjusterBehavior (bool pexblackadd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; From 2dee88428fe5b002c6c8304883aaa6a57f384086 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Sun, 21 Jul 2019 13:18:31 +0200 Subject: [PATCH 068/222] Japanese localization updated by Yz2house, closes #5384 --- rtdata/languages/Deutsch | 22 +++++++++------------ rtdata/languages/Japanese | 40 ++++++++++++++++++--------------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 63595e328..7967786dd 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -829,6 +829,8 @@ HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;(Bildschleier entfernen)\nMaske anzeigen HISTORY_MSG_DEHAZE_STRENGTH;(Bildschleier entfernen)\nIntensität HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;(Sensor—Matrix)\nFarbinterpolation\nAuto-Kontrastschwelle HISTORY_MSG_DUALDEMOSAIC_CONTRAST;(Sensor-Matrix)\nFarbinterpolation\nKontrastschwelle +HISTORY_MSG_FILMNEGATIVE_ENABLED;(Filmnegativ) +HISTORY_MSG_FILMNEGATIVE_VALUES;(Filmnegativ) - Werte HISTORY_MSG_HISTMATCHING;(Belichtung)\nAuto-Tonwertkurve HISTORY_MSG_ICM_OUTPUT_PRIMARIES;(Farbmanagement)\nAusgabeprofil\nVorlagen HISTORY_MSG_ICM_OUTPUT_TEMP;(Farbmanagement)\nAusgabeprofil\nIccV4-Illuminant D @@ -1065,6 +1067,7 @@ PARTIALPASTE_EQUALIZER;Wavelet PARTIALPASTE_EVERYTHING;Alle Parameter aktivieren / deaktivieren PARTIALPASTE_EXIFCHANGES;Änderungen an Exif-Daten PARTIALPASTE_EXPOSURE;Belichtung +PARTIALPASTE_FILMNEGATIVE;Filmnegativ PARTIALPASTE_FILMSIMULATION;Filmsimulation PARTIALPASTE_FLATFIELDAUTOSELECT;Weißbild: Automatische Auswahl PARTIALPASTE_FLATFIELDBLURRADIUS;Weißbild: Unschärferadius @@ -1718,6 +1721,12 @@ TP_EXPOSURE_TCMODE_STANDARD;Standard TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewichteter Standard TP_EXPOS_BLACKPOINT_LABEL;Schwarzpunkt TP_EXPOS_WHITEPOINT_LABEL;Weißpunkt +TP_FILMNEGATIVE_BLUE;Blauverhältnis +TP_FILMNEGATIVE_GREEN;Bezugsexponent (Kontrast) +TP_FILMNEGATIVE_GUESS_TOOLTIP;Berechnet die Exponenten durch Auswahl zweier neutraler\nReferenzpunkte im Bild. Weiß (Hellgrau) und Schwarz (Dunkelgrau).\nDie Reihenfolge spielt keine Rolle. Die Exponenten werden aktualisiert,\nnachdem der zweite Punkt ausgewählt wurde. +TP_FILMNEGATIVE_LABEL;Filmnegativ +TP_FILMNEGATIVE_PICK;Weißen und schwarzen Bereich auswählen +TP_FILMNEGATIVE_RED;Rotverhältnis TP_FILMSIMULATION_LABEL;Filmsimulation TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee sucht nach Hald-CLUT-Bildern, die für die Filmsimulation benötigt werden, in einem Ordner, der viel Zeit benötigt.\nGehen Sie zu\n< Einstellungen > Bildbearbeitung > Filmsimulation >\nund prüfen Sie welcher Order benutzt wird. Wählen Sie den Ordner aus, der nur die Hald-CLUT-Bilder beinhaltet, oder einen leeren Ordner, wenn Sie die Filsimulation nicht verwenden möchten.\n\nWeitere Informationen über die Filmsimulation finden Sie auf RawPedia.\n\nMöchten Sie die Suche beenden? TP_FILMSIMULATION_STRENGTH;Intensität @@ -2362,16 +2371,3 @@ ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen.\nTaste: Alt + f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -HISTORY_MSG_FILMNEGATIVE_ENABLED;(Filmnegativ) -HISTORY_MSG_FILMNEGATIVE_VALUES;(Filmnegativ) - Werte -PARTIALPASTE_FILMNEGATIVE;Filmnegativ -TP_FILMNEGATIVE_BLUE;Blauverhältnis -TP_FILMNEGATIVE_GREEN;Bezugsexponent (Kontrast) -TP_FILMNEGATIVE_GUESS_TOOLTIP;Berechnet die Exponenten durch Auswahl zweier neutraler\nReferenzpunkte im Bild. Weiß (Hellgrau) und Schwarz (Dunkelgrau).\nDie Reihenfolge spielt keine Rolle. Die Exponenten werden aktualisiert,\nnachdem der zweite Punkt ausgewählt wurde. -TP_FILMNEGATIVE_LABEL;Filmnegativ -TP_FILMNEGATIVE_PICK;Weißen und schwarzen Bereich auswählen -TP_FILMNEGATIVE_RED;Rotverhältnis diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 316133b3a..96ffea174 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -152,8 +152,12 @@ FILEBROWSER_COLORLABEL_TOOLTIP;カラー・ラベル\n\nドロップダウン・ FILEBROWSER_COPYPROFILE;プロファイルをコピー FILEBROWSER_CURRENT_NAME;現在の名前: FILEBROWSER_DARKFRAME;ダークフレーム +FILEBROWSER_DELETEDIALOG_ALL;ゴミ箱の中にある%1枚のファイル全てを完全に削除しますか? FILEBROWSER_DELETEDIALOG_HEADER;ファイル削除確認 +FILEBROWSER_DELETEDIALOG_SELECTED;選択した%1枚のファイルを完全に削除しますか? +FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;キュー処理に保持されているファイルを含め、選択した%1枚のファイルを完全に削除しますか? FILEBROWSER_EMPTYTRASH;ゴミ箱を空にする +FILEBROWSER_EMPTYTRASHHINT;ゴミ箱の中のファイルを全て完全に 削除します FILEBROWSER_EXTPROGMENU;..で開く FILEBROWSER_FLATFIELD;フラットフィールド FILEBROWSER_MOVETODARKFDIR;ダークフレーム・ディレクトリに移動 @@ -187,6 +191,8 @@ FILEBROWSER_POPUPRANK2;ランク 2 ** FILEBROWSER_POPUPRANK3;ランク 3 *** FILEBROWSER_POPUPRANK4;ランク 4 **** FILEBROWSER_POPUPRANK5;ランク 5 ***** +FILEBROWSER_POPUPREMOVE;完全に削除 +FILEBROWSER_POPUPREMOVEINCLPROC;キュー処理に保持されているファイルを含めて完全に削除 FILEBROWSER_POPUPRENAME;名前変更 FILEBROWSER_POPUPSELECTALL;全選択 FILEBROWSER_POPUPTRASH;ゴミ箱へ移動 @@ -213,6 +219,7 @@ FILEBROWSER_SHOWDIRHINT;全ての絞り込みをクリア\nショートカット FILEBROWSER_SHOWEDITEDHINT;編集済み画像を表示\nショートカット: 7 FILEBROWSER_SHOWEDITEDNOTHINT;未編集画像を表示\nショートカット: 6 FILEBROWSER_SHOWEXIFINFO;EXIF情報を表示\nショートカット: i\n\nシングル・エディタ・タブのショートカット: Alt-i +FILEBROWSER_SHOWNOTTRASHHINT;ゴミ箱の中にある画像だけを表示 FILEBROWSER_SHOWORIGINALHINT;元画像だけを表示\n\nファイル名は同じだが拡張子が異なる画像がある場合は、環境設定の中のファイルブラウザタブにある拡張子リストの上位に位置する拡張子を持った画像を元画像とする。 FILEBROWSER_SHOWRANK1HINT;1つ星ランクを表示\nショートカット: 1 FILEBROWSER_SHOWRANK2HINT;2つ星ランクを表示\nショートカット: 2 @@ -771,6 +778,8 @@ HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;霞除去 - 深度マップの表示 HISTORY_MSG_DEHAZE_STRENGTH;霞除去 - 強さ HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;デュアルデモザイク - 自動しきい値 HISTORY_MSG_DUALDEMOSAIC_CONTRAST;AMaZE+VNG4 - コントラストのしきい値 +HISTORY_MSG_FILMNEGATIVE_ENABLED;ネガフィルム +HISTORY_MSG_FILMNEGATIVE_VALUES;ネガフィルムの値 HISTORY_MSG_HISTMATCHING;トーンカーブの自動調節 HISTORY_MSG_ICM_OUTPUT_PRIMARIES;出力 - プライマリ HISTORY_MSG_ICM_OUTPUT_TEMP;出力 - ICC-v4 光源 D @@ -1007,6 +1016,7 @@ PARTIALPASTE_EQUALIZER;ウェーブレット PARTIALPASTE_EVERYTHING;すべて PARTIALPASTE_EXIFCHANGES;exifデータを変える PARTIALPASTE_EXPOSURE;露光量 +PARTIALPASTE_FILMNEGATIVE;ネガフィルム PARTIALPASTE_FILMSIMULATION;フィルムシミュレーション PARTIALPASTE_FLATFIELDAUTOSELECT;フラットフィールド 自動選択 PARTIALPASTE_FLATFIELDBLURRADIUS;フラットフィールド ぼかし半径 @@ -1065,6 +1075,7 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;カラーピッカーのフォント PREFERENCES_APPEARANCE_CROPMASKCOLOR;切り抜きのマスクカラー PREFERENCES_APPEARANCE_MAINFONT;メインフォント PREFERENCES_APPEARANCE_NAVGUIDECOLOR;ナビゲーターのガイドカラー +PREFERENCES_APPEARANCE_PSEUDOHIDPI;擬似HiDPIモード PREFERENCES_APPEARANCE_THEME;テーマ PREFERENCES_APPLNEXTSTARTUP;要再起動 PREFERENCES_AUTOMONPROFILE;OSのメインモニター・プロファイルを使用 @@ -1284,6 +1295,7 @@ QUEUE_FORMAT_TITLE;ファイル形式 QUEUE_LOCATION_FOLDER;フォルダに保存 QUEUE_LOCATION_TEMPLATE;テンプレートを使う QUEUE_LOCATION_TEMPLATE_TOOLTIP;次の書式文字を使用することができます:\n%f, %d1, %d2, ..., %p1, %p2, ...%r\n\nこれらの書式文字は画像パス名のそれぞれ別々の部分、画像の属性を参照します\n\n例えば、次の画像を処理中の場合は:\n\n/home/tom/photos/2010-10-31/dsc0042.nef\n書式文字の意味するものは:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%rは写真のランクに置き換えられます。評価なしは%rは'0 'に置換されます。画像がごみ箱にある場合、%rは'X'に置換されます\n\n元画像と同じ場所に出力したい場合はこのように書きます:\n%p1/%f\n\n処理画像のディレクトリ下 "converted" という名前のディレクトリに出力画像を保存したい場合このように書きます:\n%p1/converted/%f\n\n"/home/tom/photos/converted/2010-10-31" という名前のディレクトリに出力画像を保存したい場合はこのように書きます:\n%p2/converted/%d1/%f +QUEUE_LOCATION_TITLE;出力の場所 QUEUE_STARTSTOP_TOOLTIP;キューにある画像の現像を始める、或いは中止する\n\nショートカット: Ctrl+s SAMPLEFORMAT_0;データ形式不明 SAMPLEFORMAT_1;符号なし8ビット @@ -1658,6 +1670,12 @@ TP_EXPOSURE_TCMODE_STANDARD;標準 TP_EXPOSURE_TCMODE_WEIGHTEDSTD;加重平均 TP_EXPOS_BLACKPOINT_LABEL;raw ブラック・ポイント TP_EXPOS_WHITEPOINT_LABEL;raw ホワイト・ポイント +TP_FILMNEGATIVE_BLUE;ブルーの比率 +TP_FILMNEGATIVE_GREEN;参考指数(コントラスト) +TP_FILMNEGATIVE_GUESS_TOOLTIP;画像の中でニュートラルな参考ポイントを2点選んで指数を計算します;白い(明るいグレー)1点と黒い(暗いグレー)1点を選びます。順番は関係ありません。2つ目のポイントが選択されると指数が更新されます。 +TP_FILMNEGATIVE_LABEL;ネガフィルム +TP_FILMNEGATIVE_PICK;白と黒のポイントをピックアップする +TP_FILMNEGATIVE_RED;レッドの比率 TP_FILMSIMULATION_LABEL;フィルムシミュレーション TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapeeはフィルムシミュレーション機能に使う画像をHald CLUTフォルダーの中から探すよう設計されています(プログラムに組み込むにはフォルダーが大き過ぎるため)。\n変更するには、環境設定 > 画像処理 > フィルムシミュレーションと進み\nどのフォルダーが使われているか確認します。機能を利用する場合は、Hald CLUTだけが入っているフォルダーを指定するか、 この機能を使わない場合はそのフォルダーを空にしておきます。\n\n詳しくはRawPediaを参照して下さい。\n\nフィルム画像のスキャンを止めますか? TP_FILMSIMULATION_STRENGTH;強さ @@ -2301,25 +2319,3 @@ ZOOMPANEL_ZOOMFITSCREEN;画像全体を画面に合わせる\nショートカッ ZOOMPANEL_ZOOMIN;ズームイン\nショートカット: + ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -!FILEBROWSER_DELETEDIALOG_ALL;Are you sure you want to permanently delete all %1 files in trash? -!FILEBROWSER_DELETEDIALOG_SELECTED;Are you sure you want to permanently delete the selected %1 files? -!FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Are you sure you want to permanently delete the selected %1 files, including a queue-processed version? -!FILEBROWSER_EMPTYTRASHHINT;Permanently delete all files in trash. -!FILEBROWSER_POPUPREMOVE;Delete permanently -!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. -!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values -!PARTIALPASTE_FILMNEGATIVE;Film Negative -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode -!QUEUE_LOCATION_TITLE;Output Location -!TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking two neutral reference spots in the image; one white (light gray) and one black (dark gray). The order does not matter. The exponents will be updated after the second spot is picked. -!TP_FILMNEGATIVE_LABEL;Film Negative -!TP_FILMNEGATIVE_PICK;Pick white and black spots -!TP_FILMNEGATIVE_RED;Red ratio From cbb3f05b7e51faf3af16022c616d04e7b9926d9b Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 22 Jul 2019 13:49:08 +0200 Subject: [PATCH 069/222] use empty() instead of comparison with an empty string --- rtengine/improcfun.cc | 2 +- rtengine/procparams.cc | 6 +- rtengine/rawimagesource.cc | 4 +- rtengine/simpleprocess.cc | 2 +- rtengine/stdimagesource.cc | 2 +- rtexif/nikonattribs.cc | 67 +++----------- rtgui/batchqueue.cc | 4 +- rtgui/darkframe.cc | 2 +- rtgui/exifpanel.cc | 4 +- rtgui/favoritbrowser.cc | 2 +- rtgui/filepanel.cc | 2 +- rtgui/flatfield.cc | 2 +- rtgui/icmpanel.cc | 6 +- rtgui/imagearea.cc | 2 +- rtgui/inspector.cc | 2 +- rtgui/lwbutton.cc | 20 +++-- rtgui/lwbutton.h | 1 + rtgui/lwbuttonset.cc | 79 ++++++----------- rtgui/lwbuttonset.h | 13 ++- rtgui/placesbrowser.cc | 2 +- rtgui/renamedlg.cc | 156 --------------------------------- rtgui/renamedlg.h | 43 --------- rtgui/thumbbrowserbase.cc | 2 +- rtgui/thumbbrowserentrybase.cc | 4 +- rtgui/thumbnail.cc | 12 +-- 25 files changed, 85 insertions(+), 356 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index c164abc0d..85954abfa 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5653,7 +5653,7 @@ void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_size) { - if (fname != "") { + if (!fname.empty()) { rtengine::RawMetaDataLocation ri; int w_raw = -1, h_raw = thumb_size; int w_thumb = -1, h_thumb = thumb_size; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 81de080bd..cb27fc2b3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -39,11 +39,11 @@ namespace Glib::ustring expandRelativePath(const Glib::ustring &procparams_fname, const Glib::ustring &prefix, Glib::ustring embedded_fname) { - if (embedded_fname == "" || !Glib::path_is_absolute(procparams_fname)) { + if (embedded_fname.empty() || !Glib::path_is_absolute(procparams_fname)) { return embedded_fname; } - if (prefix != "") { + if (!prefix.empty()) { if (embedded_fname.length() < prefix.length() || embedded_fname.substr(0, prefix.length()) != prefix) { return embedded_fname; } @@ -61,7 +61,7 @@ Glib::ustring expandRelativePath(const Glib::ustring &procparams_fname, const Gl Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool fnameAbsolute, Glib::ustring embedded_fname) { - if (fnameAbsolute || embedded_fname == "" || !Glib::path_is_absolute(procparams_fname)) { + if (fnameAbsolute || embedded_fname.empty() || !Glib::path_is_absolute(procparams_fname)) { return embedded_fname; } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 3b2738405..9f310508f 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -3824,7 +3824,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed return false; } - if (inProfile == "(embedded)" && embedded) { + if (embedded && inProfile == "(embedded)") { in = embedded; } else if (inProfile == "(cameraICC)") { // DCPs have higher quality, so use them first @@ -3833,7 +3833,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed if (*dcpProf == nullptr) { in = ICCStore::getInstance()->getStdProfile(camName); } - } else if (inProfile != "(camera)" && inProfile != "") { + } else if (inProfile != "(camera)" && !inProfile.empty()) { Glib::ustring normalName = inProfile; if (!inProfile.compare (0, 5, "file:")) { diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 4bdaa6ff1..2d594e0af 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1326,7 +1326,7 @@ private: } else { // use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma - if (params.icm.outputProfile != "" && params.icm.outputProfile != ColorManagementParams::NoICMString) { + if (!params.icm.outputProfile.empty() && params.icm.outputProfile != ColorManagementParams::NoICMString) { // if ICCStore::getInstance()->getProfile send back an object, then ICCStore::getInstance()->getContent will do too cmsHPROFILE jprof = ICCStore::getInstance()->getProfile (params.icm.outputProfile); //get outProfile diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 6ca3091a3..e5c98a93a 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -224,7 +224,7 @@ void StdImageSource::colorSpaceConversion (Imagefloat* im, const ColorManagement cmsHPROFILE in = nullptr; cmsHPROFILE out = ICCStore::getInstance()->workingSpace (cmp.workingProfile); - if (cmp.inputProfile == "(embedded)" || cmp.inputProfile == "" || cmp.inputProfile == "(camera)" || cmp.inputProfile == "(cameraICC)") { + if (cmp.inputProfile == "(embedded)" || cmp.inputProfile.empty() || cmp.inputProfile == "(camera)" || cmp.inputProfile == "(cameraICC)") { if (embedded) { in = embedded; } else { diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc index b2066150d..1c6ead006 100644 --- a/rtexif/nikonattribs.cc +++ b/rtexif/nikonattribs.cc @@ -257,65 +257,18 @@ public: std::ostringstream af; - if (aff & 1) - if (af.str() == "") { - af << "Center"; - } else { - af << ", Center"; - } else if (aff & 2) - if (af.str() == "") { - af << "Top"; - } else { - af << ", Top"; - } else if (aff & 4) - if (af.str() == "") { - af << "Bottom"; - } else { - af << ", Bottom"; - } else if (aff & 8) - if (af.str() == "") { - af << "Left"; - } else { - af << ", Left"; - } else if (aff & 16) - if (af.str() == "") { - af << "Right"; - } else { - af << ", Right"; - } else if (aff & 32) - if (af.str() == "") { - af << "Upper-left"; - } else { - af << ", Upper-left"; - } else if (aff & 64) - if (af.str() == "") { - af << "Upper-right"; - } else { - af << ", Upper-right"; - } else if (aff & 128) - if (af.str() == "") { - af << " Lower-left"; - } else { - af << ", Lower-left"; - } else if (aff & 256) - if (af.str() == "") { - af << "Lower-right"; - } else { - af << ", Lower-right"; - } else if (aff & 512) - if (af.str() == "") { - af << "Far Left"; - } else { - af << ", Far Left"; - } else if (aff & 1024) { - if (af.str() == "") { - af << "Far Right"; - } else { - af << ", Far Right"; + if (aff) { + for (size_t i = 0; i < afpchoices.size(); ++i) { + if (aff & (1 << i)) { + if (!af.str().empty()) { + af << ", "; + } + af << afpchoices.at(i); + } } } - str << "AFPointsInFocus = " << af.str(); + str << "AFPointsInFocus = " << (af.str().empty() ? "None" : af.str()); return str.str(); } }; @@ -553,7 +506,7 @@ public: std::map::const_iterator r = lenses.find (lid.str()); if (r != lenses.end()) { - if (r == lenses.begin() && EffectiveMaxApertureString != "") { // first entry is for unchipped lenses + if (r == lenses.begin() && !EffectiveMaxApertureString.empty()) { // first entry is for unchipped lenses Tag *FLTag = t->getParent()->getRoot()->findTag ("FocalLength"); ld << "Lens = MF "; diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 7222be05d..239057b87 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -667,7 +667,7 @@ rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img) Glib::ustring fname; SaveFormat saveFormat; - if (processing->outFileName == "") { // auto file name + if (processing->outFileName.empty()) { // auto file name Glib::ustring s = calcAutoFileNameBase (processing->filename, processing->sequence); saveFormat = options.saveFormatBatch; fname = autoCompleteFileName (s, saveFormat.format); @@ -686,7 +686,7 @@ rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img) //printf ("fname=%s, %s\n", fname.c_str(), removeExtension(fname).c_str()); - if (img && fname != "") { + if (img && !fname.empty()) { int err = 0; if (saveFormat.format == "tif") { diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index 77e9c53a6..8ffca7544 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -125,7 +125,7 @@ void DarkFrame::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi Glib::ustring fname = Glib::path_get_basename(dfp->GetCurrentImageFilePath()); Glib::ustring filetype; - if (fname != "") { + if (!fname.empty()) { // get image filetype, set filter to the same as current image's filetype std::string::size_type idx; idx = fname.rfind('.'); diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index c5036798e..6c196e575 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -496,7 +496,7 @@ void ExifPanel::addPressed () Glib::ustring sel = getSelection (true); - if (sel == "") { + if (sel.empty()) { tcombo->set_active_text ("Exif.UserComment"); } else { tcombo->set_active_text (sel); @@ -658,7 +658,7 @@ Glib::ustring ExifPanel::getSelection (bool onlyeditable) void ExifPanel::updateChangeList (Gtk::TreeModel::Children root, std::string prefix) { - if (prefix != "") { + if (!prefix.empty()) { prefix = prefix + "."; } diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc index 379ce26e6..0e1b4490b 100644 --- a/rtgui/favoritbrowser.cc +++ b/rtgui/favoritbrowser.cc @@ -97,7 +97,7 @@ void FavoritBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustr void FavoritBrowser::addPressed () { - if (lastSelectedDir == "") { + if (lastSelectedDir.empty()) { return; } diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index 5a344c8ba..da33caddf 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -358,7 +358,7 @@ void FilePanel::saveOptions () options.browserToolPanelWidth = winW - get_position(); options.browserToolPanelHeight = tpcPaned->get_position (); - if (options.startupDir == STARTUPDIR_LAST && fileCatalog->lastSelectedDir () != "") { + if (options.startupDir == STARTUPDIR_LAST && !fileCatalog->lastSelectedDir().empty()) { options.startupPath = fileCatalog->lastSelectedDir (); } diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 3cbd7acf1..25482909e 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -192,7 +192,7 @@ void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi Glib::ustring fname = Glib::path_get_basename(ffp->GetCurrentImageFilePath()); Glib::ustring filetype; - if (fname != "") { + if (!fname.empty()) { // get image filetype, set filter to the same as current image's filetype std::string::size_type idx; idx = fname.rfind('.'); diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index ca025ec75..e7efa20e9 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -504,7 +504,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) if (pp->icm.inputProfile == "(none)") { inone->set_active(true); updateDCP(pp->icm.dcpIlluminant, ""); - } else if (pp->icm.inputProfile == "(embedded)" || ((pp->icm.inputProfile == "(camera)" || pp->icm.inputProfile == "") && icamera->get_state() == Gtk::STATE_INSENSITIVE)) { + } else if (pp->icm.inputProfile == "(embedded)" || ((pp->icm.inputProfile == "(camera)" || pp->icm.inputProfile.empty()) && icamera->get_state() == Gtk::STATE_INSENSITIVE)) { iembedded->set_active(true); updateDCP(pp->icm.dcpIlluminant, ""); } else if ((pp->icm.inputProfile == "(cameraICC)") && icameraICC->get_state() != Gtk::STATE_INSENSITIVE) { @@ -519,7 +519,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) // If neither (camera) nor (cameraICC) are available, as is the case when loading a non-raw, activate (embedded). iembedded->set_active(true); updateDCP(pp->icm.dcpIlluminant, "(cameraICC)"); - } else if ((pp->icm.inputProfile == "(camera)" || pp->icm.inputProfile == "") && icamera->get_state() != Gtk::STATE_INSENSITIVE) { + } else if ((pp->icm.inputProfile == "(camera)" || pp->icm.inputProfile.empty()) && icamera->get_state() != Gtk::STATE_INSENSITIVE) { icamera->set_active(true); updateDCP(pp->icm.dcpIlluminant, ""); } else { @@ -949,7 +949,7 @@ void ICMPanel::setRawMeta(bool raw, const rtengine::FramesData* pMeta) void ICMPanel::ipSelectionChanged() { - if (ipDialog->get_filename() == "") { + if (ipDialog->get_filename().empty()) { return; } diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index dd891b351..886d9ff5b 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -247,7 +247,7 @@ bool ImageArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) (*i)->expose (cr); } - if (options.showInfo && infotext != "") { + if (options.showInfo && !infotext.empty()) { iBackBuffer.copySurface(cr); } diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 06e2272e7..a183a3419 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -34,7 +34,7 @@ InspectorBuffer::InspectorBuffer(const Glib::ustring &imagePath) : currTransform // generate thumbnail image Glib::ustring ext = getExtension (imagePath); - if (ext == "") { + if (ext.empty()) { imgPath.clear(); return; } diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc index 02041ea0c..3c97ff6bb 100644 --- a/rtgui/lwbutton.cc +++ b/rtgui/lwbutton.cc @@ -45,6 +45,12 @@ void LWButton::setPosition (int x, int y) ypos = y; } +void LWButton::addPosition (int x, int y) +{ + xpos += x; + ypos += y; +} + void LWButton::getPosition (int& x, int& y) const { @@ -219,15 +225,11 @@ void LWButton::getAlignment (Alignment& ha, Alignment& va) const Glib::ustring LWButton::getToolTip (int x, int y) const { - if (inside(x, y)) { - if (toolTip) { - return *toolTip; - } else { - return ""; - } - } else { - return ""; - } + if (inside(x, y) && toolTip) { + return *toolTip; + } else { + return {}; + } } void LWButton::setToolTip (Glib::ustring* tooltip) diff --git a/rtgui/lwbutton.h b/rtgui/lwbutton.h index aec875d55..12dbb6346 100644 --- a/rtgui/lwbutton.h +++ b/rtgui/lwbutton.h @@ -57,6 +57,7 @@ public: void getSize (int& minw, int& minh) const; void getAlignment (Alignment& ha, Alignment& va) const; void setPosition (int x, int y); + void addPosition (int x, int y); void getPosition (int& x, int& y) const; bool inside (int x, int y) const; void setIcon (Cairo::RefPtr i); diff --git a/rtgui/lwbuttonset.cc b/rtgui/lwbuttonset.cc index 99d3dce7c..d4d39bfe3 100644 --- a/rtgui/lwbuttonset.cc +++ b/rtgui/lwbuttonset.cc @@ -24,21 +24,18 @@ LWButtonSet::LWButtonSet () : aw(0), ah(0), ax(-1), ay(-1) LWButtonSet::~LWButtonSet () { - - for (size_t i = 0; i < buttons.size(); i++) { - delete buttons[i]; + for (const auto entry : buttons) { + delete entry; } } void LWButtonSet::add (LWButton* b) { - buttons.push_back (b); } -void LWButtonSet::getMinimalDimensions (int& w, int& h) +void LWButtonSet::getMinimalDimensions (int& w, int& h) const { - w = 0; h = 0; @@ -104,108 +101,86 @@ void LWButtonSet::arrangeButtons (int x, int y, int w, int h) void LWButtonSet::move (int nx, int ny) { - - for (size_t i = 0; i < buttons.size(); i++) { - int x, y; - buttons[i]->getPosition (x, y); - buttons[i]->setPosition (x + nx - ax, y + ny - ay); + for (const auto entry : buttons) { + entry->addPosition(nx - ax, ny - ay); } - ax = nx; ay = ny; } void LWButtonSet::redraw (Cairo::RefPtr context) { - - for (size_t i = 0; i < buttons.size(); i++) { - buttons[i]->redraw (context); + for (const auto entry : buttons) { + entry->redraw(context); } } bool LWButtonSet::motionNotify (int x, int y) { - bool res = false; - - for (size_t i = 0; i < buttons.size(); i++) { - bool handled = buttons[i]->motionNotify (x, y); - res = res || handled; + for (const auto entry : buttons) { + res = entry->motionNotify(x, y) || res; } - return res; } bool LWButtonSet::pressNotify (int x, int y) { - bool res = false; - - for (size_t i = 0; i < buttons.size(); i++) { - bool handled = buttons[i]->pressNotify (x, y); - res = res || handled; + for (const auto entry : buttons) { + res = entry->pressNotify(x, y) || res; } - return res; } bool LWButtonSet::releaseNotify (int x, int y) { - bool res = false; - - for (size_t i = 0; i < buttons.size(); i++) { - bool handled = buttons[i]->releaseNotify (x, y); - res = res || handled; + for (const auto entry : buttons) { + res = entry->releaseNotify(x, y) || res; } - return res; } -bool LWButtonSet::inside (int x, int y) +bool LWButtonSet::inside (int x, int y) const { - for (size_t i = 0; i < buttons.size(); i++) - if (buttons[i]->inside (x, y)) { + for (const auto entry : buttons) { + if (entry->inside(x, y)) { return true; } - + } return false; } void LWButtonSet::setButtonListener (LWButtonListener* bl) { - - for (size_t i = 0; i < buttons.size(); i++) { - buttons[i]->setButtonListener (bl); + for (const auto entry : buttons) { + entry->setButtonListener(bl); } } -void LWButtonSet::getAllocatedDimensions (int& w, int& h) +void LWButtonSet::getAllocatedDimensions (int& w, int& h) const { - w = aw; h = ah; } void LWButtonSet::setColors (const Gdk::RGBA& bg, const Gdk::RGBA& fg) { - - for (size_t i = 0; i < buttons.size(); i++) { - buttons[i]->setColors (bg, fg); + for (const auto entry : buttons) { + entry->setColors(bg, fg); } } -Glib::ustring LWButtonSet::getToolTip (int x, int y) +Glib::ustring LWButtonSet::getToolTip (int x, int y) const { + for (const auto entry : buttons) { + const auto ttip = entry->getToolTip(x, y); - for (size_t i = 0; i < buttons.size(); i++) { - Glib::ustring ttip = buttons[i]->getToolTip (x, y); - - if (ttip != "") { + if (!ttip.empty()) { return ttip; } } - - return ""; + return {}; } diff --git a/rtgui/lwbuttonset.h b/rtgui/lwbuttonset.h index 5452fa434..fa33620ae 100644 --- a/rtgui/lwbuttonset.h +++ b/rtgui/lwbuttonset.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _LWBUTTONSET_ -#define _LWBUTTONSET_ +#pragma once #include #include "lwbutton.h" @@ -35,20 +34,18 @@ public: void add (LWButton* b); - void getMinimalDimensions (int& w, int& h); - void getAllocatedDimensions (int& w, int& h); + void getMinimalDimensions (int& w, int& h) const; + void getAllocatedDimensions (int& w, int& h) const; void arrangeButtons (int x, int y, int w, int h); void setColors (const Gdk::RGBA& bg, const Gdk::RGBA& fg); bool motionNotify (int x, int y); bool pressNotify (int x, int y); bool releaseNotify (int x, int y); void move (int nx, int ny); - bool inside (int x, int y); + bool inside (int x, int y) const; - Glib::ustring getToolTip (int x, int y); + Glib::ustring getToolTip (int x, int y) const; void setButtonListener (LWButtonListener* bl); void redraw (Cairo::RefPtr context); }; - -#endif diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc index 0d20e9bad..9935064ee 100644 --- a/rtgui/placesbrowser.cc +++ b/rtgui/placesbrowser.cc @@ -309,7 +309,7 @@ void PlacesBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustri void PlacesBrowser::addPressed () { - if (lastSelectedDir == "") { + if (lastSelectedDir.empty()) { return; } diff --git a/rtgui/renamedlg.cc b/rtgui/renamedlg.cc index f03df455f..14931817f 100644 --- a/rtgui/renamedlg.cc +++ b/rtgui/renamedlg.cc @@ -88,159 +88,3 @@ Glib::ustring RenameDialog::getNewName () return newName->get_text (); } -//void RenameDialog::fillTemplateList () -//{ -// -// templateModel->clear (); -// -// for (size_t i = 0; i < options.renameTemplates.size(); i++) { -// Gtk::TreeModel::iterator iter = templateModel->append (); -// iter->set_value (templateColumns.tmplName, options.renameTemplates[i]); -// iter->set_value (templateColumns.rowSeparator, false); -// } -// -// // append separator and the manage... item -// Gtk::TreeModel::iterator iter = templateModel->append (); -// iter->set_value (templateColumns.tmplName, Glib::ustring("")); -// iter->set_value (templateColumns.rowSeparator, true); -// iter = templateModel->append (); -// iter->set_value (templateColumns.tmplName, Glib::ustring(M("FILEBROWSER_ADDDELTEMPLATE"))); -// iter->set_value (templateColumns.rowSeparator, false); -//} - -//bool RenameDialog::rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) -//{ -// -// return iter->get_value (templateColumns.rowSeparator); -//} - -//void RenameDialog::useTemplToggled () -//{ -// -// templates->set_sensitive (useTmpl->get_active ()); -// -// if (useTmpl->get_active () && isTemplSelected ()) { -// all->set_sensitive (true); -// newName->set_text (applyTemplate (oldName->get_text(), imageData, getActiveTemplate())); -// } else { -// all->set_sensitive (false); -// } -// -// newName->select_region (0, newName->get_text().size()); -//} - -//bool RenameDialog::isTemplSelected () -//{ -// -// Gtk::TreeModel::iterator iter = templates->get_active(); -// return iter && iter->get_value (templateColumns.tmplName) != M("FILEBROWSER_ADDDELTEMPLATE"); -//} - -//Glib::ustring RenameDialog::getActiveTemplate () -//{ -// -// Gtk::TreeModel::iterator iter = templates->get_active(); -// -// if (iter && iter->get_value (templateColumns.tmplName) != M("FILEBROWSER_ADDDELTEMPLATE")) { -// return iter->get_value (templateColumns.tmplName); -// } else { -// return ""; -// } -//} - -//void RenameDialog::tmplSelectionChanged () -//{ -// -// Gtk::TreeModel::iterator iter = templates->get_active(); -// -// if (iter && iter->get_value (templateColumns.tmplName) == M("FILEBROWSER_ADDDELTEMPLATE")) { -// RenameTemplateEditor* rte = new RenameTemplateEditor (p); -// -// if (rte->run() == Gtk::RESPONSE_OK) { -// fillTemplateList (); -// } -// -// delete rte; -// // show add/del template dialog -// } else { -// useTemplToggled (); -// } -//} - -//RenameTemplateEditor::RenameTemplateEditor (Gtk::Window* parent) -// : Gtk::Dialog ("Edit rename templates", *parent, true) -//{ -// -// list = Gtk::manage (new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); -// list->set_headers_visible (false); -// get_content_area ()->pack_start (*list); -// -// Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); -// templ = Gtk::manage (new Gtk::Entry ()); -// Gtk::Button* add = Gtk::manage (new Gtk::Button ()); -// Gtk::Button* del = Gtk::manage (new Gtk::Button ()); -// add->add (*Gtk::manage (new RTImage ("add-small.png"))); -// del->add (*Gtk::manage (new RTImage ("remove-small.png"))); -// hb->pack_start (*templ); -// hb->pack_start (*add, Gtk::PACK_SHRINK, 2); -// hb->pack_start (*del, Gtk::PACK_SHRINK, 2); -// -// get_content_area ()->pack_start (*hb, Gtk::PACK_SHRINK, 4); -// -// add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); -// -// refreshTemplateList (); -// -// add->signal_pressed().connect( sigc::mem_fun(*this, &RenameTemplateEditor::addPressed) ); -// del->signal_pressed().connect( sigc::mem_fun(*this, &RenameTemplateEditor::delPressed) ); -// -// show_all_children (); -// -// set_size_request (-1, 250); -//} -// -//void RenameTemplateEditor::refreshTemplateList () -//{ -// -// list->remove_all_columns(); -// -// for (size_t i = 0; i < options.renameTemplates.size(); i++) { -// list->append (options.renameTemplates[i]); -// } -//} -// -//void RenameTemplateEditor::addPressed () -//{ -// -// if (templ->get_text() != "") { -// options.renameTemplates.push_back (templ->get_text ()); -// refreshTemplateList (); -// templ->set_text(""); -// } -//} -// -//void RenameTemplateEditor::delPressed () -//{ -// -// std::vector sel = list->get_selected (); -// -// for (size_t i = 0; i < sel.size(); i++) { -// Glib::ustring toDel = list->get_text (sel[i]); -// std::vector::iterator f = std::find (options.renameTemplates.begin(), options.renameTemplates.end(), toDel); -// -// if (f != options.renameTemplates.end()) { -// options.renameTemplates.erase (f); -// } -// } -// -// refreshTemplateList (); -//} - -//Glib::ustring RenameDialog::applyTemplate (const Glib::ustring& oName, const CacheImageData* cid, const Glib::ustring& templ) -//{ -// -// return Glib::ustring ("szeva"); -// -//} - - diff --git a/rtgui/renamedlg.h b/rtgui/renamedlg.h index 94972d575..ab51a43c6 100644 --- a/rtgui/renamedlg.h +++ b/rtgui/renamedlg.h @@ -30,62 +30,19 @@ class RenameDialog : public Gtk::Dialog protected: -// class TemplateColumns : public Gtk::TreeModel::ColumnRecord -// { -// public: -// Gtk::TreeModelColumn tmplName; -// Gtk::TreeModelColumn rowSeparator; -// TemplateColumns() -// { -// add(tmplName); -// add(rowSeparator); -// } -// }; -// TemplateColumns templateColumns; -// Glib::RefPtr templateModel; Gtk::Window* p; Gtk::Label* oldName; Gtk::Entry* newName; -// Gtk::CheckButton* useTmpl; -// MyComboBox* templates; -// Gtk::Button* all; const CacheImageData* imageData; -// void fillTemplateList (); - public: explicit RenameDialog (Gtk::Window* parent); void initName (const Glib::ustring& iname, const CacheImageData* cid); Glib::ustring getNewName (); -// bool rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter); -// void tmplSelectionChanged (); -// void useTemplToggled (); - -// bool isTemplSelected (); -// Glib::ustring getActiveTemplate (); - -// static Glib::ustring applyTemplate (const Glib::ustring& oName, const CacheImageData* cid, const Glib::ustring& templ); }; -//class RenameTemplateEditor : public Gtk::Dialog -//{ -// -//protected: -// Gtk::ListViewText* list; -// Gtk::Entry* templ; -// -// void refreshTemplateList (); -//public: -// explicit RenameTemplateEditor (Gtk::Window* parent); -// -// Glib::ustring getSelectedTemplate (); -// -// void addPressed (); -// void delPressed (); -//}; - #endif diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 1ae0cdf98..cf3b36d03 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -748,7 +748,7 @@ bool ThumbBrowserBase::Internal::on_query_tooltip (int x, int y, bool keyboard_t } } - if (ttip != "") { + if (!ttip.empty()) { tooltip->set_markup (ttip); return true; } else { diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index 2960ccf70..f9e2b41b5 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -401,7 +401,7 @@ void ThumbBrowserEntryBase::updateBackBuffer () // draw date/time label int tpos = fnlabh; - if (options.fbShowDateTime && datetimeline != "") { + if (options.fbShowDateTime && !datetimeline.empty()) { fn = w->create_pango_layout (datetimeline); fn->set_width (textw * Pango::SCALE); fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); @@ -412,7 +412,7 @@ void ThumbBrowserEntryBase::updateBackBuffer () } // draw basic exif info - if (options.fbShowBasicExif && exifline != "") { + if (options.fbShowBasicExif && !exifline.empty()) { fn = w->create_pango_layout (exifline); fn->set_width (textw * Pango::SCALE); fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 39f4ca093..55e69ab21 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -117,9 +117,9 @@ void Thumbnail::_generateThumbnailImage () imgRatio = -1.; // generate thumbnail image - Glib::ustring ext = getExtension (fname); + const std::string ext = getExtension(fname).lowercase(); - if (ext == "") { + if (ext.empty()) { return; } @@ -127,20 +127,20 @@ void Thumbnail::_generateThumbnailImage () cfs.exifValid = false; cfs.timeValid = false; - if (ext.lowercase() == "jpg" || ext.lowercase() == "jpeg") { + if (ext == "jpg" || ext == "jpeg") { infoFromImage (fname); tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams->wb.equal); if (tpp) { cfs.format = FT_Jpeg; } - } else if (ext.lowercase() == "png") { + } else if (ext == "png") { tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams->wb.equal); if (tpp) { cfs.format = FT_Png; } - } else if (ext.lowercase() == "tif" || ext.lowercase() == "tiff") { + } else if (ext == "tif" || ext == "tiff") { infoFromImage (fname); tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams->wb.equal); @@ -716,7 +716,7 @@ void Thumbnail::generateExifDateTimeStrings () exifString = Glib::ustring::compose ("f/%1 %2s %3%4 %5mm", Glib::ustring(rtengine::FramesData::apertureToString(cfs.fnumber)), Glib::ustring(rtengine::FramesData::shutterToString(cfs.shutter)), M("QINFO_ISO"), cfs.iso, Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), cfs.focalLen)); - if (options.fbShowExpComp && cfs.expcomp != "0.00" && cfs.expcomp != "") { // don't show exposure compensation if it is 0.00EV;old cache iles do not have ExpComp, so value will not be displayed. + if (options.fbShowExpComp && cfs.expcomp != "0.00" && !cfs.expcomp.empty()) { // don't show exposure compensation if it is 0.00EV;old cache iles do not have ExpComp, so value will not be displayed. exifString = Glib::ustring::compose ("%1 %2EV", exifString, cfs.expcomp); // append exposure compensation to exifString } From 6604755c6b9341a676e75c713ef84fa27ad7cd72 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 22 Jul 2019 14:58:22 +0200 Subject: [PATCH 070/222] Fix a typo --- rtgui/thumbnail.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 55e69ab21..1ec10aacc 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -716,7 +716,7 @@ void Thumbnail::generateExifDateTimeStrings () exifString = Glib::ustring::compose ("f/%1 %2s %3%4 %5mm", Glib::ustring(rtengine::FramesData::apertureToString(cfs.fnumber)), Glib::ustring(rtengine::FramesData::shutterToString(cfs.shutter)), M("QINFO_ISO"), cfs.iso, Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), cfs.focalLen)); - if (options.fbShowExpComp && cfs.expcomp != "0.00" && !cfs.expcomp.empty()) { // don't show exposure compensation if it is 0.00EV;old cache iles do not have ExpComp, so value will not be displayed. + if (options.fbShowExpComp && cfs.expcomp != "0.00" && !cfs.expcomp.empty()) { // don't show exposure compensation if it is 0.00EV;old cache files do not have ExpComp, so value will not be displayed. exifString = Glib::ustring::compose ("%1 %2EV", exifString, cfs.expcomp); // append exposure compensation to exifString } From a6b1eb46fd415e31dfad5c97f6893c3d17966889 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Thu, 25 Jul 2019 11:49:17 +0200 Subject: [PATCH 071/222] Filmstrip horizontal scroll rate When scrolling with the mouse scroll-wheel while hovering over a thumbnail in the Filmstrip, now it scrolls by an amount equal to the first thumb's width. Previously it used the height. Spotted by Ingo. --- rtgui/thumbbrowserbase.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index cf3b36d03..b7170856a 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -542,7 +542,7 @@ void ThumbBrowserBase::configScrollBars () vscroll.get_adjustment()->set_upper (inH); hscroll.get_adjustment()->set_lower (0); vscroll.get_adjustment()->set_lower (0); - hscroll.get_adjustment()->set_step_increment (!fd.empty() ? fd[0]->getEffectiveHeight() : 0); + hscroll.get_adjustment()->set_step_increment (!fd.empty() ? fd[0]->getEffectiveWidth() : 0); vscroll.get_adjustment()->set_step_increment (!fd.empty() ? fd[0]->getEffectiveHeight() : 0); hscroll.get_adjustment()->set_page_increment (iw); vscroll.get_adjustment()->set_page_increment (ih); From 4cbc2a9091273abd17e535950984a74dc2204c02 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Thu, 25 Jul 2019 12:04:45 +0200 Subject: [PATCH 072/222] Fix missing filename tooltip When hovering over a thumb which has characters in its filename which are used in markup, such as '&', the tooltip was missing, due to the ampersand being parsed as markup. Now the filename is treated as plain text. --- rtgui/thumbbrowserbase.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index b7170856a..5129620e1 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -749,7 +749,7 @@ bool ThumbBrowserBase::Internal::on_query_tooltip (int x, int y, bool keyboard_t } if (!ttip.empty()) { - tooltip->set_markup (ttip); + tooltip->set_text(ttip); return true; } else { return false; From a9edbcf47bf9120f7e6a73ce4ff9d4d556638d5c Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Thu, 25 Jul 2019 14:11:40 +0200 Subject: [PATCH 073/222] Improve page-up/down scrolling in File Browser Patch by Ingo --- rtgui/thumbbrowserbase.cc | 43 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 5129620e1..8392e1b61 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -534,28 +534,33 @@ void ThumbBrowserBase::configScrollBars () GThreadLock tLock; // Acquire the GUI if (inW > 0 && inH > 0) { - - int iw = internal.get_width (); - int ih = internal.get_height (); - - hscroll.get_adjustment()->set_upper (inW); - vscroll.get_adjustment()->set_upper (inH); - hscroll.get_adjustment()->set_lower (0); - vscroll.get_adjustment()->set_lower (0); - hscroll.get_adjustment()->set_step_increment (!fd.empty() ? fd[0]->getEffectiveWidth() : 0); - vscroll.get_adjustment()->set_step_increment (!fd.empty() ? fd[0]->getEffectiveHeight() : 0); - hscroll.get_adjustment()->set_page_increment (iw); - vscroll.get_adjustment()->set_page_increment (ih); - hscroll.get_adjustment()->set_page_size (iw); - vscroll.get_adjustment()->set_page_size (ih); - - if(iw >= inW) { - hscroll.hide(); + int ih = internal.get_height(); + if (arrangement == TB_Horizontal) { + auto ha = hscroll.get_adjustment(); + int iw = internal.get_width(); + ha->set_upper(inW); + ha->set_lower(0); + ha->set_step_increment(!fd.empty() ? fd[0]->getEffectiveWidth() : 0); + ha->set_page_increment(iw); + ha->set_page_size(iw); + if (iw >= inW) { + hscroll.hide(); + } else { + hscroll.show(); + } } else { - hscroll.show(); + hscroll.hide(); } - if(ih >= inH) { + auto va = vscroll.get_adjustment(); + va->set_upper(inH); + va->set_lower(0); + const auto height = !fd.empty() ? fd[0]->getEffectiveHeight() : 0; + va->set_step_increment(height); + va->set_page_increment(height == 0 ? ih : (ih / height) * height); + va->set_page_size(ih); + + if (ih >= inH) { vscroll.hide(); } else { vscroll.show(); From 17f343f6825217d6f303a52ce9d90f0b3a803242 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 25 Jul 2019 17:45:43 +0200 Subject: [PATCH 074/222] add -Wcast-qual switch and fix all related warnings --- CMakeLists.txt | 2 +- rtengine/dcraw.cc | 6 +++--- rtengine/image16.cc | 4 ++-- rtengine/image16.h | 2 +- rtengine/image8.cc | 4 ++-- rtengine/image8.h | 2 +- rtengine/imagefloat.cc | 8 ++++---- rtengine/imagefloat.h | 2 +- rtengine/imageio.cc | 14 +++++++------- rtengine/imageio.h | 2 +- rtexif/rtexif.cc | 8 ++++---- rtexif/rtexif.h | 6 +++--- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 637cc1b9f..b027ea5f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,7 +392,7 @@ if(WITH_PROF) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wno-deprecated-declarations -Wno-unused-result") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wcast-qual -Wno-deprecated-declarations -Wno-unused-result") if(OPTION_OMP) find_package(OpenMP) if(OPENMP_FOUND) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 280b692e7..a4450a69a 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -240,7 +240,7 @@ int CLASS fcol (int row, int col) #ifndef __GLIBC__ char *my_memmem (char *haystack, size_t haystacklen, - char *needle, size_t needlelen) + const char *needle, size_t needlelen) { char *c; for (c = haystack; c <= haystack + haystacklen - needlelen; c++) @@ -9233,8 +9233,8 @@ void CLASS identify() fseek (ifp, 0, SEEK_SET); fread (head, 1, 32, ifp); /* RT: changed string constant */ - if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) || - (cp = (char *) memmem (head, 32, (char*)"IIII", 4))) { + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || + (cp = (char *) memmem (head, 32, "IIII", 4))) { parse_phase_one (cp-head); if (cp-head && parse_tiff(0)) apply_tiff(); } else if (order == 0x4949 || order == 0x4d4d) { diff --git a/rtengine/image16.cc b/rtengine/image16.cc index c0e97557a..7d4d3e41d 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -74,7 +74,7 @@ void Image16::getScanline(int row, unsigned char* buffer, int bps, bool isFloat) } } -void Image16::setScanline(int row, unsigned char* buffer, int bps, unsigned int numSamples) +void Image16::setScanline(int row, const unsigned char* buffer, int bps, unsigned int numSamples) { if (data == nullptr) { @@ -101,7 +101,7 @@ void Image16::setScanline(int row, unsigned char* buffer, int bps, unsigned int } case (IIOSF_UNSIGNED_SHORT): { - unsigned short* sbuffer = (unsigned short*) buffer; + const unsigned short* sbuffer = (const unsigned short*) buffer; int ix = 0; for (int i = 0; i < width; ++i) { diff --git a/rtengine/image16.h b/rtengine/image16.h index 9762af990..f31626939 100644 --- a/rtengine/image16.h +++ b/rtengine/image16.h @@ -56,7 +56,7 @@ public: } void getScanline(int row, unsigned char* buffer, int bps, bool isFloat = false) const override; - void setScanline(int row, unsigned char* buffer, int bps, unsigned int numSamples) override; + void setScanline(int row, const unsigned char* buffer, int bps, unsigned int numSamples) override; // functions inherited from IImage16: MyMutex& getMutex() override diff --git a/rtengine/image8.cc b/rtengine/image8.cc index 513b0049e..850ec87c0 100644 --- a/rtengine/image8.cc +++ b/rtengine/image8.cc @@ -55,7 +55,7 @@ void Image8::getScanline (int row, unsigned char* buffer, int bps, bool isFloat) } } -void Image8::setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) +void Image8::setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) { if (data == nullptr) { @@ -74,7 +74,7 @@ void Image8::setScanline (int row, unsigned char* buffer, int bps, unsigned int break; case (IIOSF_UNSIGNED_SHORT): { - unsigned short* sbuffer = (unsigned short*) buffer; + const unsigned short* sbuffer = (const unsigned short*) buffer; for (int i = 0, ix = row * width * 3; i < width * 3; ++i, ++ix) { data[ix] = uint16ToUint8Rounded(sbuffer[i]); diff --git a/rtengine/image8.h b/rtengine/image8.h index 8928cf85b..57852b7af 100644 --- a/rtengine/image8.h +++ b/rtengine/image8.h @@ -53,7 +53,7 @@ public: } void getScanline (int row, unsigned char* buffer, int bps, bool isFloat = false) const override; - void setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) override; + void setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) override; // functions inherited from IImage*: MyMutex& getMutex () override diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index d98a817a2..793915604 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -45,7 +45,7 @@ Imagefloat::~Imagefloat () } // Call this method to handle floating points input values of different size -void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) +void Imagefloat::setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) { if (data == nullptr) { @@ -58,7 +58,7 @@ void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned switch (sampleFormat) { case (IIOSF_FLOAT16): { int ix = 0; - uint16_t* sbuffer = (uint16_t*) buffer; + const uint16_t* sbuffer = (const uint16_t*) buffer; for (int i = 0; i < width; i++) { r(row, i) = 65535.f * DNG_HalfToFloat(sbuffer[ix++]); @@ -71,7 +71,7 @@ void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned //case (IIOSF_FLOAT24): case (IIOSF_FLOAT32): { int ix = 0; - float* sbuffer = (float*) buffer; + const float* sbuffer = (const float*) buffer; for (int i = 0; i < width; i++) { r(row, i) = 65535.f * sbuffer[ix++]; @@ -85,7 +85,7 @@ void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned case (IIOSF_LOGLUV24): case (IIOSF_LOGLUV32): { int ix = 0; - float* sbuffer = (float*) buffer; + const float* sbuffer = (const float*) buffer; float xyzvalues[3], rgbvalues[3]; for (int i = 0; i < width; i++) { diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index e1e5086b8..805971e7a 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -62,7 +62,7 @@ public: } void getScanline (int row, unsigned char* buffer, int bps, bool isFloat = false) const override; - void setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) override; + void setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) override; // functions inherited from IImagefloat: MyMutex& getMutex () override diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 3b0fdcf6d..1e4f8c008 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -89,7 +89,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot) } if (eroot) { - rtexif::TagDirectory* td = ((rtexif::TagDirectory*)eroot)->clone (nullptr); + rtexif::TagDirectory* td = eroot->clone (nullptr); // make IPTC and XMP pass through td->keepTag(0x83bb); // IPTC @@ -113,7 +113,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr } if (eroot) { - exifRoot = ((rtexif::TagDirectory*)eroot)->clone (nullptr); + exifRoot = eroot->clone (nullptr); } if (iptc != nullptr) { @@ -140,7 +140,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr for (unsigned int j = 0; j < i->second.size(); j++) { IptcDataSet * ds = iptc_dataset_new (); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(j).c_str(), min(static_cast(64), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); + iptc_dataset_set_data (ds, (const unsigned char*)i->second.at(j).c_str(), min(static_cast(64), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); iptc_data_add_dataset (iptc, ds); iptc_dataset_unref (ds); } @@ -150,7 +150,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr for (unsigned int j = 0; j < i->second.size(); j++) { IptcDataSet * ds = iptc_dataset_new (); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(j).c_str(), min(static_cast(32), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); + iptc_dataset_set_data (ds, (const unsigned char*)i->second.at(j).c_str(), min(static_cast(32), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); iptc_data_add_dataset (iptc, ds); iptc_dataset_unref (ds); } @@ -162,7 +162,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr if (i->first == strTags[j].field && !(i->second.empty())) { IptcDataSet * ds = iptc_dataset_new (); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, strTags[j].tag); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(0).c_str(), min(strTags[j].size, i->second.at(0).bytes()), IPTC_DONT_VALIDATE); + iptc_dataset_set_data (ds, (const unsigned char*)i->second.at(0).c_str(), min(strTags[j].size, i->second.at(0).bytes()), IPTC_DONT_VALIDATE); iptc_data_add_dataset (iptc, ds); iptc_dataset_unref (ds); } @@ -910,12 +910,12 @@ int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool s char swapped[line_length]; for ( int row = 0; row < height; ++row ) { - ::rtengine::swab(((char*)buffer) + (row * line_length), swapped, line_length); + ::rtengine::swab(((const char*)buffer) + (row * line_length), swapped, line_length); setScanline(row, (unsigned char*)&swapped[0], bps); } } else { for ( int row = 0; row < height; ++row ) { - setScanline(row, ((unsigned char*)buffer) + (row * line_length), bps); + setScanline(row, ((const unsigned char*)buffer) + (row * line_length), bps); } } diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 05a11655a..fd2cbc2b9 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -81,7 +81,7 @@ public: virtual void getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* image, PreviewProps pp) const = 0; virtual int getBPS () const = 0; virtual void getScanline (int row, unsigned char* buffer, int bps, bool isFloat = false) const = 0; - virtual void setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples = 3) = 0; + virtual void setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples = 3) = 0; virtual const char* getType () const = 0; int load (const Glib::ustring &fname); diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 312cbd1c7..dcc0ed56d 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -673,7 +673,7 @@ int TagDirectory::calculateSize () return size; } -TagDirectory* TagDirectory::clone (TagDirectory* parent) +TagDirectory* TagDirectory::clone (TagDirectory* parent) const { TagDirectory* td = new TagDirectory (parent, attribs, order); @@ -857,7 +857,7 @@ TagDirectoryTable::TagDirectoryTable (TagDirectory* p, FILE* f, int memsize, int } } } -TagDirectory* TagDirectoryTable::clone (TagDirectory* parent) +TagDirectory* TagDirectoryTable::clone (TagDirectory* parent) const { TagDirectory* td = new TagDirectoryTable (parent, values, valuesSize, zeroOffset, defaultType, attribs, order); @@ -1382,7 +1382,7 @@ bool Tag::parseMakerNote (FILE* f, int base, ByteOrder bom ) return true; } -Tag* Tag::clone (TagDirectory* parent) +Tag* Tag::clone (TagDirectory* parent) const { Tag* t = new Tag (parent, attrib); @@ -1397,7 +1397,7 @@ Tag* Tag::clone (TagDirectory* parent) t->value = new unsigned char [valuesize]; memcpy (t->value, value, valuesize); } else { - value = nullptr; + t->value = nullptr; } t->makerNoteKind = makerNoteKind; diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 43b296746..eadea4fa1 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -180,7 +180,7 @@ public: virtual int calculateSize (); virtual int write (int start, unsigned char* buffer); - virtual TagDirectory* clone (TagDirectory* parent); + virtual TagDirectory* clone (TagDirectory* parent) const; void applyChange (const std::string &field, const Glib::ustring &value); virtual void printAll (unsigned int level = 0) const; // reentrant debug function, keep level=0 on first call ! @@ -204,7 +204,7 @@ public: ~TagDirectoryTable() override; int calculateSize () override; int write (int start, unsigned char* buffer) override; - TagDirectory* clone (TagDirectory* parent) override; + TagDirectory* clone (TagDirectory* parent) const override; }; // a class representing a single tag @@ -310,7 +310,7 @@ public: // functions for writing int calculateSize (); int write (int offs, int dataOffs, unsigned char* buffer); - Tag* clone (TagDirectory* parent); + Tag* clone (TagDirectory* parent) const; // to control if the tag shall be written bool getKeep () From 13207910528e2f553f3f875503b20f104941d958 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 27 Jul 2019 11:40:01 +0200 Subject: [PATCH 075/222] Backwards thumbnail selection using Shift-key unexpectedly shifts starting point of selection, fixes #5389 --- rtgui/thumbbrowserbase.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 8392e1b61..dba5390c1 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -178,15 +178,19 @@ void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* clicked, bool additio if (!additional || !lastClicked) { // Extend the current range w.r.t to first selected entry. ThumbIterator front = std::find(fd.begin(), fd.end(), selected.front()); + ThumbIterator back; ThumbIterator current = std::find(fd.begin(), fd.end(), clicked); if (front > current) { - std::swap(front, current); + front = current; + back = std::find(fd.begin(), fd.end(), selected.back()); + } else { + back = current; } clearSelection(selected); - for (; front <= current && front != fd.end(); ++front) { + for (; front <= back && front != fd.end(); ++front) { addToSelection(*front, selected); } } else { From de963c54dedea70f8cd68052a97aadda1a9afdf8 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 27 Jul 2019 17:39:16 +0200 Subject: [PATCH 076/222] Further speedups for filebrowser/catalog --- rtgui/browserfilter.cc | 10 ++-- rtgui/browserfilter.h | 6 +- rtgui/filebrowser.cc | 66 +++++++------------- rtgui/filebrowser.h | 2 +- rtgui/filecatalog.cc | 30 +++++++--- rtgui/thumbbrowserbase.cc | 123 ++++++++++++++++++++++++++++++++------ rtgui/thumbbrowserbase.h | 7 ++- 7 files changed, 159 insertions(+), 85 deletions(-) diff --git a/rtgui/browserfilter.cc b/rtgui/browserfilter.cc index ab4c843a4..cd3af072e 100644 --- a/rtgui/browserfilter.cc +++ b/rtgui/browserfilter.cc @@ -19,11 +19,11 @@ #include "browserfilter.h" BrowserFilter::BrowserFilter () : - showTrash (true), - showNotTrash (true), - showOriginal (false), - multiselect (false), - exifFilterEnabled (false) + showTrash(true), + showNotTrash(true), + showOriginal(false), + exifFilterEnabled(false), + matchEqual(true) { for (int i = 0; i < 6; i++) { showRanked[i] = true; diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h index 8880a364d..ac9818ce5 100644 --- a/rtgui/browserfilter.h +++ b/rtgui/browserfilter.h @@ -33,13 +33,11 @@ public: bool showOriginal; bool showEdited[2]; bool showRecentlySaved[2]; - bool multiselect; - - Glib::ustring queryString; - Glib::ustring queryFileName; bool exifFilterEnabled; + bool matchEqual; ExifFilterSettings exifFilter; + std::vector vFilterStrings; BrowserFilter (); }; diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index cc215e70a..7a32cd6b7 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -18,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include #include #include @@ -622,7 +623,7 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) initEntry(entry); } - redraw(false); + redraw(entry); } FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) @@ -1461,12 +1462,12 @@ void FileBrowser::applyFilter (const BrowserFilter& filter) redraw (); } -bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry complies filter +bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) const // true -> entry complies filter { FileBrowserEntry* entry = static_cast(entryb); - if (filter.showOriginal && entry->getOriginal() != nullptr) { + if (filter.showOriginal && entry->getOriginal()) { return false; } @@ -1485,44 +1486,22 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry return false; } - // return false is query is not satisfied - if (!filter.queryFileName.empty()) { + // return false if query is not satisfied + if (!filter.vFilterStrings.empty()) { // check if image's FileName contains queryFileName (case insensitive) // TODO should we provide case-sensitive search option via preferences? - Glib::ustring FileName; - FileName = Glib::path_get_basename (entry->thumbnail->getFileName()); - FileName = FileName.uppercase(); - //printf("FileBrowser::checkFilter FileName = '%s'; find() result= %i \n",FileName.c_str(), FileName.find(filter.queryFileName.uppercase())); - - Glib::ustring decodedQueryFileName; - bool MatchEqual; - - // Determine the match mode - check if the first 2 characters are equal to "!=" - if (filter.queryFileName.find("!=") == 0) { - decodedQueryFileName = filter.queryFileName.substr (2, filter.queryFileName.length() - 2); - MatchEqual = false; - } else { - decodedQueryFileName = filter.queryFileName; - MatchEqual = true; - } - - // Consider that queryFileName consist of comma separated values (FilterString) - // Evaluate if ANY of these FilterString are contained in the filename - // This will construct OR filter within the filter.queryFileName + std::string FileName = Glib::path_get_basename(entry->thumbnail->getFileName()); + std::transform(FileName.begin(), FileName.end(), FileName.begin(), ::toupper); int iFilenameMatch = 0; - std::vector vFilterStrings = Glib::Regex::split_simple(",", decodedQueryFileName.uppercase()); - for(size_t i = 0; i < vFilterStrings.size(); i++) { - // ignore empty vFilterStrings. Otherwise filter will always return true if - // e.g. filter.queryFileName ends on "," and will stop being a filter - if (!vFilterStrings.at(i).empty()) { - if (FileName.find(vFilterStrings.at(i)) != Glib::ustring::npos) { - iFilenameMatch++; - } + for (const auto& entry : filter.vFilterStrings) { + if (FileName.find(entry) != std::string::npos) { + iFilenameMatch++; + break; } } - if (MatchEqual) { + if (filter.matchEqual) { if (iFilenameMatch == 0) { //none of the vFilterStrings found in FileName return false; } @@ -1531,10 +1510,10 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry return false; } } + } - /*experimental Regex support, this is unlikely to be useful to photographers*/ - //bool matchfound=Glib::Regex::match_simple(filter.queryFileName.uppercase(),FileName); - //if (!matchfound) return false; + if (!filter.exifFilterEnabled) { + return true; } // check exif filter @@ -1542,17 +1521,12 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry double tol = 0.01; double tol2 = 1e-8; - if (!filter.exifFilterEnabled) { - return true; - } - - Glib::ustring camera(cfs->getCamera()); - - if (!cfs->exifValid) - return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera) > 0) + if (!cfs->exifValid) { + return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->getCamera()) > 0) && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0) && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0) && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0); + } return (!filter.exifFilter.filterShutter || (rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom - tol2 && rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo + tol2)) @@ -1560,7 +1534,7 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry && (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom - tol && cfs->focalLen <= filter.exifFilter.focalTo + tol)) && (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo)) && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0) - && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera) > 0) + && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->getCamera()) > 0) && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0) && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0); } diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index b208a854d..cef99e08c 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -168,7 +168,7 @@ public: void buttonPressed (LWButton* button, int actionCode, void* actionData) override; void redrawNeeded (LWButton* button) override; - bool checkFilter (ThumbBrowserEntryBase* entry) override; + bool checkFilter (ThumbBrowserEntryBase* entry) const override; void rightClicked (ThumbBrowserEntryBase* entry) override; void doubleClicked (ThumbBrowserEntryBase* entry) override; bool keyPressed (GdkEventKey* event) override; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index dbe540cb4..7c14873a2 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1603,7 +1603,6 @@ BrowserFilter FileCatalog::getFilter () anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive; } - filter.multiselect = false; /* * Step 2 @@ -1619,7 +1618,6 @@ BrowserFilter FileCatalog::getFilter () (anyEditedFilterActive && anyRecentlySavedFilterActive) || (anySupplementaryActive && (anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive))) { - filter.multiselect = true; filter.showRanked[0] = anyRankFilterActive ? bUnRanked->get_active () : true; filter.showCLabeled[0] = anyCLabelFilterActive ? bUnCLabeled->get_active () : true; @@ -1656,14 +1654,28 @@ BrowserFilter FileCatalog::getFilter () //TODO could use date:;iso: etc // default will be filename - /* // this is for safe execution if getFilter is called before Query object is instantiated - Glib::ustring tempQuery; - tempQuery=""; - if (Query) tempQuery = Query->get_text(); - */ - filter.queryString = Query->get_text(); // full query string from Query Entry - filter.queryFileName = Query->get_text(); // for now Query is only by file name + Glib::ustring decodedQueryFileName = Query->get_text(); // for now Query is only by file name + // Determine the match mode - check if the first 2 characters are equal to "!=" + if (decodedQueryFileName.find("!=") == 0) { + decodedQueryFileName = decodedQueryFileName.substr(2); + filter.matchEqual = false; + } else { + filter.matchEqual = true; + } + + // Consider that queryFileName consist of comma separated values (FilterString) + // Evaluate if ANY of these FilterString are contained in the filename + // This will construct OR filter within the queryFileName + filter.vFilterStrings.clear(); + const std::vector filterStrings = Glib::Regex::split_simple(",", decodedQueryFileName.uppercase()); + for (const auto& entry : filterStrings) { + // ignore empty filterStrings. Otherwise filter will always return true if + // e.g. queryFileName ends on "," and will stop being a filter + if (!entry.empty()) { + filter.vFilterStrings.push_back(entry); + } + } return filter; } diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index dba5390c1..a67eb7eec 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -28,7 +28,7 @@ using namespace std; ThumbBrowserBase::ThumbBrowserBase () - : location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), previewHeight(options.thumbSize), numOfCols(1), arrangement(TB_Horizontal) + : location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), previewHeight(options.thumbSize), numOfCols(1), lastRowHeight(0), arrangement(TB_Horizontal) { inW = -1; inH = -1; @@ -44,6 +44,8 @@ ThumbBrowserBase::ThumbBrowserBase () show_all (); + vscroll.get_adjustment()->set_lower(0); + hscroll.get_adjustment()->set_lower(0); vscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); hscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); @@ -543,7 +545,6 @@ void ThumbBrowserBase::configScrollBars () auto ha = hscroll.get_adjustment(); int iw = internal.get_width(); ha->set_upper(inW); - ha->set_lower(0); ha->set_step_increment(!fd.empty() ? fd[0]->getEffectiveWidth() : 0); ha->set_page_increment(iw); ha->set_page_size(iw); @@ -558,7 +559,6 @@ void ThumbBrowserBase::configScrollBars () auto va = vscroll.get_adjustment(); va->set_upper(inH); - va->set_lower(0); const auto height = !fd.empty() ? fd[0]->getEffectiveHeight() : 0; va->set_step_increment(height); va->set_page_increment(height == 0 ? ih : (ih / height) * height); @@ -572,8 +572,22 @@ void ThumbBrowserBase::configScrollBars () } } -void ThumbBrowserBase::arrangeFiles(bool checkfilter) +void ThumbBrowserBase::arrangeFiles(ThumbBrowserEntryBase* entry) { + + if (fd.empty()) { + // nothing to arrange + resizeThumbnailArea(0, 0); + return; + } + if(entry && entry->filtered) { + // a filtered entry was added, nothing to arrange, but has to be marked not drawable + MYREADERLOCK(l, entryRW); + entry->drawable = false; + MYREADERLOCK_RELEASE(l); + return; + } + MYREADERLOCK(l, entryRW); // GUI already locked by ::redraw, the only caller of this method for now. @@ -581,17 +595,22 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) //GThreadLock lock; int rowHeight = 0; - for (const auto entry : fd) { - if (checkfilter) { - // apply filter - entry->filtered = !checkFilter(entry); - } + if (entry) { + // we got the reference to the added entry, makes calculation of rowHeight O(1) + lastRowHeight = rowHeight = std::max(lastRowHeight, entry->getMinimalHeight()); + } else { - // compute size of the items - if (!entry->filtered) { - rowHeight = std::max(entry->getMinimalHeight(), rowHeight); + lastRowHeight = 0; + for (const auto thumb : fd) { + // apply filter + thumb->filtered = !checkFilter(thumb); + // compute max rowHeight + if (!thumb->filtered) { + rowHeight = std::max(thumb->getMinimalHeight(), rowHeight); + } } } + if (arrangement == TB_Horizontal) { numOfCols = 1; @@ -622,14 +641,16 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) const int availWidth = internal.get_width(); // initial number of columns + int oldNumOfCols = numOfCols; numOfCols = 0; int colsWidth = 0; for (unsigned int i = 0; i < fd.size(); ++i) { if (!fd[i]->filtered && colsWidth + fd[i]->getMinimalWidth() <= availWidth) { - colsWidth += fd[numOfCols]->getMinimalWidth(); + colsWidth += fd[i]->getMinimalWidth(); ++numOfCols; if(colsWidth > availWidth) { + --numOfCols; break; } } @@ -640,6 +661,7 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) } std::vector colWidths; + std::vector oldColWidths; for (; numOfCols > 0; --numOfCols) { // compute column widths @@ -663,10 +685,77 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) } } + if (oldNumOfCols == numOfCols) { + int oldColsWidth = 0; + for (; oldNumOfCols > 0; --oldNumOfCols) { + // compute old column widths + oldColWidths.assign(oldNumOfCols, 0); + + for (unsigned int i = 0, j = 0; i < fd.size(); ++i) { + if (fd[i] != entry && !fd[i]->filtered && fd[i]->getMinimalWidth() > oldColWidths[j % oldNumOfCols]) { + oldColWidths[j % oldNumOfCols] = fd[i]->getMinimalWidth(); + } + + if (fd[i] != entry && !fd[i]->filtered) { + ++j; + } + } + // if not wider than the space available, arrange it and we are ready + oldColsWidth = std::accumulate(oldColWidths.begin(), oldColWidths.end(), 0); + + if (oldNumOfCols == 1 || oldColsWidth < availWidth) { + break; + } + } + } + + bool arrangeAll = true; + if (entry && oldNumOfCols == numOfCols && oldColWidths.size() > 0) { + arrangeAll = false; + for (int i = 0; i < numOfCols; ++i) { + if(colWidths[i] != oldColWidths[i]) { + arrangeAll = true; + break; + } + } + } + // arrange files int curry = 0; + size_t ct = 0; + if (entry && !arrangeAll) { + int i = 0; + // Find currently added entry + for (; ct < fd.size() && fd[ct] != entry; i += !fd[ct]->filtered, ++ct) { + } + //Calculate the position of currently added entry + const int row = i / numOfCols; + const int col = i % numOfCols; + curry = row * rowHeight; + int currx = 0; + for (int c = 0; c < col; ++c) { + currx += colWidths[c]; + } + // arrange all entries in the row beginning with the currently added one + for (int i = col; ct < fd.size() && i < numOfCols; ++i, ++ct) { + for (; ct < fd.size() && fd[ct]->filtered; ++ct) { + fd[ct]->drawable = false; + } + if (ct < fd.size()) { + fd[ct]->setPosition(currx, curry, colWidths[i], rowHeight); + fd[ct]->drawable = true; + currx += colWidths[i]; + } + } + + if (currx > 0) { // there were thumbnails placed in the row + curry += rowHeight; + } + } + + // arrange remaining entries, if any, that's the most expensive part + for (; ct < fd.size();) { - for (unsigned int ct = 0; ct < fd.size();) { // arrange items in the row int currx = 0; @@ -689,7 +778,7 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) MYREADERLOCK_RELEASE(l); // This will require a Writer access - resizeThumbnailArea (colsWidth, curry); + resizeThumbnailArea(colsWidth, curry); } } @@ -979,11 +1068,11 @@ bool ThumbBrowserBase::Internal::on_scroll_event (GdkEventScroll* event) } -void ThumbBrowserBase::redraw (bool checkfilter) +void ThumbBrowserBase::redraw (ThumbBrowserEntryBase* entry) { GThreadLock lock; - arrangeFiles(checkfilter); + arrangeFiles(entry); queue_draw(); } diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index ae561db43..e9e69416c 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -174,12 +174,13 @@ protected: int previewHeight; int numOfCols; + int lastRowHeight; Arrangement arrangement; std::set editedFiles; - void arrangeFiles (bool checkfilter = true); + void arrangeFiles (ThumbBrowserEntryBase* entry = nullptr); void zoomChanged (bool zoomIn); public: @@ -201,7 +202,7 @@ public: return fd; } void on_style_updated () override; - void redraw (bool checkfilter = true); // arrange files and draw area + void redraw (ThumbBrowserEntryBase* entry = nullptr); // arrange files and draw area void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshQuickThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshEditedState (const std::set& efiles); @@ -214,7 +215,7 @@ public: void setArrangement (Arrangement a); void enableTabMode(bool enable); // set both thumb sizes and arrangements - virtual bool checkFilter (ThumbBrowserEntryBase* entry) + virtual bool checkFilter (ThumbBrowserEntryBase* entry) const { return true; } From e748f424274579267deed21993cf8a62e8479a8e Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 27 Jul 2019 21:26:00 +0200 Subject: [PATCH 077/222] Some code cleanups --- rtgui/thumbbrowserbase.cc | 115 +++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 59 deletions(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index a67eb7eec..88c2c3cce 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -661,7 +661,6 @@ void ThumbBrowserBase::arrangeFiles(ThumbBrowserEntryBase* entry) } std::vector colWidths; - std::vector oldColWidths; for (; numOfCols > 0; --numOfCols) { // compute column widths @@ -685,71 +684,69 @@ void ThumbBrowserBase::arrangeFiles(ThumbBrowserEntryBase* entry) } } - if (oldNumOfCols == numOfCols) { - int oldColsWidth = 0; - for (; oldNumOfCols > 0; --oldNumOfCols) { - // compute old column widths - oldColWidths.assign(oldNumOfCols, 0); - - for (unsigned int i = 0, j = 0; i < fd.size(); ++i) { - if (fd[i] != entry && !fd[i]->filtered && fd[i]->getMinimalWidth() > oldColWidths[j % oldNumOfCols]) { - oldColWidths[j % oldNumOfCols] = fd[i]->getMinimalWidth(); - } - - if (fd[i] != entry && !fd[i]->filtered) { - ++j; - } - } - // if not wider than the space available, arrange it and we are ready - oldColsWidth = std::accumulate(oldColWidths.begin(), oldColWidths.end(), 0); - - if (oldNumOfCols == 1 || oldColsWidth < availWidth) { - break; - } - } - } - bool arrangeAll = true; - if (entry && oldNumOfCols == numOfCols && oldColWidths.size() > 0) { - arrangeAll = false; - for (int i = 0; i < numOfCols; ++i) { - if(colWidths[i] != oldColWidths[i]) { - arrangeAll = true; - break; - } - } - } - // arrange files int curry = 0; size_t ct = 0; - if (entry && !arrangeAll) { - int i = 0; - // Find currently added entry - for (; ct < fd.size() && fd[ct] != entry; i += !fd[ct]->filtered, ++ct) { - } - //Calculate the position of currently added entry - const int row = i / numOfCols; - const int col = i % numOfCols; - curry = row * rowHeight; - int currx = 0; - for (int c = 0; c < col; ++c) { - currx += colWidths[c]; - } - // arrange all entries in the row beginning with the currently added one - for (int i = col; ct < fd.size() && i < numOfCols; ++i, ++ct) { - for (; ct < fd.size() && fd[ct]->filtered; ++ct) { - fd[ct]->drawable = false; - } - if (ct < fd.size()) { - fd[ct]->setPosition(currx, curry, colWidths[i], rowHeight); - fd[ct]->drawable = true; - currx += colWidths[i]; + if (entry) { + std::vector oldColWidths; + if (oldNumOfCols == numOfCols) { + for (; oldNumOfCols > 0; --oldNumOfCols) { + // compute old column widths + oldColWidths.assign(oldNumOfCols, 0); + + for (unsigned int i = 0, j = 0; i < fd.size(); ++i) { + if (fd[i] != entry && !fd[i]->filtered && fd[i]->getMinimalWidth() > oldColWidths[j % oldNumOfCols]) { + oldColWidths[j % oldNumOfCols] = fd[i]->getMinimalWidth(); + } + + if (fd[i] != entry && !fd[i]->filtered) { + ++j; + } + } + if (oldNumOfCols == 1 || std::accumulate(oldColWidths.begin(), oldColWidths.end(), 0) < availWidth) { + break; + } } } - if (currx > 0) { // there were thumbnails placed in the row - curry += rowHeight; + if (oldNumOfCols == numOfCols) { + arrangeAll = false; + for (int i = 0; i < numOfCols; ++i) { + if(colWidths[i] != oldColWidths[i]) { + arrangeAll = true; + break; + } + } + } + if (!arrangeAll) { + int i = 0; + // Find currently added entry + for (; ct < fd.size() && fd[ct] != entry; i += !fd[ct]->filtered, ++ct) { + } + //Calculate the position of currently added entry + const int row = i / numOfCols; + const int col = i % numOfCols; + curry = row * rowHeight; + int currx = 0; + for (int c = 0; c < col; ++c) { + currx += colWidths[c]; + } + // arrange all entries in the row beginning with the currently added one + for (int i = col; ct < fd.size() && i < numOfCols; ++i, ++ct) { + for (; ct < fd.size() && fd[ct]->filtered; ++ct) { + fd[ct]->drawable = false; + } + if (ct < fd.size()) { + fd[ct]->setPosition(currx, curry, colWidths[i], rowHeight); + fd[ct]->drawable = true; + currx += colWidths[i]; + } + } + + if (currx > 0) { // there were thumbnails placed in the row + curry += rowHeight; + } } } From f523149582af993b814aa7804c13b3cac79fa4e1 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 29 Jul 2019 13:56:38 +0200 Subject: [PATCH 078/222] Clear processing profile is broken, fixes #5392 --- rtengine/procparams.cc | 2 +- rtgui/thumbnail.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index cb27fc2b3..2118213d5 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2878,7 +2878,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo keyFile.set_string("Version", "AppVersion", RTVERSION); keyFile.set_integer("Version", "Version", PPVERSION); - saveToKeyfile(!pedited || pedited->general.rank, "General", "Rank", rank, keyFile); + saveToKeyfile(!pedited || pedited->general.rank, "General", "Rank", std::max(rank, 0), keyFile); saveToKeyfile(!pedited || pedited->general.colorlabel, "General", "ColorLabel", colorlabel, keyFile); saveToKeyfile(!pedited || pedited->general.intrash, "General", "InTrash", inTrash, keyFile); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 1ec10aacc..6ac3d629b 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -399,6 +399,7 @@ void Thumbnail::clearProcParams (int whoClearedIt) // and restore rank and inTrash setRank(rank); + pparamsValid = cfs.rating != rank; setColorLabel(colorlabel); setStage(inTrash); From 4e4106b4e796707cb1e4f0e3d9c6b149de21be9e Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 29 Jul 2019 14:41:36 +0200 Subject: [PATCH 079/222] Minor cleanups --- rtgui/filebrowser.cc | 2 +- rtgui/filebrowserentry.cc | 22 +++++++++++----------- rtgui/filecatalog.cc | 16 ++++++++-------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 7a32cd6b7..4326c1666 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -1496,7 +1496,7 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) const // true -> for (const auto& entry : filter.vFilterStrings) { if (FileName.find(entry) != std::string::npos) { - iFilenameMatch++; + ++iFilenameMatch; break; } } diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 4b1764824..8b518335c 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -251,32 +251,32 @@ void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rten bool newLandscape = img->getWidth() > img->getHeight(); bool rotated = false; - if (preh == img->getHeight ()) { + if (preh == img->getHeight()) { + const bool resize = !preview || prew != img->getWidth(); prew = img->getWidth (); GThreadLock lock; // Check if image has been rotated since last time - rotated = preview != nullptr && newLandscape != landscape; + rotated = preview && newLandscape != landscape; - guint8* temp = preview; - preview = nullptr; - delete [] temp; - temp = new guint8 [prew * preh * 3]; - memcpy (temp, img->getData(), prew * preh * 3); - preview = temp; + if (resize) { + delete [] preview; + preview = new guint8 [prew * preh * 3]; + } + memcpy(preview, img->getData(), prew * preh * 3); updateBackBuffer (); } landscape = newLandscape; - img->free (); + img->free(); - if (parent != nullptr) { + if (parent) { if (rotated) { parent->thumbRearrangementNeeded(); } else if (redrawRequests == 0) { - parent->redrawNeeded (this); + parent->redrawNeeded(this); } } } diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 7c14873a2..63ebc7676 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -804,28 +804,28 @@ void FileCatalog::previewsFinishedUI () { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected - redrawAll (); + redrawAll(); previewsToLoad = 0; if (filterPanel) { - filterPanel->set_sensitive (true); + filterPanel->set_sensitive(true); - if ( !hasValidCurrentEFS ) { - MyMutex::MyLock lock(dirEFSMutex); + if (!hasValidCurrentEFS) { + MyMutex::MyLock myLock(dirEFSMutex); currentEFS = dirEFS; - filterPanel->setFilter ( dirEFS, true ); + filterPanel->setFilter(dirEFS, true); } else { - filterPanel->setFilter ( currentEFS, false ); + filterPanel->setFilter(currentEFS, false); } } if (exportPanel) { - exportPanel->set_sensitive (true); + exportPanel->set_sensitive(true); } // restart anything that might have been loaded low quality fileBrowser->refreshQuickThumbImages(); - fileBrowser->applyFilter (getFilter()); // refresh total image count + fileBrowser->applyFilter(getFilter()); // refresh total image count _refreshProgressBar(); } filepanel->loadingThumbs(M("PROGRESSBAR_READY"), 0); From 0f0dc03849b7d4c8b50f2d121d23e205f1db5845 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 29 Jul 2019 15:21:23 +0200 Subject: [PATCH 080/222] Fix broken thumbnail butto tooltips --- rtgui/batchqueueentry.cc | 8 +++++--- rtgui/batchqueueentry.h | 2 +- rtgui/thumbbrowserbase.cc | 12 ++++++++---- rtgui/thumbbrowserentrybase.cc | 5 +++-- rtgui/thumbbrowserentrybase.h | 4 ++-- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index a5dfb6dde..23982095c 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -168,10 +168,12 @@ void BatchQueueEntry::getIconSize (int& w, int& h) const } -Glib::ustring BatchQueueEntry::getToolTip (int x, int y) const +std::tuple BatchQueueEntry::getToolTip (int x, int y) const { // get the parent class' tooltip first - Glib::ustring tooltip = ThumbBrowserEntryBase::getToolTip(x, y); + Glib::ustring tooltip; + bool useMarkup; + std::tie(tooltip, useMarkup) = ThumbBrowserEntryBase::getToolTip(x, y); // add the saving param options if (!outFileName.empty()) { @@ -198,7 +200,7 @@ Glib::ustring BatchQueueEntry::getToolTip (int x, int y) const } } - return tooltip; + return std::make_tuple(std::move(tooltip), useMarkup); } diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index d13dfe827..0ea56e403 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -70,7 +70,7 @@ public: std::vector> getIconsOnImageArea () override; void getIconSize (int& w, int& h) const override; - Glib::ustring getToolTip (int x, int y) const override; + std::tuple getToolTip (int x, int y) const override; // bqentryupdatelistener interface void updateImage (guint8* img, int w, int h, int origw, int origh, guint8* newOPreview) override; diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index dba5390c1..f637015bc 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -745,20 +745,24 @@ void ThumbBrowserBase::Internal::on_realize() bool ThumbBrowserBase::Internal::on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip) { // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) - Glib::ustring ttip = ""; - + Glib::ustring ttip; + boolean useMarkup = false; { MYREADERLOCK(l, parent->entryRW); for (size_t i = 0; i < parent->fd.size(); i++) if (parent->fd[i]->drawable && parent->fd[i]->inside (x, y)) { - ttip = parent->fd[i]->getToolTip (x, y); + std::tie(ttip, useMarkup) = parent->fd[i]->getToolTip (x, y); break; } } if (!ttip.empty()) { - tooltip->set_text(ttip); + if (useMarkup) { + tooltip->set_markup(ttip); + } else { + tooltip->set_text(ttip); + } return true; } else { return false; diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index f9e2b41b5..e660e794b 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -724,7 +724,7 @@ bool ThumbBrowserEntryBase::releaseNotify (int button, int type, int bstate, int return buttonSet ? buttonSet->releaseNotify (x, y) : false; } -Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) const +std::tuple ThumbBrowserEntryBase::getToolTip (int x, int y) const { Glib::ustring tooltip; @@ -734,6 +734,7 @@ Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) const // Always show the filename in the tooltip since the filename in the thumbnail could be truncated. // If "Show Exif info" is disabled, also show Exif info in the tooltip. + bool useMarkup = !tooltip.empty(); if (inside(x, y) && tooltip.empty()) { tooltip = dispname; @@ -748,7 +749,7 @@ Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) const } } - return tooltip; + return std::make_tuple(std::move(tooltip), useMarkup); } diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index 12e64c60d..6cbcb37d0 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -19,7 +19,7 @@ #pragma once #include - +#include #include #include "cursormanager.h" @@ -190,7 +190,7 @@ public: virtual bool motionNotify (int x, int y); virtual bool pressNotify (int button, int type, int bstate, int x, int y); virtual bool releaseNotify (int button, int type, int bstate, int x, int y); - virtual Glib::ustring getToolTip (int x, int y) const; + virtual std::tuple getToolTip (int x, int y) const; inline ThumbBrowserEntryBase* getOriginal() const { From 287bd5bbe31d5e7595c06c16434aa0dc995cdf35 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 29 Jul 2019 23:05:01 +0200 Subject: [PATCH 081/222] boolean > bool --- rtgui/thumbbrowserbase.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index f637015bc..53b5828aa 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -746,7 +746,7 @@ bool ThumbBrowserBase::Internal::on_query_tooltip (int x, int y, bool keyboard_t { // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) Glib::ustring ttip; - boolean useMarkup = false; + bool useMarkup = false; { MYREADERLOCK(l, parent->entryRW); From 6b868a8d4d7b9f0ac1efbb19284dfd2cb91aba84 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 30 Jul 2019 13:22:15 +0200 Subject: [PATCH 082/222] Make thumbnail range-selection more similar to OS behaviour, fixes #5393 --- rtgui/filebrowser.cc | 1 + rtgui/thumbbrowserbase.cc | 26 +++++++++++++------------- rtgui/thumbbrowserbase.h | 1 + 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index cc215e70a..b968a285e 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -667,6 +667,7 @@ void FileBrowser::close () MYWRITERLOCK(l, entryRW); selected.clear (); + anchor = nullptr; MYWRITERLOCK_RELEASE(l); // notifySelectionListener will need read access! diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 53b5828aa..71f9e4a04 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -28,7 +28,7 @@ using namespace std; ThumbBrowserBase::ThumbBrowserBase () - : location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), previewHeight(options.thumbSize), numOfCols(1), arrangement(TB_Horizontal) + : location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), anchor(nullptr), previewHeight(options.thumbSize), numOfCols(1), arrangement(TB_Horizontal) { inW = -1; inH = -1; @@ -162,30 +162,29 @@ inline void removeFromSelection (const ThumbIterator& iterator, ThumbVector& sel void ThumbBrowserBase::selectSingle (ThumbBrowserEntryBase* clicked) { - clearSelection (selected); + clearSelection(selected); + anchor = clicked; - if (clicked) - addToSelection (clicked, selected); + if (clicked) { + addToSelection(clicked, selected); + } } void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* clicked, bool additional) { - if (selected.empty()) { + if (selected.empty() && !anchor) { addToSelection(clicked, selected); + anchor = clicked; return; } if (!additional || !lastClicked) { // Extend the current range w.r.t to first selected entry. - ThumbIterator front = std::find(fd.begin(), fd.end(), selected.front()); - ThumbIterator back; - ThumbIterator current = std::find(fd.begin(), fd.end(), clicked); + ThumbIterator back = std::find(fd.begin(), fd.end(), clicked); + ThumbIterator front = std::find(fd.begin(), fd.end(), anchor); - if (front > current) { - front = current; - back = std::find(fd.begin(), fd.end(), selected.back()); - } else { - back = current; + if (front > back) { + std::swap(front, back); } clearSelection(selected); @@ -217,6 +216,7 @@ void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* clicked) } else { addToSelection (clicked, selected); } + anchor = clicked; } static void scrollToEntry (double& h, double& v, int iw, int ih, ThumbBrowserEntryBase* entry) diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index ae561db43..953ec44ec 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -171,6 +171,7 @@ protected: std::vector fd; std::vector selected; ThumbBrowserEntryBase* lastClicked; + ThumbBrowserEntryBase* anchor; int previewHeight; int numOfCols; From f85de946e63b4668716bceddade50b772037d6c3 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 30 Jul 2019 14:44:18 +0200 Subject: [PATCH 083/222] Fix some corner cases in thumb selection, #5393 --- rtgui/filebrowser.cc | 25 ++++++++++++++++--------- rtgui/thumbbrowserbase.cc | 20 +++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index b968a285e..eb85613ee 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -783,16 +783,20 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) { MYWRITERLOCK(l, entryRW); - selected.clear (); + selected.clear(); - for (size_t i = 0; i < fd.size(); i++) - if (checkFilter (fd[i])) { + for (size_t i = 0; i < fd.size(); ++i) { + if (checkFilter(fd[i])) { fd[i]->selected = true; - selected.push_back (fd[i]); + selected.push_back(fd[i]); } + } + if (!anchor && !selected.empty()) { + anchor = selected[0]; + } } queue_draw (); - notifySelectionListener (); + notifySelectionListener(); } else if( m == copyTo) { tbl->copyMoveRequested (mselected, false); } @@ -1438,12 +1442,12 @@ void FileBrowser::applyFilter (const BrowserFilter& filter) } for (size_t i = 0; i < fd.size(); i++) { - if (checkFilter (fd[i])) { + if (checkFilter(fd[i])) { numFiltered++; - } else if (fd[i]->selected ) { + } else if (fd[i]->selected) { fd[i]->selected = false; - std::vector::iterator j = std::find (selected.begin(), selected.end(), fd[i]); - selected.erase (j); + std::vector::iterator j = std::find(selected.begin(), selected.end(), fd[i]); + selected.erase(j); if (lastClicked == fd[i]) { lastClicked = nullptr; @@ -1452,6 +1456,9 @@ void FileBrowser::applyFilter (const BrowserFilter& filter) selchanged = true; } } + if (selected.empty() || (anchor && std::find(selected.begin(), selected.end(), anchor) == selected.end())) { + anchor = nullptr; + } } if (selchanged) { diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 71f9e4a04..20a7d3e44 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -172,16 +172,18 @@ void ThumbBrowserBase::selectSingle (ThumbBrowserEntryBase* clicked) void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* clicked, bool additional) { - if (selected.empty() && !anchor) { - addToSelection(clicked, selected); + if (!anchor) { anchor = clicked; - return; + if (selected.empty()) { + addToSelection(clicked, selected); + return; + } } if (!additional || !lastClicked) { // Extend the current range w.r.t to first selected entry. ThumbIterator back = std::find(fd.begin(), fd.end(), clicked); - ThumbIterator front = std::find(fd.begin(), fd.end(), anchor); + ThumbIterator front = anchor == clicked ? back : std::find(fd.begin(), fd.end(), anchor); if (front > back) { std::swap(front, back); @@ -195,7 +197,7 @@ void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* clicked, bool additio } else { // Add an additional range w.r.t. the last clicked entry. ThumbIterator last = std::find(fd.begin(), fd.end(), lastClicked); - ThumbIterator current = std::find (fd.begin(), fd.end(), clicked); + ThumbIterator current = std::find(fd.begin(), fd.end(), clicked); if (last > current) { std::swap(last, current); @@ -209,12 +211,12 @@ void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* clicked, bool additio void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* clicked) { - const ThumbIterator iterator = std::find (selected.begin (), selected.end (), clicked); + const ThumbIterator iterator = std::find(selected.begin(), selected.end(), clicked); - if (iterator != selected.end ()) { - removeFromSelection (iterator, selected); + if (iterator != selected.end()) { + removeFromSelection(iterator, selected); } else { - addToSelection (clicked, selected); + addToSelection(clicked, selected); } anchor = clicked; } From 0ed517d972eaca5ebd712accf574c87d6815daab Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 31 Jul 2019 16:08:25 +0200 Subject: [PATCH 084/222] cppcheck: more explicit contructors --- rtengine/curves.h | 4 ++-- rtengine/imagedata.h | 2 +- rtengine/improcfun.h | 2 +- rtengine/procparams.h | 4 ++-- rtgui/curveeditorgroup.h | 2 +- rtgui/guiutils.h | 2 +- rtgui/popupcommon.h | 2 +- rtgui/rtimage.h | 10 +++++----- rtgui/rtsurface.h | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/rtengine/curves.h b/rtengine/curves.h index deed5d0fe..98ce68015 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -468,7 +468,7 @@ protected: void NURBS_set (); public: - DiagonalCurve (const std::vector& points, int ppn = CURVES_MIN_POLY_POINTS); + explicit DiagonalCurve (const std::vector& points, int ppn = CURVES_MIN_POLY_POINTS); ~DiagonalCurve () override; double getVal (double t) const override; @@ -493,7 +493,7 @@ private: public: - FlatCurve (const std::vector& points, bool isPeriodic = true, int ppn = CURVES_MIN_POLY_POINTS); + explicit FlatCurve (const std::vector& points, bool isPeriodic = true, int ppn = CURVES_MIN_POLY_POINTS); ~FlatCurve () override; double getVal (double t) const override; diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index d06820296..774547487 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -98,7 +98,7 @@ private: unsigned int dcrawFrameCount; public: - FramesData (const Glib::ustring& fname, std::unique_ptr rml = nullptr, bool firstFrameOnly = false); + explicit FramesData (const Glib::ustring& fname, std::unique_ptr rml = nullptr, bool firstFrameOnly = false); ~FramesData () override; void setDCRawFrameCount (unsigned int frameCount); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index cd1650f6e..d3e6f4032 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -200,7 +200,7 @@ public: double lumimul[3]; - ImProcFunctions(const ProcParams* iparams, bool imultiThread = true) + explicit ImProcFunctions(const ProcParams* iparams, bool imultiThread = true) : monitorTransform(nullptr), params(iparams), scale(1), multiThread(imultiThread), lumimul{} {} ~ImProcFunctions(); bool needsLuminanceOnly() diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 46eb530bc..369af85fa 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1634,8 +1634,8 @@ class PartialProfile : { public: PartialProfile(bool createInstance = false, bool paramsEditedValue = false); - PartialProfile(ProcParams* pp, ParamsEdited* pe = nullptr, bool fullCopy = false); - PartialProfile(const ProcParams* pp, const ParamsEdited* pe = nullptr); + explicit PartialProfile(ProcParams* pp, ParamsEdited* pe = nullptr, bool fullCopy = false); + explicit PartialProfile(const ProcParams* pp, const ParamsEdited* pe = nullptr); void deleteInstance(); void clearGeneral(); int load(const Glib::ustring& fName); diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h index 80a1a95a4..ae0ebee07 100644 --- a/rtgui/curveeditorgroup.h +++ b/rtgui/curveeditorgroup.h @@ -70,7 +70,7 @@ public: * dialogs. */ - CurveEditorGroup(Glib::ustring& curveDir, Glib::ustring groupLabel = ""); + explicit CurveEditorGroup(Glib::ustring& curveDir, Glib::ustring groupLabel = ""); ~CurveEditorGroup() override; void newLine(); void curveListComplete(); diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index e4c38f347..73cd27171 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -400,7 +400,7 @@ protected: void set_none(); public: - MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); + explicit MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); sigc::signal &signal_selection_changed(); sigc::signal &signal_file_set(); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index f939dbe96..92d6a6214 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -47,7 +47,7 @@ public: type_signal_item_selected signal_item_selected(); Gtk::Grid* buttonGroup; // this is the widget to be packed - PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); + explicit PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label); int getEntryCount () const; diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index 5679f6edc..244d0030a 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -38,11 +38,11 @@ protected: public: RTImage (); RTImage (RTImage &other); - RTImage (Glib::RefPtr &pixbuf); - RTImage (Cairo::RefPtr &surf); - RTImage(Cairo::RefPtr other); - RTImage (Glib::RefPtr &other); - RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); + explicit RTImage (Glib::RefPtr &pixbuf); + explicit RTImage (Cairo::RefPtr &surf); + explicit RTImage(Cairo::RefPtr other); + explicit RTImage (Glib::RefPtr &other); + explicit RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); void setImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); void changeImage (const Glib::ustring& imageName); diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index c314ab1c1..b442b7493 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -30,7 +30,7 @@ class RTSurface : { public: RTSurface(); - RTSurface(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); + explicit RTSurface(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); void setImage(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); From 4101102ddf930dc24de14900b64d6a007ad01305 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 31 Jul 2019 20:02:35 +0200 Subject: [PATCH 085/222] cppcheck: further fixes --- rtengine/EdgePreservingDecomposition.cc | 33 +++++++-------- rtengine/color.cc | 39 ------------------ rtengine/color.h | 54 +++++++------------------ rtengine/imagedata.cc | 4 +- rtexif/rtexif.h | 10 ++--- rtgui/bqentryupdater.cc | 3 +- rtgui/editorpanel.cc | 2 +- rtgui/guiutils.cc | 38 +++++------------ rtgui/histogrampanel.cc | 5 --- rtgui/iccprofilecreator.cc | 26 ++++-------- rtgui/icmpanel.cc | 2 - rtgui/imagearea.cc | 5 +-- rtgui/inspector.cc | 4 -- rtgui/rtimage.cc | 4 +- rtgui/rtwindow.cc | 4 +- rtgui/splash.cc | 4 +- rtgui/thresholdselector.cc | 13 +----- rtgui/whitebalance.cc | 1 - 18 files changed, 62 insertions(+), 189 deletions(-) diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc index 6bda5d437..85b7ce243 100644 --- a/rtengine/EdgePreservingDecomposition.cc +++ b/rtengine/EdgePreservingDecomposition.cc @@ -401,13 +401,10 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max //How many diagonals in the decomposition? MaxFillAbove++; //Conceptually, now "fill" includes an existing diagonal. Simpler in the math that follows. - int j, mic, fp; - mic = 1; - fp = 1; + int mic = 1; for(int ii = 1; ii < m; ii++) { - fp = rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); //Guaranteed positive since StartRows must be created in increasing order. - mic = mic + fp; + mic += rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); //Guaranteed positive since StartRows must be created in increasing order. } //Initialize the decomposition - setup memory, start rows, etc. @@ -421,7 +418,7 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max for(int ii = 1; ii < m; ii++) { //Set j to the number of diagonals to be created corresponding to a diagonal on this source matrix... - j = rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); + int j = rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); //...and create those diagonals. I want to take a moment to tell you about how much I love minimalistic loops: very much. while(j-- != 0) @@ -491,7 +488,7 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max findmap[j] = FindIndex( icStartRows[j]); } - for(j = 0; j < n; j++) { + for(int j = 0; j < n; j++) { //Calculate d for this column. d[j] = Diagonals[0][j]; @@ -557,12 +554,11 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R float* RESTRICT *d = IncompleteCholeskyFactorization->Diagonals; int* RESTRICT s = IncompleteCholeskyFactorization->StartRows; int M = IncompleteCholeskyFactorization->m, N = IncompleteCholeskyFactorization->n; - int i, j; if(M != DIAGONALSP1) { // can happen in theory - for(j = 0; j < N; j++) { + for(int j = 0; j < N; j++) { float sub = b[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j - s[i]; while(c >= 0) { @@ -574,9 +570,9 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } } else { // that's the case almost every time - for(j = 0; j <= s[M - 1]; j++) { + for(int j = 0; j <= s[M - 1]; j++) { float sub = b[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j - s[1]; while(c >= 0) { @@ -588,7 +584,7 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } - for(j = s[M - 1] + 1; j < N; j++) { + for(int j = s[M - 1] + 1; j < N; j++) { float sub = b[j]; // using local var to reduce memory writes, gave a big speedup for(int i = DIAGONALSP1 - 1; i > 0; i--) { // using a constant upperbound allows the compiler to unroll this loop (gives a good speedup) @@ -605,14 +601,15 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R #pragma omp parallel for #endif - for(j = 0; j < N; j++) { + for(int j = 0; j < N; j++) { x[j] = x[j] / d[0][j]; } if(M != DIAGONALSP1) { // can happen in theory + int j = N; while(j-- > 0) { float sub = x[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j + s[1]; while(c < N) { @@ -624,9 +621,9 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } } else { // that's the case almost every time - for(j = N - 1; j >= (N - 1) - s[M - 1]; j--) { + for(int j = N - 1; j >= (N - 1) - s[M - 1]; j--) { float sub = x[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j + s[1]; while(c < N) { @@ -638,7 +635,7 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } - for(j = (N - 2) - s[M - 1]; j >= 0; j--) { + for(int j = (N - 2) - s[M - 1]; j >= 0; j--) { float sub = x[j]; // using local var to reduce memory writes, gave a big speedup for(int i = DIAGONALSP1 - 1; i > 0; i--) { // using a constant upperbound allows the compiler to unroll this loop (gives a good speedup) diff --git a/rtengine/color.cc b/rtengine/color.cc index 3f2a75788..7c12c0ca5 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -2016,45 +2016,6 @@ void Color::Lch2Luv(float c, float h, float &u, float &v) v = c * sincosval.y; } -// NOT TESTED -void Color::XYZ2Luv (float X, float Y, float Z, float &L, float &u, float &v) -{ - - X /= 65535.f; - Y /= 65535.f; - Z /= 65535.f; - - if (Y > float(eps)) { - L = 116.f * std::cbrt(Y) - 16.f; - } else { - L = float(kappa) * Y; - } - - u = 13.f * L * float(u0); - v = 13.f * L * float(v0); -} - -// NOT TESTED -void Color::Luv2XYZ (float L, float u, float v, float &X, float &Y, float &Z) -{ - if (L > float(epskap)) { - float t = (L + 16.f) / 116.f; - Y = t * t * t; - } else { - Y = L / float(kappa); - } - - float a = ((52.f * L) / (u + 13.f * L * float(u0)) - 1.f) / 3.f; - float d = Y * (((39 * L) / (v + 13 * float(v0))) - 5.f); - float b = -5.f * Y; - X = (d - b) / (a + 1.f / 3.f); - - Z = X * a + b; - - X *= 65535.f; - Y *= 65535.f; - Z *= 65535.f; -} /* * Gamut mapping algorithm diff --git a/rtengine/color.h b/rtengine/color.h index fb4eea458..5bf178636 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -240,20 +240,20 @@ public: static inline void rgb2slfloat(float r, float g, float b, float &s, float &l) { - float m = min(r, g, b); - float M = max(r, g, b); - float C = M - m; + float minVal = min(r, g, b); + float maxVal = max(r, g, b); + float C = maxVal - minVal; - l = (M + m) * 7.6295109e-6f; // (0.5f / 65535.f) + l = (maxVal + minVal) * 7.6295109e-6f; // (0.5f / 65535.f) if (C < 0.65535f) { // 0.00001f * 65535.f s = 0.f; } else { if (l <= 0.5f) { - s = C / (M + m); + s = C / (maxVal + minVal); } else { - s = C / (131070.f - (M + m)); // 131070.f = 2.f * 65535.f + s = C / (131070.f - (maxVal + minVal)); // 131070.f = 2.f * 65535.f } } } @@ -261,11 +261,11 @@ public: static inline void rgb2hslfloat(float r, float g, float b, float &h, float &s, float &l) { - float m = min(r, g, b); - float M = max(r, g, b); - float C = M - m; + float minVal = min(r, g, b); + float maxVal = max(r, g, b); + float C = maxVal - minVal; - l = (M + m) * 7.6295109e-6f; // (0.5f / 65535.f) + l = (maxVal + minVal) * 7.6295109e-6f; // (0.5f / 65535.f) if (C < 0.65535f) { // 0.00001f * 65535.f h = 0.f; @@ -273,14 +273,14 @@ public: } else { if (l <= 0.5f) { - s = C / (M + m); + s = C / (maxVal + minVal); } else { - s = C / (131070.f - (M + m)); // 131070.f = 2.f * 65535.f + s = C / (131070.f - (maxVal + minVal)); // 131070.f = 2.f * 65535.f } - if ( r == M ) { + if ( r == maxVal ) { h = (g - b); - } else if ( g == M ) { + } else if ( g == maxVal ) { h = (2.f * C) + (b - r); } else { h = (4.f * C) + (r - g); @@ -686,32 +686,6 @@ public: static void Lch2Luv(float c, float h, float &u, float &v); - /** - * @brief Convert the XYZ values to Luv values - * Warning: this method has never been used/tested so far - * @param x X coordinate [0 ; 65535] ; can be negative or superior to 65535 - * @param y Y coordinate [0 ; 65535] ; can be negative or superior to 65535 - * @param z Z coordinate [0 ; 65535] ; can be negative or superior to 65535 - * @param L 'L' channel [0 ; 32768] (return value) - * @param u 'u' channel [-42000 ; 42000] ; can be more than 42000 (return value) - * @param v 'v' channel [-42000 ; 42000] ; can be more than 42000 (return value) - */ - static void XYZ2Luv (float X, float Y, float Z, float &L, float &u, float &v); - - - /** - * @brief Convert the Luv values to XYZ values - * Warning: this method has never been used/tested so far - * @param L 'L' channel [0 ; 32768] - * @param u 'u' channel [-42000 ; 42000] ; can be more than 42000 - * @param v 'v' channel [-42000 ; 42000] ; can be more than 42000 - * @param x X coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) - * @param y Y coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) - * @param z Z coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) - */ - static void Luv2XYZ (float L, float u, float v, float &X, float &Y, float &Z); - - /** * @brief Return "f" in function of CIE's kappa and epsilon constants * @param f f can be fx fy fz where: diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index faa7ad5ed..b074cdbb2 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -258,7 +258,6 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* tag = exif->getTag("SubjectDistance"); if (tag) { - int num, denom; tag->toRational(num, denom); } else { // Second try, XMP data @@ -524,8 +523,7 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* focal_len = flt->toDouble (); } } else if ((flt = mnote->getTagP ("FocalLength"))) { - rtexif::Tag* flt = mnote->getTag ("FocalLength"); - focal_len = flt->toDouble (); + focal_len = mnote->getTag("FocalLength")->toDouble (); } if (mnote->getTag ("FocalLengthIn35mmFilm")) { diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 43b296746..534484c3e 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -405,7 +405,6 @@ public: // Get the value as a double virtual double toDouble (const Tag* t, int ofs = 0) { - double ud, dd; switch (t->getType()) { case SBYTE: @@ -428,10 +427,11 @@ public: return (double) ((int)sget4 (t->getValue() + ofs, t->getOrder())); case SRATIONAL: - case RATIONAL: - ud = (int)sget4 (t->getValue() + ofs, t->getOrder()); - dd = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); - return dd == 0. ? 0. : (double)ud / (double)dd; + case RATIONAL: { + const double dividend = (int)sget4 (t->getValue() + ofs, t->getOrder()); + const double divisor = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); + return divisor == 0. ? 0. : dividend / divisor; + } case FLOAT: return double (sget4 (t->getValue() + ofs, t->getOrder())); diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc index f5adf56f9..46aedc869 100644 --- a/rtgui/bqentryupdater.cc +++ b/rtgui/bqentryupdater.cc @@ -100,13 +100,12 @@ void BatchQueueEntryUpdater::processThread () break; } - rtengine::IImage8* img = nullptr; bool newBuffer = false; if (current.thumbnail && current.pparams) { // the thumbnail and the pparams are provided, it means that we have to build the original preview image double tmpscale; - img = current.thumbnail->processThumbImage (*current.pparams, current.oh, tmpscale); + rtengine::IImage8* img = current.thumbnail->processThumbImage (*current.pparams, current.oh, tmpscale); //current.thumbnail->decreaseRef (); // WARNING: decreasing refcount (and maybe deleting) thumbnail, with or without processed image if (img) { diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index c59561903..1f8e83c3e 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1377,7 +1377,7 @@ void EditorPanel::info_toggled () infoString = M ("QINFO_NOEXIF"); } - iareapanel->imageArea->setInfoText (infoString); + iareapanel->imageArea->setInfoText (std::move(infoString)); iareapanel->imageArea->infoEnabled (info->get_active ()); } diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index eb3704076..eda07af03 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -298,17 +298,14 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx1, recty1); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - std::valarray ds (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx1, recty1); cr->line_to (rectx2, recty1); cr->line_to (rectx2, recty2); cr->line_to (rectx1, recty2); cr->line_to (rectx1, recty1); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); if (cparams.guide != "Rule of diagonals" && cparams.guide != "Golden Triangle 1" && cparams.guide != "Golden Triangle 2") { // draw guide lines @@ -446,14 +443,11 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx2, recty2); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - std::valarray ds (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx1, recty1); cr->line_to (rectx2, recty2); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); double height = recty2 - recty1; double width = rectx2 - rectx1; @@ -470,14 +464,11 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - ds.resize (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx1, recty2); cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); x = width - (a * b) / height; y = (b * (d - a)) / width; @@ -486,14 +477,11 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - ds.resize (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx2, recty1); cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); } } @@ -675,12 +663,6 @@ MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) : statusImage->set_can_focus(false); - Glib::ustring str("-"); - - if (!titleLabel.empty()) { - str = titleLabel; - } - label = Gtk::manage(new Gtk::Label()); setExpandAlignProperties(label, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); label->set_markup(Glib::ustring("") + escapeHtmlChars(titleLabel) + Glib::ustring("")); @@ -1604,7 +1586,7 @@ bool BackBuffer::setDrawRectangle(Glib::RefPtr window, int newX, in x = newX; y = newY; - if (newH > 0) { + if (newW > 0) { w = newW; } if (newH > 0) { @@ -1637,7 +1619,7 @@ bool BackBuffer::setDrawRectangle(Cairo::Format format, int newX, int newY, int x = newX; y = newY; - if (newH > 0) { + if (newW > 0) { w = newW; } if (newH > 0) { diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 49960b2db..12da0cc0d 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -464,7 +464,6 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin if (surface) { Cairo::RefPtr cc = Cairo::Context::create(surface); - Glib::RefPtr style = get_style_context(); cc->set_source_rgba (0., 0., 0., 0.); cc->set_operator (Cairo::OPERATOR_CLEAR); @@ -616,7 +615,6 @@ void HistogramRGBArea::on_realize () { Gtk::DrawingArea::on_realize(); - Glib::RefPtr window = get_window(); add_events(Gdk::BUTTON_PRESS_MASK); } @@ -984,7 +982,6 @@ void HistogramArea::on_realize () { Gtk::DrawingArea::on_realize(); - Glib::RefPtr window = get_window(); add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); } @@ -1037,8 +1034,6 @@ void HistogramArea::drawMarks(Cairo::RefPtr &cr, bool HistogramArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - Glib::RefPtr window = get_window(); - if (get_width() != oldwidth || get_height() != oldheight || isDirty ()) { updateBackBuffer (); } diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index 0ab1ac61d..ed880bd0e 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -674,8 +674,6 @@ void ICCProfileCreator::savePressed() //necessary for V2 profile if (!v2except) { - std::string is_RTv4 = ""; - //used partially for v4, and in case of if we want to back to old manner for v2 if (primariesPreset == "ACES-AP0" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.ACESp0)) { sNewProfile = options.rtSettings.ACESp0; @@ -687,11 +685,9 @@ void ICCProfileCreator::savePressed() sNewProfile = options.rtSettings.adobe; sPrimariesPreset = "Medium"; } else if (primariesPreset == "ProPhoto" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.prophoto)) { - is_RTv4 = options.rtSettings.prophoto.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.prophoto.substr(0, 4) == "RTv4") { options.rtSettings.prophoto = "RTv2_Large"; - }; + } sNewProfile = options.rtSettings.prophoto; @@ -703,32 +699,26 @@ void ICCProfileCreator::savePressed() sNewProfile = options.rtSettings.srgb; sPrimariesPreset = "sRGB"; } else if (primariesPreset == "Widegamut" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.widegamut)) { - is_RTv4 = options.rtSettings.widegamut.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.widegamut.substr(0, 4) == "RTv4") { options.rtSettings.widegamut = "RTv2_Wide"; - }; + } sNewProfile = options.rtSettings.widegamut; sPrimariesPreset = "Wide"; } else if (primariesPreset == "BestRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.best)) { - is_RTv4 = options.rtSettings.best.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.best.substr(0, 4) == "RTv4") { options.rtSettings.best = "RTv2_Best"; - }; + } sNewProfile = options.rtSettings.best; sPrimariesPreset = "Best"; } else if (primariesPreset == "BetaRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.beta)) { sNewProfile = options.rtSettings.beta; - is_RTv4 = options.rtSettings.beta.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.beta.substr(0, 4) == "RTv4") { options.rtSettings.widegamut = "RTv2_Beta"; - }; + } sPrimariesPreset = "Beta"; } else if (primariesPreset == "BruceRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.bruce)) { diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index e7efa20e9..c0944eef6 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -617,8 +617,6 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) } else { pp->icm.inputProfile = ""; // just a directory } - - Glib::ustring p = Glib::path_get_dirname(ipDialog->get_filename()); } pp->icm.workingProfile = wProfNames->get_active_text(); diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 886d9ff5b..24b793fd9 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -29,7 +29,6 @@ ImageArea::ImageArea (ImageAreaPanel* p) : parent(p), fullImageWidth(0), fullImageHeight(0) { - infotext = ""; cropgl = nullptr; pmlistener = nullptr; pmhlistener = nullptr; @@ -148,7 +147,7 @@ void ImageArea::on_style_updated () void ImageArea::setInfoText (Glib::ustring text) { - infotext = text; + infotext = std::move(text); Glib::RefPtr context = get_pango_context () ; Pango::FontDescription fontd(get_style_context()->get_font()); @@ -160,7 +159,7 @@ void ImageArea::setInfoText (Glib::ustring text) // create text layout Glib::RefPtr ilayout = create_pango_layout(""); - ilayout->set_markup(text); + ilayout->set_markup(infotext); // get size of the text block int iw, ih; diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index a183a3419..85c5f463d 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -83,7 +83,6 @@ InspectorBuffer::~InspectorBuffer() { Inspector::Inspector () : currImage(nullptr), zoom(0.0), active(false) { - Glib::RefPtr style = get_style_context(); set_name("Inspector"); } @@ -115,7 +114,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) // compute the displayed area rtengine::Coord availableSize; rtengine::Coord topLeft; - rtengine::Coord displayedSize; rtengine::Coord dest(0, 0); availableSize.x = win->get_width(); availableSize.y = win->get_height(); @@ -125,7 +123,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) if (imW < availableSize.x) { // center the image in the available space along X topLeft.x = 0; - displayedSize.x = availableSize.x; dest.x = (availableSize.x - imW) / 2; } else { // partial image display @@ -139,7 +136,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) if (imH < availableSize.y) { // center the image in the available space along Y topLeft.y = 0; - displayedSize.y = availableSize.y; dest.y = (availableSize.y - imH) / 2; } else { // partial image display diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index cd687f252..593ac95df 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -37,12 +37,10 @@ int RTImage::scaleBack = 0; RTImage::RTImage () {} -RTImage::RTImage (RTImage &other) +RTImage::RTImage (RTImage &other) : surface(other.surface), pixbuf(other.pixbuf) { dpiBack = other.dpiBack; scaleBack = other.scaleBack; - pixbuf = other.pixbuf; - surface = other.surface; if (pixbuf) { set(pixbuf); } else if (surface) { diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 6158cb76a..85b902727 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -173,8 +173,8 @@ RTWindow::RTWindow () } else { Glib::RefPtr style = Gtk::StyleContext::create(); Pango::FontDescription pfd = style->get_font(Gtk::STATE_FLAG_NORMAL); - int pt; if (pfd.get_set_fields() & Pango::FONT_MASK_SIZE) { + int pt; int fontSize = pfd.get_size(); bool isPix = pfd.get_size_is_absolute(); int resolution = (int)style->get_screen()->get_resolution(); @@ -254,8 +254,6 @@ RTWindow::RTWindow () #if defined(__APPLE__) { osxApp = (GtkosxApplication *)g_object_new (GTKOSX_TYPE_APPLICATION, NULL); - gboolean falseval = FALSE; - gboolean trueval = TRUE; RTWindow *rtWin = this; g_signal_connect (osxApp, "NSApplicationBlockTermination", G_CALLBACK (osx_should_quit_cb), rtWin); g_signal_connect (osxApp, "NSApplicationWillTerminate", G_CALLBACK (osx_will_quit_cb), rtWin); diff --git a/rtgui/splash.cc b/rtgui/splash.cc index d608ccd97..36b796c4d 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -27,15 +27,13 @@ extern Glib::ustring creditsPath; extern Glib::ustring licensePath; extern Glib::ustring versionString; -SplashImage::SplashImage () +SplashImage::SplashImage () : surface(RTImage::createImgSurfFromFile("splash.png")) { - surface = RTImage::createImgSurfFromFile ("splash.png"); } bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - Glib::RefPtr window = get_window(); cr->set_source(surface, 0., 0.); cr->rectangle(0, 0, surface->get_width(), surface->get_height()); cr->fill(); diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index e1e6fc36f..9b5250862 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -30,7 +30,7 @@ ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom, double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop, ThresholdCurveProvider* curveProvider) - : coloredBar(RTO_Left2Right) + : separatedLabelBottom(std::move(labelBottom)), separatedLabelTop(std::move(labelTop)), coloredBar(RTO_Left2Right) { positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom; positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop; @@ -40,8 +40,6 @@ ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBotto this->precisionBottom = precisionBottom; doubleThresh = false; - separatedLabelBottom = labelBottom; - separatedLabelTop = labelTop; bgCurveProvider = curveProvider; separatedSliders = true; @@ -66,9 +64,6 @@ ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double de this->precisionBottom = precision; doubleThresh = false; - separatedLabelBottom = ""; - separatedLabelTop = ""; - #ifndef NDEBUG if (startAtOne) { @@ -106,9 +101,6 @@ ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double de this->precisionBottom = precision; doubleThresh = true; - separatedLabelBottom = ""; - separatedLabelTop = ""; - #ifndef NDEBUG if (startAtOne) { @@ -329,14 +321,13 @@ void ThresholdSelector::updateBackBuffer() if (pts.size() >= 4) { std::vector::iterator i = pts.begin(); - double x = *i; ++i; double y = *i; ++i; cr->move_to (xStart, ih*y + yStart); for (; i < pts.end(); ) { - x = *i; + double x = *i; ++i; y = *i; ++i; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 761dc5e04..aa3443829 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -382,7 +382,6 @@ void WhiteBalance::adjusterChanged(Adjuster* a, double newval) return; } - Glib::ustring colLabel = row[methodColumns.colLabel]; const std::pair ppMethod = findWBEntry (row[methodColumns.colLabel], WBLT_GUI); const std::pair wbCustom = findWBEntry ("Custom", WBLT_PP); From 41fc34c5c6fa5c1672ba99deb19d9c5709eb94e8 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 31 Jul 2019 20:21:16 +0200 Subject: [PATCH 086/222] Do not assign empty strings on creation of std::string or Glib::ustring --- rtengine/procparams.cc | 2 +- rtengine/profilestore.cc | 2 +- rtengine/rtlensfun.cc | 2 +- rtgui/batchqueue.cc | 4 ++-- rtgui/batchqueueentry.cc | 1 - rtgui/coordinateadjuster.cc | 2 +- rtgui/curveeditorgroup.cc | 2 +- rtgui/exifpanel.cc | 2 +- rtgui/favoritbrowser.cc | 2 +- rtgui/filecatalog.cc | 2 -- rtgui/flatfield.cc | 1 - rtgui/icmpanel.cc | 4 +--- rtgui/main-cli.cc | 4 ++-- rtgui/profilepanel.cc | 2 +- 14 files changed, 13 insertions(+), 19 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2118213d5..10d03270f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -65,7 +65,7 @@ Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool f return embedded_fname; } - Glib::ustring prefix = ""; + Glib::ustring prefix; if (embedded_fname.length() > 5 && embedded_fname.substr(0, 5) == "file:") { embedded_fname = embedded_fname.substr(5); diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 437ef6ec6..82074053f 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -535,7 +535,7 @@ PartialProfile *ProfileStore::loadDynamicProfile (const FramesMetaData *im) return ret; } -ProfileStoreEntry::ProfileStoreEntry() : label (""), type (PSET_FOLDER), parentFolderId (0), folderId (0) {} +ProfileStoreEntry::ProfileStoreEntry() : type (PSET_FOLDER), parentFolderId (0), folderId (0) {} ProfileStoreEntry::ProfileStoreEntry (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) : label (label), type (type), parentFolderId (parentFolder), folderId (folder) {} diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 3cea8c484..5f0ffdd91 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -132,7 +132,7 @@ Glib::ustring LFModifier::getDisplayString() const return "NONE"; } else { Glib::ustring ret; - Glib::ustring sep = ""; + Glib::ustring sep; if (flags_ & LF_MODIFY_DISTORTION) { ret += "distortion"; sep = ", "; diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 239057b87..3fb2cd438 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -811,7 +811,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam break; } - Glib::ustring tok = ""; + Glib::ustring tok; while ((i < origFileName.size()) && !(origFileName[i] == '\\' || origFileName[i] == '/')) { tok = tok + origFileName[i++]; @@ -857,7 +857,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam // constructing full output path // printf ("path=|%s|\n", options.savePath.c_str()); - Glib::ustring path = ""; + Glib::ustring path; if (options.saveUsePathTemplate) { unsigned int ix = 0; diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 23982095c..78e3991c7 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -40,7 +40,6 @@ BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine: job(pjob), params(new rtengine::procparams::ProcParams(pparams)), progress(0), - outFileName(""), sequence(0), forceFormatOpts(false), fast_pipeline(job->fastPipeline()), diff --git a/rtgui/coordinateadjuster.cc b/rtgui/coordinateadjuster.cc index 2525a07e5..5065606d9 100644 --- a/rtgui/coordinateadjuster.cc +++ b/rtgui/coordinateadjuster.cc @@ -23,7 +23,7 @@ #include "curveeditorgroup.h" Axis::Axis() - : label(""), decimal(5), increment(0.001), pageIncrement(0.01), rangeLowerBound(0.), rangeUpperBound(1.) + : decimal(5), increment(0.001), pageIncrement(0.01), rangeLowerBound(0.), rangeUpperBound(1.) {} Axis::Axis(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin = 0.0, double valMax = 1.0) diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index 10aff907c..495e4324b 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -397,7 +397,7 @@ void CurveEditorGroup::setUnChanged (bool uc, CurveEditor* ce) } } -CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : curveDir(curveDir), lastFilename(""), valLinear(0), valUnchanged(0), parent(nullptr) +CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : curveDir(curveDir), valLinear(0), valUnchanged(0), parent(nullptr) { leftBar = nullptr; bottomBar = nullptr; diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 6c196e575..f9324e90c 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -632,7 +632,7 @@ Glib::ustring ExifPanel::getSelection (bool onlyeditable) Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); - Glib::ustring ret = ""; + Glib::ustring ret; bool first = true; bool editable = false; diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc index 0e1b4490b..09deacfab 100644 --- a/rtgui/favoritbrowser.cc +++ b/rtgui/favoritbrowser.cc @@ -20,7 +20,7 @@ #include "multilangmgr.h" #include "rtimage.h" -FavoritBrowser::FavoritBrowser () : listener (NULL), lastSelectedDir ("") +FavoritBrowser::FavoritBrowser () : listener (NULL) { scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index dbe540cb4..98e805d3a 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -457,8 +457,6 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : hScrollPos[i] = 0; vScrollPos[i] = 0; } - - selectedDirectory = ""; } FileCatalog::~FileCatalog() diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 25482909e..f69b90170 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -86,7 +86,6 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L flatFieldFileReset->signal_clicked().connect( sigc::mem_fun(*this, &FlatField::flatFieldFile_Reset), true ); flatFieldAutoSelectconn = flatFieldAutoSelect->signal_toggled().connect ( sigc::mem_fun(*this, &FlatField::flatFieldAutoSelectChanged), true); flatFieldBlurTypeconn = flatFieldBlurType->signal_changed().connect( sigc::mem_fun(*this, &FlatField::flatFieldBlurTypeChanged) ); - lastShortcutPath = ""; // Set filename filters b_filter_asCurrent = false; diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index c0944eef6..a6857eaa9 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -34,7 +34,7 @@ using namespace rtengine::procparams; extern Options options; -ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr), lastRefFilename(""), camName("") +ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr) { auto m = ProcEventMapper::getInstance(); EvICMprimariMethod = m->newEvent(GAMMA, "HISTORY_MSG_ICM_OUTPUT_PRIMARIES"); @@ -304,8 +304,6 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha ipDialog->set_show_hidden(true); // ProgramData is hidden on Windows #endif - oldip = ""; - wprofnamesconn = wProfNames->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::wpChanged)); oprofnamesconn = oProfNames->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::opChanged)); orendintentconn = oRendIntent->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::oiChanged)); diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index cbea1d477..f71d7099d 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -256,7 +256,7 @@ int processLineParams ( int argc, char **argv ) { rtengine::procparams::PartialProfile *rawParams = nullptr, *imgParams = nullptr; std::vector inputFiles; - Glib::ustring outputPath = ""; + Glib::ustring outputPath; std::vector processingParams; bool outputDirectory = false; bool leaveUntouched = false; @@ -271,7 +271,7 @@ int processLineParams ( int argc, char **argv ) int subsampling = 3; int bits = -1; bool isFloat = false; - std::string outputType = ""; + std::string outputType; unsigned errors = 0; for ( int iArg = 1; iArg < argc; iArg++) { diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index af39695fa..c969d13c0 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -42,7 +42,7 @@ void ProfilePanel::cleanup () delete partialProfileDlg; } -ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastFilename(""), imagePath(""), lastSavedPSE(nullptr), customPSE(nullptr) +ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastSavedPSE(nullptr), customPSE(nullptr) { tpc = nullptr; From 46cbb652d5384af6243546935ccc5ab0ed491b00 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 1 Aug 2019 14:02:38 +0200 Subject: [PATCH 087/222] cppcheck: further fixes --- rtengine/curves.h | 4 ++-- rtengine/dfmanager.cc | 4 ++-- rtengine/ffmanager.cc | 4 ++-- rtengine/ipshadowshighlights.cc | 20 ++++++++++---------- rtengine/pdaflinesfilter.h | 6 ++++-- rtengine/rawimagesource.cc | 1 + rtexif/nikonattribs.cc | 2 +- rtexif/rtexif.h | 2 +- rtgui/adjuster.cc | 8 ++++---- rtgui/batchqueue.h | 4 +++- rtgui/batchqueueentry.h | 3 ++- rtgui/crop.cc | 9 +++------ rtgui/cropwindow.h | 3 ++- rtgui/curveeditor.h | 3 ++- rtgui/diagonalcurveeditorsubgroup.h | 3 ++- rtgui/editorpanel.h | 4 +++- rtgui/filebrowser.h | 4 +++- rtgui/filebrowserentry.h | 4 +++- rtgui/filecatalog.h | 4 +++- rtgui/filepanel.h | 4 +++- rtgui/filmnegative.h | 3 --- rtgui/flatcurveeditorsubgroup.h | 3 ++- rtgui/histogrampanel.h | 7 ++++--- rtgui/mycurve.h | 3 ++- rtgui/previewhandler.h | 3 ++- rtgui/profilepanel.h | 3 ++- rtgui/rtwindow.h | 3 ++- rtgui/saveformatpanel.h | 3 ++- rtgui/toolpanel.h | 3 ++- rtgui/toolpanelcoord.h | 4 +++- 30 files changed, 77 insertions(+), 54 deletions(-) diff --git a/rtengine/curves.h b/rtengine/curves.h index 98ce68015..55068630a 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -31,7 +31,7 @@ #include "../rtgui/mydiagonalcurve.h" #include "color.h" #include "pipettebuffer.h" - +#include "noncopyable.h" #include "LUT.h" #define CURVES_MIN_POLY_POINTS 1000 @@ -479,7 +479,7 @@ public: }; }; -class FlatCurve : public Curve +class FlatCurve : public Curve, public rtengine::NonCopyable { private: diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index c41c8a180..311921c52 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -328,8 +328,8 @@ void DFManager::init(const Glib::ustring& pathname) } else { printf( "%s: MEAN of \n ", i.key().c_str()); - for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) { - printf( "%s, ", iter->c_str() ); + for(std::list::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) { + printf("%s, ", path->c_str()); } printf("\n"); diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 6e4977076..56660a82a 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -277,8 +277,8 @@ void FFManager::init(const Glib::ustring& pathname) } else { printf( "%s: MEAN of \n ", i.key().c_str()); - for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) { - printf( "%s, ", iter->c_str() ); + for(std::list::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) { + printf("%s, ", path->c_str()); } printf("\n"); diff --git a/rtengine/ipshadowshighlights.cc b/rtengine/ipshadowshighlights.cc index 6ce66d9b3..2433ca13c 100644 --- a/rtengine/ipshadowshighlights.cc +++ b/rtengine/ipshadowshighlights.cc @@ -106,10 +106,10 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab) #pragma omp parallel for if (multiThread) #endif for (int l = 0; l < 32768; ++l) { - auto base = pow_F(l / 32768.f, gamma); + auto val = pow_F(l / 32768.f, gamma); // get a bit more contrast in the shadows - base = sh_contrast.getVal(base); - f[l] = base * 32768.f; + val = sh_contrast.getVal(val); + f[l] = val * 32768.f; } } else { #ifdef _OPENMP @@ -119,10 +119,10 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab) float l, a, b; float R = c, G = c, B = c; rgb2lab(R, G, B, l, a, b); - auto base = pow_F(l / 32768.f, gamma); + auto val = pow_F(l / 32768.f, gamma); // get a bit more contrast in the shadows - base = sh_contrast.getVal(base); - l = base * 32768.f; + val = sh_contrast.getVal(val); + l = val * 32768.f; lab2rgb(l, a, b, R, G, B); f[c] = G; } @@ -133,8 +133,8 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab) #pragma omp parallel for if (multiThread) #endif for (int l = 0; l < 32768; ++l) { - auto base = pow_F(l / 32768.f, gamma); - f[l] = base * 32768.f; + auto val = pow_F(l / 32768.f, gamma); + f[l] = val * 32768.f; } } else { #ifdef _OPENMP @@ -144,8 +144,8 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab) float l, a, b; float R = c, G = c, B = c; rgb2lab(R, G, B, l, a, b); - auto base = pow_F(l / 32768.f, gamma); - l = base * 32768.f; + auto val = pow_F(l / 32768.f, gamma); + l = val * 32768.f; lab2rgb(l, a, b, R, G, B); f[c] = G; } diff --git a/rtengine/pdaflinesfilter.h b/rtengine/pdaflinesfilter.h index b1f7bf650..3ae406ec8 100644 --- a/rtengine/pdaflinesfilter.h +++ b/rtengine/pdaflinesfilter.h @@ -20,12 +20,14 @@ #pragma once -#include "rawimagesource.h" #include +#include "rawimagesource.h" +#include "noncopyable.h" namespace rtengine { -class PDAFLinesFilter { +class PDAFLinesFilter: public rtengine::NonCopyable +{ public: explicit PDAFLinesFilter(RawImage *ri); ~PDAFLinesFilter(); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 9f310508f..6cb6fff16 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -429,6 +429,7 @@ RawImageSource::RawImageSource () , plistener(nullptr) , scale_mul{} , c_black{} + , c_white{} , cblacksom{} , ref_pre_mul{} , refwb_red(0.0) diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc index 1c6ead006..678b4b568 100644 --- a/rtexif/nikonattribs.cc +++ b/rtexif/nikonattribs.cc @@ -380,7 +380,7 @@ public: } } - std::string EffectiveMaxApertureString = ""; + std::string EffectiveMaxApertureString; if (!d100) { int EffectiveMaxApertureValue; diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 534484c3e..e1e1d6668 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -190,7 +190,7 @@ public: }; // a table of tags: id are offset from beginning and not identifiers -class TagDirectoryTable: public TagDirectory +class TagDirectoryTable: public TagDirectory, public rtengine::NonCopyable { protected: unsigned char *values; // Tags values are saved internally here diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index 0d2c2961f..5a3f783db 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -631,21 +631,21 @@ void Adjuster::setSliderValue(double val) if (val >= logPivot) { double range = vMax - logPivot; double x = (val - logPivot) / range; - val = (vMin + mid) + std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * mid; + val = (vMin + mid) + std::log1p(x * (logBase - 1.0)) / std::log(logBase) * mid; } else { double range = logPivot - vMin; double x = (logPivot - val) / range; - val = (vMin + mid) - std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * mid; + val = (vMin + mid) - std::log1p(x * (logBase - 1.0)) / std::log(logBase) * mid; } } else { if (val >= logPivot) { double range = vMax - logPivot; double x = (val - logPivot) / range; - val = logPivot + std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * range; + val = logPivot + std::log1p(x * (logBase - 1.0)) / std::log(logBase) * range; } else { double range = logPivot - vMin; double x = (logPivot - val) / range; - val = logPivot - std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * range; + val = logPivot - std::log1p(x * (logBase - 1.0)) / std::log(logBase) * range; } } } diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index 95d92aef2..6f1b8f7f8 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -29,6 +29,7 @@ #include "options.h" #include "threadutils.h" #include "thumbbrowserbase.h" +#include "../rtengine/noncopyable.h" class BatchQueueListener { @@ -44,7 +45,8 @@ class FileCatalog; class BatchQueue final : public ThumbBrowserBase, public rtengine::BatchProcessingListener, - public LWButtonListener + public LWButtonListener, + public rtengine::NonCopyable { public: explicit BatchQueue (FileCatalog* aFileCatalog); diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index 0ea56e403..4972eaf7a 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -26,6 +26,7 @@ #include "thumbbrowserentrybase.h" #include "thumbnail.h" #include "bqentryupdater.h" +#include "../rtengine/noncopyable.h" class BatchQueueEntry; struct BatchQueueEntryIdleHelper { @@ -34,7 +35,7 @@ struct BatchQueueEntryIdleHelper { int pending; }; -class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListener +class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListener, public rtengine::NonCopyable { guint8* opreview; diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 781a916a1..a8b12819e 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -1400,24 +1400,19 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2) y2 = maxh - 1; } - int X, Y; int W; if (x < x2) { W = x2 - x + 1; - X = x; } else { W = x - x2 + 1; - X = x2; } - int H; + int Y; if (y < y2) { - H = y2 - y + 1; Y = y; } else { - H = y - y2 + 1; Y = y2; } @@ -1425,6 +1420,7 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2) W = maxw; } + int H; if (fixr->get_active()) { double r = getRatio (); @@ -1457,6 +1453,7 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2) } } + int X; if (x < x2) { W = x2 - x + 1; X = x; diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 6e2097d3b..26edf69ee 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -31,6 +31,7 @@ #include "cursormanager.h" #include "editbuffer.h" #include "editcoordsys.h" +#include "../rtengine/noncopyable.h" class CropWindow; @@ -45,7 +46,7 @@ public: }; class ImageArea; -class CropWindow : public LWButtonListener, public CropDisplayHandler, public EditCoordSystem, public ObjectMOBuffer +class CropWindow : public LWButtonListener, public CropDisplayHandler, public EditCoordSystem, public ObjectMOBuffer, public rtengine::NonCopyable { static bool initialized; diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h index 1227edc0f..e38d3f205 100644 --- a/rtgui/curveeditor.h +++ b/rtgui/curveeditor.h @@ -25,6 +25,7 @@ #include "editcallbacks.h" #include "mydiagonalcurve.h" #include "myflatcurve.h" +#include "../rtengine/noncopyable.h" class CurveEditorGroup; class CurveEditorSubGroup; @@ -38,7 +39,7 @@ class CurveEditorSubGroup; /** @brief This class is an interface between RT and the curve editor group * It handles the methods related to a specific curve. It is created by CurveEditorGroup::addCurve */ -class CurveEditor : public EditSubscriber +class CurveEditor : public EditSubscriber, public rtengine::NonCopyable { friend class CurveEditorGroup; diff --git a/rtgui/diagonalcurveeditorsubgroup.h b/rtgui/diagonalcurveeditorsubgroup.h index 54f424dc6..68047e0c2 100644 --- a/rtgui/diagonalcurveeditorsubgroup.h +++ b/rtgui/diagonalcurveeditorsubgroup.h @@ -21,10 +21,11 @@ #include #include "curveeditorgroup.h" +#include "../rtengine/noncopyable.h" class DiagonalCurveEditor; -class DiagonalCurveEditorSubGroup : public CurveEditorSubGroup, public SHCListener, public AdjusterListener +class DiagonalCurveEditorSubGroup : public CurveEditorSubGroup, public SHCListener, public AdjusterListener, public rtengine::NonCopyable { friend class DiagonalCurveEditor; diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index de5360646..7fe79b827 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -34,6 +34,7 @@ #include "navigator.h" #include "progressconnector.h" #include "filepanel.h" +#include "../rtengine/noncopyable.h" class EditorPanel; class MyProgressBar; @@ -52,7 +53,8 @@ class EditorPanel final : public rtengine::ProgressListener, public ThumbnailListener, public HistoryBeforeLineListener, - public rtengine::HistogramListener + public rtengine::HistogramListener, + public rtengine::NonCopyable { public: explicit EditorPanel (FilePanel* filePanel = nullptr); diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index b208a854d..9c7a86f74 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -30,6 +30,7 @@ #include "exportpanel.h" #include "extprog.h" #include "profilestorecombobox.h" +#include "../rtengine/noncopyable.h" class ProfileStoreLabel; class FileBrowser; @@ -56,7 +57,8 @@ public: class FileBrowser : public ThumbBrowserBase, public LWButtonListener, public ExportPanelListener, - public ProfileStoreListener + public ProfileStoreListener, + public rtengine::NonCopyable { private: typedef sigc::signal type_trash_changed; diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 5122de55f..bd3a266aa 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -34,6 +34,7 @@ #include "thumbimageupdater.h" #include "thumbnail.h" #include "thumbnaillistener.h" +#include "../rtengine/noncopyable.h" class FileBrowserEntry; @@ -46,7 +47,8 @@ struct FileBrowserEntryIdleHelper { class FileThumbnailButtonSet; class FileBrowserEntry : public ThumbBrowserEntryBase, public ThumbnailListener, - public ThumbImageUpdateListener + public ThumbImageUpdateListener, + public rtengine::NonCopyable { double scale; diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 2f3054bcf..0ff2fb1e8 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -32,6 +32,7 @@ #include "previewloader.h" #include "multilangmgr.h" #include "threadutils.h" +#include "../rtengine/noncopyable.h" class FilePanel; /* @@ -44,7 +45,8 @@ class FileCatalog : public Gtk::VBox, public PreviewLoaderListener, public FilterPanelListener, public FileBrowserListener, - public ExportPanelListener + public ExportPanelListener, + public rtengine::NonCopyable { public: typedef sigc::slot DirSelectionSlot; diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h index df61cb60d..0385c48d3 100644 --- a/rtgui/filepanel.h +++ b/rtgui/filepanel.h @@ -31,12 +31,14 @@ #include "filterpanel.h" #include "exportpanel.h" #include "progressconnector.h" +#include "../rtengine/noncopyable.h" class RTWindow; class FilePanel final : public Gtk::HPaned, - public FileSelectionListener + public FileSelectionListener, + public rtengine::NonCopyable { public: FilePanel (); diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index e967f535c..a1efdc455 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -28,8 +28,6 @@ #include "toolpanel.h" #include "wbprovider.h" -#include "../rtengine/noncopyable.h" - class FilmNegProvider { public: @@ -39,7 +37,6 @@ public: }; class FilmNegative : - public rtengine::NonCopyable, public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/flatcurveeditorsubgroup.h b/rtgui/flatcurveeditorsubgroup.h index ab2abedfb..f931bf660 100644 --- a/rtgui/flatcurveeditorsubgroup.h +++ b/rtgui/flatcurveeditorsubgroup.h @@ -21,10 +21,11 @@ #include #include "curveeditorgroup.h" +#include "../rtengine/noncopyable.h" class FlatCurveEditor; -class FlatCurveEditorSubGroup: public CurveEditorSubGroup +class FlatCurveEditorSubGroup: public CurveEditorSubGroup, public rtengine::NonCopyable { friend class FlatCurveEditor; diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index f34b07c39..f66d2e654 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -28,6 +28,7 @@ #include "guiutils.h" #include "pointermotionlistener.h" +#include "../rtengine/noncopyable.h" class HistogramArea; struct HistogramAreaIdleHelper { @@ -51,7 +52,7 @@ public: double log (double vsize, double val); }; -class HistogramRGBArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling +class HistogramRGBArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling, public rtengine::NonCopyable { private: typedef const double (*TMatrix)[3]; @@ -114,7 +115,7 @@ public: virtual void toggleButtonMode() = 0; }; -class HistogramArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling +class HistogramArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling, public rtengine::NonCopyable { public: typedef sigc::signal type_signal_factor_changed; @@ -172,7 +173,7 @@ private: void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const override; }; -class HistogramPanel : public Gtk::Grid, public PointerMotionListener, public DrawModeListener +class HistogramPanel : public Gtk::Grid, public PointerMotionListener, public DrawModeListener, public rtengine::NonCopyable { protected: diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index 82dd4a1a4..81a747bcd 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -28,6 +28,7 @@ #include "../rtengine/LUT.h" #include "guiutils.h" #include "options.h" +#include "../rtengine/noncopyable.h" #define RADIUS 3.5 /** radius of the control points ; must be x.5 to target the center of a pixel */ #define CBAR_WIDTH 10 /** inner width of the colored bar (border excluded) */ @@ -55,7 +56,7 @@ enum SnapToType { class MyCurveIdleHelper; class CurveEditor; -class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider +class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider, public rtengine::NonCopyable { friend class MyCurveIdleHelper; diff --git a/rtgui/previewhandler.h b/rtgui/previewhandler.h index fcd0a0c5f..7a93ed480 100644 --- a/rtgui/previewhandler.h +++ b/rtgui/previewhandler.h @@ -28,6 +28,7 @@ #include "guiutils.h" #include "../rtengine/rtengine.h" +#include "../rtengine/noncopyable.h" class PreviewListener { @@ -44,7 +45,7 @@ struct PreviewHandlerIdleHelper { int pending; }; -class PreviewHandler : public rtengine::PreviewImageListener +class PreviewHandler : public rtengine::PreviewImageListener, public rtengine::NonCopyable { private: friend int setImageUI (void* data); diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index b0fb42ab7..bc42f96c3 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -28,8 +28,9 @@ #include "guiutils.h" #include "profilestorecombobox.h" #include "rtimage.h" +#include "../rtengine/noncopyable.h" -class ProfilePanel : public Gtk::Grid, public PParamsChangeListener, public ProfileStoreListener +class ProfilePanel : public Gtk::Grid, public PParamsChangeListener, public ProfileStoreListener, public rtengine::NonCopyable { private: diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index 5b58ab0eb..d037d8875 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -29,8 +29,9 @@ #if defined(__APPLE__) #include #endif +#include "../rtengine/noncopyable.h" -class RTWindow : public Gtk::Window, public rtengine::ProgressListener +class RTWindow : public Gtk::Window, public rtengine::ProgressListener, public rtengine::NonCopyable { private: diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index e25210b97..7d7210282 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -23,6 +23,7 @@ #include "adjuster.h" #include "guiutils.h" #include "options.h" +#include "../rtengine/noncopyable.h" class FormatChangeListener { @@ -31,7 +32,7 @@ public: virtual void formatChanged(const Glib::ustring& format) = 0; }; -class SaveFormatPanel : public Gtk::Grid, public AdjusterListener +class SaveFormatPanel : public Gtk::Grid, public AdjusterListener, public rtengine::NonCopyable { protected: diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index 2da5f1bba..1d3630c6d 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -26,6 +26,7 @@ #include "guiutils.h" #include "multilangmgr.h" #include "paramsedited.h" +#include "../rtengine/noncopyable.h" class ToolPanel; class FoldableToolPanel; @@ -51,7 +52,7 @@ public: ToolParamBlock(); }; -class ToolPanel +class ToolPanel : public rtengine::NonCopyable { protected: diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 5569861ae..a1b26b29f 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -83,6 +83,7 @@ #include "dehaze.h" #include "guiutils.h" #include "filmnegative.h" +#include "../rtengine/noncopyable.h" class ImageEditorCoordinator; @@ -99,7 +100,8 @@ class ToolPanelCoordinator : public ICMPanelListener, public ImageAreaToolListener, public rtengine::ImageTypeListener, - public FilmNegProvider + public FilmNegProvider, + public rtengine::NonCopyable { protected: WhiteBalance* whitebalance; From 13a1b59c46e8223b8be6f42b4c2dbe704480787e Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 1 Aug 2019 21:35:52 +0200 Subject: [PATCH 088/222] Better white level for Canon EOS 400D DIGITAL --- rtengine/camconst.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 894414f8a..ab90a03a3 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -805,6 +805,12 @@ Camera constants: // Canon mid-range DSLRs (Rebels) + { // Quality C + "make_model": [ "Canon EOS 400D DIGITAL" ], + "ranges": { + "white": 4056 + }, + { // Quality B, ISO and aperture WL data by ..... at RawTherapee forums, missing samples safely guessed "make_model": [ "Canon EOS 550D", "Canon EOS Rebel T2i", "Canon EOS Kiss X4" ], "dcraw_matrix": [ 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 ], // dcraw 550d From 2ec224c9ef2f9427e79d87d18367424c8c6cc576 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 1 Aug 2019 21:48:24 +0200 Subject: [PATCH 089/222] Fix wrong camconst.json entry --- rtengine/camconst.json | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index ab90a03a3..2f0f5ff40 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -809,6 +809,7 @@ Camera constants: "make_model": [ "Canon EOS 400D DIGITAL" ], "ranges": { "white": 4056 + } }, { // Quality B, ISO and aperture WL data by ..... at RawTherapee forums, missing samples safely guessed From b36e14c73185ed2d0fb018f9d2d26ea57df111f2 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 2 Aug 2019 11:49:25 +0200 Subject: [PATCH 090/222] raw crop for LEICA Q2 --- rtengine/camconst.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 2f0f5ff40..9551d5e16 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1366,6 +1366,11 @@ Camera constants: "raw_crop": [ 4, 4, -4, -4 ] // full raw 6016x4016, Official 6000x4000 }, + { // Quality C + "make_model": "LEICA Q2", + "raw_crop": [ 0, 0, 8392, 5624 ] + }, + { // Quality B, Matrix from Adobe's dcp D65 instead of the internal in Leica's DNG "make_model": "LEICA SL (Typ 601)", "dcraw_matrix": [ 11492,-4930,-1188,-5593,14673,873,-609,1474,6343 ], // DNGv9.3 D65 From 06f224a4eb9f51a7286a882819424ef2f3e80115 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Fri, 2 Aug 2019 13:28:48 +0200 Subject: [PATCH 091/222] Fixes #5397 by requiring thumbnail reprocessing when filmnegative params are changed. --- rtgui/thumbnail.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 6ac3d629b..eedff3029 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -474,6 +474,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh || pparams->filmSimulation != pp.filmSimulation || pparams->softlight != pp.softlight || pparams->dehaze != pp.dehaze + || pparams->filmNegative != pp.filmNegative || whoChangedIt == FILEBROWSER || whoChangedIt == BATCHEDITOR; From e7d10bbf76e0c4cd6aed4831b297c565f046b8b1 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 2 Aug 2019 16:03:03 +0200 Subject: [PATCH 092/222] Fixes broken clear processing profile when image has same rank as thumb --- rtengine/procparams.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2118213d5..cb27fc2b3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2878,7 +2878,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo keyFile.set_string("Version", "AppVersion", RTVERSION); keyFile.set_integer("Version", "Version", PPVERSION); - saveToKeyfile(!pedited || pedited->general.rank, "General", "Rank", std::max(rank, 0), keyFile); + saveToKeyfile(!pedited || pedited->general.rank, "General", "Rank", rank, keyFile); saveToKeyfile(!pedited || pedited->general.colorlabel, "General", "ColorLabel", colorlabel, keyFile); saveToKeyfile(!pedited || pedited->general.intrash, "General", "InTrash", inTrash, keyFile); From 1b8dd7c49a524952281fc4812e0baf6d77127156 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Mon, 5 Aug 2019 12:11:18 +0200 Subject: [PATCH 093/222] Added camera model aliases Partly related to #5400 --- rtdata/dcpprofiles/camera_model_aliases.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtdata/dcpprofiles/camera_model_aliases.json b/rtdata/dcpprofiles/camera_model_aliases.json index 61fc2bf57..32db0db52 100644 --- a/rtdata/dcpprofiles/camera_model_aliases.json +++ b/rtdata/dcpprofiles/camera_model_aliases.json @@ -16,6 +16,8 @@ "Canon EOS 1000D": ["Canon EOS Kiss Digital F", "Canon EOS DIGITAL REBEL XS"], "Canon EOS 1200D": ["Canon EOS Kiss X70", "Canon EOS REBEL T5"], "Canon EOS 1300D": ["Canon EOS Kiss X80", "Canon EOS Rebel T6"], + "Canon EOS 2000D": ["Canon EOS 1500D", "Canon EOS Kiss X90", "Canon EOS Rebel T7"], + "Canon EOS 4000D": ["Canon EOS 3000D", "Canon EOS Rebel T100"], "MINOLTA DYNAX 5D": ["Minolta Maxxum 5D", "Minolta Alpha 5D", "Minolta Alpha Sweet"], "MINOLTA DYNAX 7D": ["Minolta Maxxum 7D", "Minolta Alpha 7D"], From 972d6907d560569e97ea41bab315ab5ea0855b17 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 6 Aug 2019 14:51:30 +0200 Subject: [PATCH 094/222] raw crop for OLYMPUS TG-5 and TG-6 --- rtengine/camconst.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 9551d5e16..9d96975c8 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1725,9 +1725,15 @@ Camera constants: { // Quality B, "make_model": "OLYMPUS TG-5", "dcraw_matrix": [ 10899,-3833,-1082,-2112,10736,1575,-267,1452,5269 ], // DNG_V9.12 D65 + "raw_crop": [ 0, 0, -18, 0 ], // 18 pixels at right are garbage "ranges": { "white": 4050 } // safe for worst case detected, nominal is 4093 }, + { // Quality C, only raw crop + "make_model": "OLYMPUS TG-6", + "raw_crop": [ 0, 0, -24, 0 ] // 24 pixels at right are garbage + }, + { // Quality C, only green equilibration "make_model" : ["OLYMPUS E-3", "OLYMPUS E-520"], "global_green_equilibration" : true From 5e9a409dba357b9d9860e496fdbf73e190141f06 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 6 Aug 2019 17:34:14 +0200 Subject: [PATCH 095/222] cbdl code cleanup --- rtengine/array2D.h | 6 + rtengine/dirpyr_equalizer.cc | 975 ++++++++++++----------------------- rtengine/helpersse2.h | 2 +- rtengine/improcfun.cc | 2 +- rtengine/improcfun.h | 7 +- 5 files changed, 338 insertions(+), 654 deletions(-) diff --git a/rtengine/array2D.h b/rtengine/array2D.h index 48a789bf8..84728f043 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -214,6 +214,12 @@ public: return ptr; } + // use as pointer to T** + operator const T* const *() + { + return ptr; + } + // use as pointer to data operator T*() { diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 4a30b48a8..94826e06e 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -16,7 +16,7 @@ * * (C) 2010 Emil Martinec * - */ +*/ #include #include @@ -25,404 +25,55 @@ #include "rt_math.h" #include "opthelper.h" -#define RANGEFN(i) ((1000.0f / (i + 1000.0f))) -#define DIRWT(i1,j1,i,j) ( domker[(i1-i)/scale+halfwin][(j1-j)/scale+halfwin] * RANGEFN(fabsf((data_fine[i1][j1]-data_fine[i][j]))) ) - -namespace rtengine -{ - -constexpr int maxlevel = 6; -constexpr float noise = 2000; - -//sequence of scales -constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; -extern const Settings* settings; - -//sequence of scales - -void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) -{ - int lastlevel = maxlevel; - - float atten123 = (float) settings->level123_cbdl; - - if(atten123 > 50.f) { - atten123 = 50.f; - } - - if(atten123 < 0.f) { - atten123 = 0.f; - } - - float atten0 = (float) settings->level0_cbdl; - - if(atten0 > 40.f) { - atten123 = 40.f; - } - - if(atten0 < 0.f) { - atten0 = 0.f; - } - - if((t_r - t_l) < 0.55f) { - t_l = t_r + 0.55f; //avoid too small range - } - - - while (lastlevel > 0 && fabs(mult[lastlevel - 1] - 1) < 0.001) { - lastlevel--; - //printf("last level to process %d \n",lastlevel); - } - - if (lastlevel == 0) { - return; - } - - int level; - float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[maxlevel]; - - for(int lv = 0; lv < maxlevel; lv++) { - scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; - - if(lv >= 1) { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten123 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% - } else { - multi[lv] = (float) mult[lv]; - } - } else { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten0 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% - } else { - multi[lv] = (float) mult[lv]; - } - } - - } - - multi_array2D dirpyrlo (srcwidth, srcheight); - - level = 0; - - //int thresh = 100 * mult[5]; - int scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - - dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale); - - level = 1; - - while(level < lastlevel) { - - scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale); - - level ++; - } - - float **tmpHue = nullptr, **tmpChr = nullptr; - - if(skinprot != 0.f) { - // precalculate hue and chroma, use SSE, if available - // by precalculating these values we can greatly reduce the number of calculations in idirpyr_eq_channel() - // but we need two additional buffers for this preprocessing - tmpHue = new float*[srcheight]; - - for (int i = 0; i < srcheight; i++) { - tmpHue[i] = new float[srcwidth]; - } - -#ifdef __SSE2__ -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < srcheight; i++) { - int j; - - for(j = 0; j < srcwidth - 3; j += 4) { - _mm_storeu_ps(&tmpHue[i][j], xatan2f(LVFU(l_b[i][j]), LVFU(l_a[i][j]))); - } - - for(; j < srcwidth; j++) { - tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); - } - } - -#else -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < srcheight; i++) { - for(int j = 0; j < srcwidth; j++) { - tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); - } - } - -#endif - tmpChr = new float*[srcheight]; - - for (int i = 0; i < srcheight; i++) { - tmpChr[i] = new float[srcwidth]; - } - -#ifdef __SSE2__ -#ifdef _OPENMP - #pragma omp parallel -#endif - { - __m128 div = _mm_set1_ps(327.68f); -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < srcheight; i++) { - int j; - - for(j = 0; j < srcwidth - 3; j += 4) { - _mm_storeu_ps(&tmpChr[i][j], vsqrtf(SQRV(LVFU(l_b[i][j])) + SQRV(LVFU(l_a[i][j]))) / div); - } - - for(; j < srcwidth; j++) { - tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; - } - } - } -#else -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < srcheight; i++) { - for(int j = 0; j < srcwidth; j++) { - tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; - } - } - -#endif - } - - // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory - float ** buffer = dirpyrlo[lastlevel - 1]; - - for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); - } - - scale = scales[0]; - - idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); - - if(skinprot != 0.f) { - for (int i = 0; i < srcheight; i++) { - delete [] tmpChr[i]; - } - - delete [] tmpChr; - - for (int i = 0; i < srcheight; i++) { - delete [] tmpHue[i]; - } - - delete [] tmpHue; - } - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = 0; i < srcheight; i++) - for (int j = 0; j < srcwidth; j++) { - dst[i][j] = /*CLIP*/(buffer[i][j]); // TODO: Really a clip necessary? - } +namespace { +float rangeFn(float i) { + return 1.f / (i + 1000.f); } - - -void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scaleprev) -{ - int lastlevel = maxlevel; - - if(settings->verbose) { - printf("CAM dirpyr scaleprev=%i\n", scaleprev); - } - - float atten123 = (float) settings->level123_cbdl; - - if(atten123 > 50.f) { - atten123 = 50.f; - } - - if(atten123 < 0.f) { - atten123 = 0.f; - } - -// printf("atten=%f\n",atten); - float atten0 = (float) settings->level0_cbdl; - - if(atten0 > 40.f) { - atten123 = 40.f; - } - - if(atten0 < 0.f) { - atten0 = 0.f; - } - - if((t_r - t_l) < 0.55f) { - t_l = t_r + 0.55f; //avoid too small range - } - - while (fabs(mult[lastlevel - 1] - 1) < 0.001 && lastlevel > 0) { - lastlevel--; - //printf("last level to process %d \n",lastlevel); - } - - if (lastlevel == 0) { - return; - } - - int level; - - float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[maxlevel]; - - for(int lv = 0; lv < maxlevel; lv++) { - scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; - - // if(scalefl[lv] < 1.f) multi[lv] = 1.f; else multi[lv]=(float) mult[lv]; - if (lv >= 1) { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten123 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; - } else { - multi[lv] = (float) mult[lv]; - } - } else { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten0 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; - } else { - multi[lv] = (float) mult[lv]; - } - } - - - } - - if(settings->verbose) { - printf("CAM CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4], multi[5]); - } - - - - - multi_array2D dirpyrlo (srcwidth, srcheight); - - level = 0; - - int scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale); - - level = 1; - - while(level < lastlevel) { - scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale); - - level ++; - } - - - // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory - float ** buffer = dirpyrlo[lastlevel - 1]; - - for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channelcam(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold , h_p, C_p, skinprot, b_l, t_l, t_r); - } - - idirpyr_eq_channelcam(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); - - - if(execdir) { -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int i = 0; i < srcheight; i++) - for (int j = 0; j < srcwidth; j++) { - if(ncie->J_p[i][j] > 8.f && ncie->J_p[i][j] < 92.f) { - dst[i][j] = /*CLIP*/( buffer[i][j] ); // TODO: Really a clip necessary? - } else { - dst[i][j] = src[i][j]; - } - } - } else { - for (int i = 0; i < srcheight; i++) - for (int j = 0; j < srcwidth; j++) { - dst[i][j] = /*CLIP*/( buffer[i][j] ); // TODO: Really a clip necessary? - } - } -} - -void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, int width, int height, int level, int scale) +void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int width, int height, int level, int scale) { // scale is spacing of directional averaging weights // calculate weights, compute directionally weighted average - if(level > 1) { + if (level > 1) { //generate domain kernel - int domker[5][5] = {{1, 1, 1, 1, 1}, {1, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {1, 1, 1, 1, 1}}; - // int domker[5][5] = {{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1}}; - static const int halfwin = 2; - const int scalewin = halfwin * scale; + // multiplied each value of domker by 1000 to avoid multiplication by 1000 inside the loop +#ifdef __SSE2__ + const float domkerv[5][5][4] ALIGNED16 = {{{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}}; +#endif + const float domker[5][5] = {{1000, 1000, 1000, 1000, 1000}, + {1000, 2000, 2000, 2000, 1000}, + {1000, 2000, 2000, 2000, 1000}, + {1000, 2000, 2000, 2000, 1000}, + {1000, 1000, 1000, 1000, 1000}}; + constexpr int halfwin = 2; #ifdef _OPENMP #pragma omp parallel #endif { + const int scalewin = halfwin * scale; #ifdef __SSE2__ - __m128 thousandv = _mm_set1_ps( 1000.0f ); - __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; -// multiplied each value of domkerv by 1000 to avoid multiplication by 1000 inside the loop - float domkerv[5][5][4] ALIGNED16 = {{{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}}; -#endif // __SSE2__ - - int j; -#ifdef _OPENMP - #pragma omp for //schedule (dynamic,8) + const vfloat thousandv = F2V(1000.f); #endif - for(int i = 0; i < height; i++) { - float dirwt; +#ifdef _OPENMP + #pragma omp for +#endif - for(j = 0; j < scalewin; j++) { + for (int i = 0; i < height; i++) { + int j; + for (j = 0; j < scalewin; j++) { float val = 0.f; float norm = 0.f; - - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { + for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { for (int jnbr = max(0, j - scalewin); jnbr <= j + scalewin; jnbr += scale) { - //printf("i=%d ",(inbr-i)/scale+halfwin); - dirwt = DIRWT(inbr, jnbr, i, j); + const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } @@ -433,174 +84,125 @@ void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, i #ifdef __SSE2__ - for(; j < width - scalewin - 3; j += 4) { - valv = _mm_setzero_ps(); - normv = _mm_setzero_ps(); - dftemp1v = LVFU(data_fine[i][j]); + for (; j < width - scalewin - 3; j += 4) { + vfloat valv = ZEROV; + vfloat normv = ZEROV; + const vfloat dftemp1v = LVFU(data_fine[i][j]); - for(int inbr = MAX(0, i - scalewin); inbr <= MIN(height - 1, i + scalewin); inbr += scale) { - int indexihlp = (inbr - i) / scale + halfwin; - - for (int jnbr = j - scalewin, indexjhlp = 0; jnbr <= j + scalewin; jnbr += scale, indexjhlp++) { - dftemp2v = LVFU(data_fine[inbr][jnbr]); - dirwtv = LVF(domkerv[indexihlp][indexjhlp]) / (vabsf(dftemp1v - dftemp2v) + thousandv); + for (int inbr = MAX(0, i - scalewin); inbr <= MIN(height - 1, i + scalewin); inbr += scale) { + const int indexihlp = (inbr - i) / scale + halfwin; + for (int jnbr = j - scalewin, indexjhlp = 0; jnbr <= j + scalewin; jnbr += scale, ++indexjhlp) { + const vfloat dftemp2v = LVFU(data_fine[inbr][jnbr]); + const vfloat dirwtv = LVF(domkerv[indexihlp][indexjhlp]) / (vabsf(dftemp1v - dftemp2v) + thousandv); valv += dirwtv * dftemp2v; normv += dirwtv; } } - - _mm_storeu_ps( &data_coarse[i][j], valv / normv); //low pass filter + STVFU(data_coarse[i][j], valv / normv); //low pass filter } - - for(; j < width - scalewin; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) { - dirwt = DIRWT(inbr, jnbr, i, j); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - -#else - - for(; j < width - scalewin; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) { - dirwt = DIRWT(inbr, jnbr, i, j); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - #endif - - for(; j < width; j++) { + for (; j < width - scalewin; j++) { float val = 0.f; float norm = 0.f; - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = j - scalewin; jnbr <= min(width - 1, j + scalewin); jnbr += scale) { - dirwt = DIRWT(inbr, jnbr, i, j); + for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { + for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) { + const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } } + data_coarse[i][j] = val / norm; //low pass filter + } + for (; j < width; j++) { + float val = 0.f; + float norm = 0.f; + + for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { + for (int jnbr = j - scalewin; jnbr <= min(width - 1, j + scalewin); jnbr += scale) { + const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + val += dirwt * data_fine[inbr][jnbr]; + norm += dirwt; + } + } data_coarse[i][j] = val / norm; //low pass filter } } } } else { // level <=1 means that all values of domker would be 1.0f, so no need for multiplication -// const int scalewin = scale; #ifdef _OPENMP #pragma omp parallel #endif { #ifdef __SSE2__ - __m128 thousandv = _mm_set1_ps( 1000.0f ); - __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; -#endif // __SSE2__ - int j; + const vfloat thousandv = F2V(1000.0f); +#endif #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) + for (int i = 0; i < height; i++) { - float dirwt; - - for(j = 0; j < scale; j++) { + int j = 0; + for (; j < scale; j++) { float val = 0.f; float norm = 0.f; - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { + for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { for (int jnbr = max(0, j - scale); jnbr <= j + scale; jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } } - data_coarse[i][j] = val / norm; //low pass filter } #ifdef __SSE2__ - for(; j < width - scale - 3; j += 4) { - valv = _mm_setzero_ps(); - normv = _mm_setzero_ps(); - dftemp1v = LVFU(data_fine[i][j]); + for (; j < width - scale - 3; j += 4) { + vfloat valv = ZEROV; + vfloat normv = ZEROV; + const vfloat dftemp1v = LVFU(data_fine[i][j]); - for(int inbr = MAX(0, i - scale); inbr <= MIN(height - 1, i + scale); inbr += scale) { + for (int inbr = MAX(0, i - scale); inbr <= MIN(height - 1, i + scale); inbr += scale) { for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { - dftemp2v = LVFU(data_fine[inbr][jnbr]); - dirwtv = thousandv / (vabsf(dftemp2v - dftemp1v) + thousandv); + const vfloat dftemp2v = LVFU(data_fine[inbr][jnbr]); + const vfloat dirwtv = thousandv / (vabsf(dftemp2v - dftemp1v) + thousandv); valv += dirwtv * dftemp2v; normv += dirwtv; } } - - _mm_storeu_ps( &data_coarse[i][j], valv / normv); //low pass filter + STVFU(data_coarse[i][j], valv / normv); //low pass filter } - - for(; j < width - scale; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - -#else - - for(; j < width - scale; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - #endif - for(; j < width; j++) { + for (; j < width - scale; j++) { float val = 0.f; float norm = 0.f; - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = j - scale; jnbr <= min(width - 1, j + scale); jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { + for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { + const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } } + data_coarse[i][j] = val / norm; //low pass filter + } + for (; j < width; j++) { + float val = 0.f; + float norm = 0.f; + + for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { + for (int jnbr = j - scale; jnbr <= min(width - 1, j + scale); jnbr += scale) { + const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + val += dirwt * data_fine[inbr][jnbr]; + norm += dirwt; + } + } data_coarse[i][j] = val / norm; //low pass filter } } @@ -608,218 +210,297 @@ void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, i } } -void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, float b_l, float t_l, float t_r) +void fillLut(LUTf &irangefn, int level, double dirpyrThreshold, float mult, float skinprot) { + + float multbis; + if (level == 4 && mult > 1.f) { + multbis = 1.f + 0.65f * (mult - 1.f); + } else if (level == 5 && mult > 1.f) { + multbis = 1.f + 0.45f * (mult - 1.f); + } else { + multbis = mult; //multbis to reduce artifacts for high values mult + } + + const float offs = skinprot == 0.f ? 0.f : -1.f; + constexpr float noise = 2000.f; + const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0)); + + for (int i = 0; i < 0x20000; i++) { + if (abs(i - 0x10000) > noisehi || multbis < 1.0) { + irangefn[i] = multbis + offs; + } else { + if (abs(i - 0x10000) < noiselo) { + irangefn[i] = 1.f + offs; + } else { + irangefn[i] = 1.f + offs + (multbis - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f); + } + } + } +} + +void idirpyr_eq_channel(const float * const * data_coarse, const float * const * data_fine, float ** buffer, int width, int height, int level, float mult, const double dirpyrThreshold, const float * const * hue, const float * const * chrom, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); - float offs; + LUTf irangefn(0x20000); + fillLut(irangefn, level, dirpyrThreshold, mult, skinprot); - if(skinprot == 0.f) { - offs = 0.f; - } else { - offs = -1.f; - } - - float multbis[maxlevel]; - - multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult - - if(level == 4 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.65f * (mult[level] - 1.f); - } - - if(level == 5 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.45f * (mult[level] - 1.f); - } - - LUTf irangefn (0x20000); - { - const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0)); - //printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot); - - for (int i = 0; i < 0x20000; i++) { - if (abs(i - 0x10000) > noisehi || multbis[level] < 1.0) { - irangefn[i] = multbis[level] + offs; - } else { - if (abs(i - 0x10000) < noiselo) { - irangefn[i] = 1.f + offs ; - } else { - irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f) ; - } - } - } - } - - if(skinprot == 0.f) + if (!skinprot) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; buffer[i][j] += irangefn[hipass + 0x10000] * hipass; } } - else if(skinprot > 0.f) + } else if (skinprot > 0.f) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { float scale = 1.f; - float hipass = (data_fine[i][j] - data_coarse[i][j]); - // These values are precalculated now - float modhue = hue[i][j]; - float modchro = chrom[i][j]; - Color::SkinSatCbdl ((data_fine[i][j]) / 327.68f, modhue, modchro, skinprot, scale, true, b_l, t_l, t_r); - buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ; + const float hipass = data_fine[i][j] - data_coarse[i][j]; + rtengine::Color::SkinSatCbdl(data_fine[i][j] / 327.68f, hue[i][j], chrom[i][j], skinprot, scale, true, b_l, t_l, t_r); + buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass; } } - else + } else { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { float scale = 1.f; - float hipass = (data_fine[i][j] - data_coarse[i][j]); - // These values are precalculated now - float modhue = hue[i][j]; - float modchro = chrom[i][j]; - Color::SkinSatCbdl ((data_fine[i][j]) / 327.68f, modhue, modchro, skinprotneg, scale, false, b_l, t_l, t_r); - float correct = irangefn[hipass + 0x10000]; + const float hipass = data_fine[i][j] - data_coarse[i][j]; + rtengine::Color::SkinSatCbdl(data_fine[i][j] / 327.68f, hue[i][j], chrom[i][j], skinprotneg, scale, false, b_l, t_l, t_r); + const float correct = irangefn[hipass + 0x10000]; if (scale == 1.f) {//image hard - buffer[i][j] += (1.f + (correct) * (factorHard)) * hipass ; + buffer[i][j] += (1.f + correct * factorHard) * hipass; } else { //image soft with scale < 1 ==> skin - buffer[i][j] += (1.f + (correct)) * hipass ; + buffer[i][j] += (1.f + correct) * hipass; } } } + } } - -void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r) +void idirpyr_eq_channelcam(const float * const * data_coarse, const float * const * data_fine, float ** buffer, int width, int height, int level, float mult, const double dirpyrThreshold, const float * const * h_p, const float * const * C_p, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; - const float factorHard = (1.f - skinprotneg / 100.f); + const float factorHard = 1.f - skinprotneg / 100.f; - float offs; + LUTf irangefn(0x20000); + fillLut(irangefn, level, dirpyrThreshold, mult, skinprot); - if(skinprot == 0.f) { - offs = 0.f; + if (!skinprot) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; + buffer[i][j] += irangefn[hipass + 0x10000] * hipass; + } + } + } else if (skinprot > 0.f) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; + float scale = 1.f; + rtengine::Color::SkinSatCbdlCam(data_fine[i][j] / 327.68f, h_p[i][j] , C_p[i][j], skinprot, scale, true, b_l, t_l, t_r); + buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass; + } + } } else { - offs = -1.f; - } - - float multbis[maxlevel]; - - multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult - - if(level == 4 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.65f * (mult[level] - 1.f); - } - - if(level == 5 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.45f * (mult[level] - 1.f); - } - - LUTf irangefn (0x20000); - { - const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0)); - - //printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot); - for (int i = 0; i < 0x20000; i++) { - if (abs(i - 0x10000) > noisehi || multbis[level] < 1.0) { - irangefn[i] = multbis[level] + offs; - } else { - if (abs(i - 0x10000) < noiselo) { - irangefn[i] = 1.f + offs ; - } else { - irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f) ; - } - } - } - } - - if(skinprot == 0.f) #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); - buffer[i][j] += irangefn[hipass + 0x10000] * hipass ; - } - } - else if(skinprot > 0.f) -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; float scale = 1.f; - Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j] , l_b_c[i][j], skinprot, scale, true, b_l, t_l, t_r); - buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ; - } - } - else -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); - float scale = 1.f; - float correct; - correct = irangefn[hipass + 0x10000]; - Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j] , skinprotneg, scale, false, b_l, t_l, t_r); + const float correct = irangefn[hipass + 0x10000]; + rtengine::Color::SkinSatCbdlCam(data_fine[i][j] / 327.68f, h_p[i][j], C_p[i][j], skinprotneg, scale, false, b_l, t_l, t_r); if (scale == 1.f) {//image hard - buffer[i][j] += (1.f + (correct) * factorHard) * hipass ; - + buffer[i][j] += (1.f + correct * factorHard) * hipass; } else { //image soft - buffer[i][j] += (1.f + (correct)) * hipass ; + buffer[i][j] += (1.f + correct) * hipass; } } } + } +} - // if(gamutlab) { - // ImProcFunctions::badpixcam (buffer[i][j], 6.0, 10, 2);//for bad pixels - // } +} - /* if(gamutlab) {//disabled - float Lprov1=(buffer[i][j])/327.68f; - float R,G,B; - #ifdef _DEBUG - bool neg=false; - bool more_rgb=false; - //gamut control : Lab values are in gamut - Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); - #else - //gamut control : Lab values are in gamut - Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f); - #endif - // Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f);//gamut control in Lab mode ..not in CIECAM - buffer[i][j]=Lprov1*327.68f; - float2 sincosval = xsincosf(modhue); - l_a_h[i][j]=327.68f*modchro*sincosval.y; - l_b_c[i][j]=327.68f*modchro*sincosval.x; +namespace rtengine +{ + +extern const Settings* settings; + +void ImProcFunctions::dirpyr_equalizer(const float * const * src, float ** dst, int srcwidth, int srcheight, const float * const * l_a, const float * const * l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) +{ + //sequence of scales + constexpr int maxlevel = 6; + constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; + const float atten123 = rtengine::LIM(settings->level123_cbdl, 0.f, 50.f); + const float atten0 = rtengine::LIM(settings->level0_cbdl, 0.f, 40.f); + + int lastlevel = maxlevel; + while (lastlevel > 0 && fabs(mult[lastlevel - 1] - 1) < 0.001) { + --lastlevel; + } + + if (lastlevel == 0) { + return; + } + + float multi[maxlevel]; + + for (int lv = 0; lv < maxlevel; ++lv) { + if (scales[lv] < scaleprev) { + const float factor = lv >= 1 ? atten123 : atten0; + multi[lv] = (factor * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% + } else { + multi[lv] = mult[lv]; + } + } + + multi_array2D dirpyrlo (srcwidth, srcheight); + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, std::max(scales[0] / scaleprev, 1)); + + for (int level = 1; level < lastlevel; ++level) { + dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, std::max(scales[level] / scaleprev, 1)); + } + + array2D tmpHue, tmpChr; + + if (skinprot) { + // precalculate hue and chroma, use SSE, if available + // by precalculating these values we can greatly reduce the number of calculations in idirpyr_eq_channel() + // but we need two additional buffers for this preprocessing + tmpHue(srcwidth, srcheight); + tmpChr(srcwidth, srcheight); + +#ifdef _OPENMP + #pragma omp parallel +#endif + { +#ifdef __SSE2__ + const vfloat div = F2V(327.68f); +#endif +#ifdef _OPENMP + #pragma omp for +#endif + + for (int i = 0; i < srcheight; i++) { + int j = 0; +#ifdef __SSE2__ + for (; j < srcwidth - 3; j += 4) { + const vfloat lav = LVFU(l_a[i][j]); + const vfloat lbv = LVFU(l_b[i][j]); + STVFU(tmpHue[i][j], xatan2f(lbv, lav)); + STVFU(tmpChr[i][j], vsqrtf(SQRV(lbv) + SQRV(lav)) / div); + } +#endif + for (; j < srcwidth; j++) { + tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); + tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; + } } - */ + } + } + + // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory + float** buffer = dirpyrlo[lastlevel - 1]; + + for (int level = lastlevel - 1; level > 0; --level) { + idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi[level], dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); + } + + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi[0], dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < srcheight; i++) { + for (int j = 0; j < srcwidth; j++) { + dst[i][j] = buffer[i][j]; + } + } } -// float hipass = (data_fine[i][j]-data_coarse[i][j]); -// buffer[i][j] += irangefn[hipass+0x10000] * hipass ; +void ImProcFunctions::dirpyr_equalizercam(const CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, const float * const * h_p, const float * const * C_p, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) +{ -#undef DIRWT_L -#undef DIRWT_AB + //sequence of scales + constexpr int maxlevel = 6; + constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; + const float atten123 = rtengine::LIM(settings->level123_cbdl, 0.f, 50.f); + const float atten0 = rtengine::LIM(settings->level0_cbdl, 0.f, 40.f); -#undef NRWT_L -#undef NRWT_AB + int lastlevel = maxlevel; + while (fabs(mult[lastlevel - 1] - 1) < 0.001 && lastlevel > 0) { + --lastlevel; + } + if (lastlevel == 0) { + return; + } + + float multi[maxlevel]; + + for (int lv = 0; lv < maxlevel; lv++) { + if (scales[lv] < scaleprev) { + const float factor = lv >= 1 ? atten123 : atten0; + multi[lv] = (factor * ((float) mult[lv] - 1.f) / 100.f) + 1.f; + } else { + multi[lv] = mult[lv]; + } + } + + multi_array2D dirpyrlo (srcwidth, srcheight); + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, std::max(scales[0] / scaleprev, 1)); + + for (int level = 1; level < lastlevel; ++level) { + dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, std::max(scales[level] / scaleprev, 1)); + } + + // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory + float ** buffer = dirpyrlo[lastlevel - 1]; + + for (int level = lastlevel - 1; level > 0; --level) { + idirpyr_eq_channelcam(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi[level], dirpyrThreshold , h_p, C_p, skinprot, b_l, t_l, t_r); + } + + idirpyr_eq_channelcam(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi[0], dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int i = 0; i < srcheight; i++) { + for (int j = 0; j < srcwidth; j++) { + if (ncie->J_p[i][j] > 8.f && ncie->J_p[i][j] < 92.f) { + dst[i][j] = buffer[i][j]; + } else { + dst[i][j] = src[i][j]; + } + } + } } +} diff --git a/rtengine/helpersse2.h b/rtengine/helpersse2.h index 74780cf48..e8c489b04 100644 --- a/rtengine/helpersse2.h +++ b/rtengine/helpersse2.h @@ -29,7 +29,7 @@ typedef __m128 vfloat; typedef __m128i vint2; // -#define LVF(x) _mm_load_ps((float*)&x) +#define LVF(x) _mm_load_ps((const float*)&x) #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_store_ps(&x,y) #define STVFU(x,y) _mm_storeu_ps(&x,y) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 85954abfa..1e6e3842b 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -1720,7 +1720,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw float t_l = static_cast (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f; lab->deleteLab(); - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM + dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM lab->reallocLab(); } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index cd1650f6e..1083da735 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -332,11 +332,8 @@ public: float MadRgb(const float * DataList, int datalen); // pyramid wavelet - void dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet - void dirpyr_equalizercam(CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet - void dirpyr_channel(float ** data_fine, float ** data_coarse, int width, int height, int level, int scale); - void idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); - void idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); + void dirpyr_equalizer(const float * const * src, float ** dst, int srcwidth, int srcheight, const float * const * l_a, const float * const * l_b, const double * mult, double dirpyrThreshold, double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet + void dirpyr_equalizercam(const CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, const float * const * h_p, const float * const * C_p, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet void defringe(LabImage* lab); void defringecam(CieImage* ncie); void badpixcam(CieImage* ncie, double rad, int thr, int mode, float chrom, bool hotbad); From 4fedfb2b264b9f3aa8f4e01d3ee724e988dd3601 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 6 Aug 2019 22:10:38 +0200 Subject: [PATCH 096/222] cppcheck: further fixes --- rtengine/dcrop.cc | 147 ++++++++++++++++++------------------- rtengine/diagonalcurves.cc | 43 +++++------ rtengine/histmatching.cc | 2 +- rtengine/iptransform.cc | 7 +- rtgui/cropwindow.cc | 4 +- rtgui/metadatapanel.cc | 3 +- rtgui/mydiagonalcurve.cc | 6 -- rtgui/myflatcurve.cc | 3 +- rtgui/paramsedited.cc | 13 ++-- rtgui/thumbnail.cc | 7 +- 10 files changed, 101 insertions(+), 134 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 6acbc0047..69af056bf 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -204,10 +204,8 @@ void Crop::update(int todo) } int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; - int kall = 2; - parent->ipf.Tile_calc(tilesize, overlap, kall, widIm, heiIm, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); - kall = 0; + parent->ipf.Tile_calc(tilesize, overlap, 2, widIm, heiIm, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); float *min_b = new float [9]; float *min_r = new float [9]; @@ -653,10 +651,9 @@ void Crop::update(int todo) if (todo & M_LINDENOISE) { if (skip == 1 && denoiseParams.enabled) { - int kall = 0; float nresi, highresi; - parent->ipf.RGB_denoise(kall, origCrop, origCrop, calclum, parent->denoiseInfoStore.ch_M, parent->denoiseInfoStore.max_r, parent->denoiseInfoStore.max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, nresi, highresi); + parent->ipf.RGB_denoise(0, origCrop, origCrop, calclum, parent->denoiseInfoStore.ch_M, parent->denoiseInfoStore.max_r, parent->denoiseInfoStore.max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, nresi, highresi); if (parent->adnListener) { parent->adnListener->noiseChanged(nresi, highresi); @@ -885,9 +882,6 @@ void Crop::update(int todo) if (skip == 1) { if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { parent->ipf.impulsedenoise(labnCrop); - } - - if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { parent->ipf.defringe(labnCrop); } @@ -900,7 +894,6 @@ void Crop::update(int todo) } // if (skip==1) { - WaveletParams WaveParams = params.wavelet; if (params.dirpyrequalizer.cbdlMethod == "aft") { if (((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) { @@ -909,81 +902,81 @@ void Crop::update(int todo) } } - int kall = 0; - int minwin = min(labnCrop->W, labnCrop->H); - int maxlevelcrop = 10; - - // if(cp.mul[9]!=0)maxlevelcrop=10; - // adap maximum level wavelet to size of crop - if (minwin * skip < 1024) { - maxlevelcrop = 9; //sampling wavelet 512 - } - - if (minwin * skip < 512) { - maxlevelcrop = 8; //sampling wavelet 256 - } - - if (minwin * skip < 256) { - maxlevelcrop = 7; //sampling 128 - } - - if (minwin * skip < 128) { - maxlevelcrop = 6; - } - - if (minwin < 64) { - maxlevelcrop = 5; - } - - int realtile; - - if (params.wavelet.Tilesmethod == "big") { - realtile = 22; - } else /*if (params.wavelet.Tilesmethod == "lit")*/ { - realtile = 12; - } - - int tilesize = 128 * realtile; - int overlap = (int) tilesize * 0.125f; - - int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; - - parent->ipf.Tile_calc(tilesize, overlap, kall, labnCrop->W, labnCrop->H, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); - //now we have tile dimensions, overlaps - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - int minsizetile = min(tilewidth, tileheight); - int maxlev2 = 10; - - if (minsizetile < 1024 && maxlevelcrop == 10) { - maxlev2 = 9; - } - - if (minsizetile < 512) { - maxlev2 = 8; - } - - if (minsizetile < 256) { - maxlev2 = 7; - } - - if (minsizetile < 128) { - maxlev2 = 6; - } - - int maxL = min(maxlev2, maxlevelcrop); - - if (parent->awavListener) { - parent->awavListener->wavChanged(float (maxL)); - } - if ((params.wavelet.enabled)) { + WaveletParams WaveParams = params.wavelet; + int kall = 0; + int minwin = min(labnCrop->W, labnCrop->H); + int maxlevelcrop = 10; + + // if(cp.mul[9]!=0)maxlevelcrop=10; + // adap maximum level wavelet to size of crop + if (minwin * skip < 1024) { + maxlevelcrop = 9; //sampling wavelet 512 + } + + if (minwin * skip < 512) { + maxlevelcrop = 8; //sampling wavelet 256 + } + + if (minwin * skip < 256) { + maxlevelcrop = 7; //sampling 128 + } + + if (minwin * skip < 128) { + maxlevelcrop = 6; + } + + if (minwin < 64) { + maxlevelcrop = 5; + } + + int realtile; + + if (params.wavelet.Tilesmethod == "big") { + realtile = 22; + } else /*if (params.wavelet.Tilesmethod == "lit")*/ { + realtile = 12; + } + + int tilesize = 128 * realtile; + int overlap = (int) tilesize * 0.125f; + + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + + parent->ipf.Tile_calc(tilesize, overlap, kall, labnCrop->W, labnCrop->H, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + //now we have tile dimensions, overlaps + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + int minsizetile = min(tilewidth, tileheight); + int maxlev2 = 10; + + if (minsizetile < 1024 && maxlevelcrop == 10) { + maxlev2 = 9; + } + + if (minsizetile < 512) { + maxlev2 = 8; + } + + if (minsizetile < 256) { + maxlev2 = 7; + } + + if (minsizetile < 128) { + maxlev2 = 6; + } + + int maxL = min(maxlev2, maxlevelcrop); + + if (parent->awavListener) { + parent->awavListener->wavChanged(float (maxL)); + } + WavCurve wavCLVCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; WavOpacityCurveWL waOpacityCurveWL; LUTf wavclCurve; - LUTu dummy; params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index b4c88fd68..dd85b87de 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -230,7 +230,6 @@ void DiagonalCurve::NURBS_set () poly_x.clear(); poly_y.clear(); unsigned int sc_xsize = j - 1; - j = 0; // adding the initial horizontal segment, if any if (x[0] > 0.) { @@ -314,18 +313,13 @@ inline void catmull_rom_spline(int n_points, double space = (t2-t1) / n_points; - double t; - int i; - double c, d, A1_x, A1_y, A2_x, A2_y, A3_x, A3_y; - double B1_x, B1_y, B2_x, B2_y, C_x, C_y; - res_x.push_back(p1_x); res_y.push_back(p1_y); // special case, a segment at 0 or 1 is computed exactly if (p1_y == p2_y && (p1_y == 0 || p1_y == 1)) { - for (i = 1; i < n_points-1; ++i) { - t = p1_x + space * i; + for (int i = 1; i < n_points-1; ++i) { + double t = p1_x + space * i; if (t >= p2_x) { break; } @@ -333,38 +327,38 @@ inline void catmull_rom_spline(int n_points, res_y.push_back(p1_y); } } else { - for (i = 1; i < n_points-1; ++i) { - t = t1 + space * i; + for (int i = 1; i < n_points-1; ++i) { + double t = t1 + space * i; - c = (t1 - t)/(t1 - t0); - d = (t - t0)/(t1 - t0); - A1_x = c * p0_x + d * p1_x; - A1_y = c * p0_y + d * p1_y; + double c = (t1 - t)/(t1 - t0); + double d = (t - t0)/(t1 - t0); + double A1_x = c * p0_x + d * p1_x; + double A1_y = c * p0_y + d * p1_y; c = (t2 - t)/(t2 - t1); d = (t - t1)/(t2 - t1); - A2_x = c * p1_x + d * p2_x; - A2_y = c * p1_y + d * p2_y; + double A2_x = c * p1_x + d * p2_x; + double A2_y = c * p1_y + d * p2_y; c = (t3 - t)/(t3 - t2); d = (t - t2)/(t3 - t2); - A3_x = c * p2_x + d * p3_x; - A3_y = c * p2_y + d * p3_y; + double A3_x = c * p2_x + d * p3_x; + double A3_y = c * p2_y + d * p3_y; c = (t2 - t)/(t2 - t0); d = (t - t0)/(t2 - t0); - B1_x = c * A1_x + d * A2_x; - B1_y = c * A1_y + d * A2_y; + double B1_x = c * A1_x + d * A2_x; + double B1_y = c * A1_y + d * A2_y; c = (t3 - t)/(t3 - t1); d = (t - t1)/(t3 - t1); - B2_x = c * A2_x + d * A3_x; - B2_y = c * A2_y + d * A3_y; + double B2_x = c * A2_x + d * A3_x; + double B2_y = c * A2_y + d * A3_y; c = (t2 - t)/(t2 - t1); d = (t - t1)/(t2 - t1); - C_x = c * B1_x + d * B2_x; - C_y = c * B1_y + d * B2_y; + double C_x = c * B1_x + d * B2_x; + double C_y = c * B1_y + d * B2_y; res_x.push_back(C_x); res_y.push_back(C_y); @@ -512,7 +506,6 @@ double DiagonalCurve::getVal (double t) const ++d; } return LIM01(*(poly_y.begin() + d)); - break; } case DCT_NURBS : { diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index e48f2017a..f9268ea5d 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -329,8 +329,8 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st int tw = target->getWidth(), th = target->getHeight(); float thumb_ratio = float(std::max(sw, sh)) / float(std::min(sw, sh)); float target_ratio = float(std::max(tw, th)) / float(std::min(tw, th)); - int cx = 0, cy = 0; if (std::abs(thumb_ratio - target_ratio) > 0.01) { + int cx = 0, cy = 0; if (thumb_ratio > target_ratio) { // crop the height int ch = th - (tw * float(sh) / float(sw)); diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index beca624a8..5b1e7c458 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -435,12 +435,7 @@ static void calcGradientParams (int oW, int oH, const GradientParams& gradient, if (gp.transpose) { gp.bright_top = !gp.bright_top; - } - - if (gp.transpose) { - int tmp = w; - w = h; - h = tmp; + std::swap(w, h); } gp.scale = 1.0 / pow (2, gradient_stops); diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index b29aa5eeb..5839a5edb 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -2198,8 +2198,6 @@ void CropWindow::updateHoveredPicker (rtengine::Coord *imgPos) } rtengine::Coord cropPos; - float r=0.f, g=0.f, b=0.f; - float rpreview=0.f, gpreview=0.f, bpreview=0.f; if (imgPos) { imageCoordToCropImage(imgPos->x, imgPos->y, cropPos.x, cropPos.y); hoveredPicker->setPosition (*imgPos); @@ -2215,6 +2213,8 @@ void CropWindow::updateHoveredPicker (rtengine::Coord *imgPos) MyMutex::MyLock lock(cropHandler.cimg); if (validity == LockableColorPicker::Validity::INSIDE) { + float r=0.f, g=0.f, b=0.f; + float rpreview=0.f, gpreview=0.f, bpreview=0.f; cropHandler.colorPick(cropPos, r, g, b, rpreview, gpreview, bpreview, hoveredPicker->getSize()); hoveredPicker->setRGB (r, g, b, rpreview, gpreview, bpreview); } diff --git a/rtgui/metadatapanel.cc b/rtgui/metadatapanel.cc index ee97a7dfe..fed7622ea 100644 --- a/rtgui/metadatapanel.cc +++ b/rtgui/metadatapanel.cc @@ -26,9 +26,8 @@ using namespace rtengine; using namespace rtengine::procparams; -MetaDataPanel::MetaDataPanel() +MetaDataPanel::MetaDataPanel() : EvMetaDataMode(ProcEventMapper::getInstance()->newEvent(M_VOID, "HISTORY_MSG_METADATA_MODE")) { - EvMetaDataMode = ProcEventMapper::getInstance()->newEvent(M_VOID, "HISTORY_MSG_METADATA_MODE"); Gtk::HBox *box = Gtk::manage(new Gtk::HBox()); box->pack_start(*Gtk::manage(new Gtk::Label(M("TP_METADATA_MODE") + ": ")), Gtk::PACK_SHRINK, 4); diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index a3e7b9375..8dc8aca56 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -637,13 +637,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) setDirty(true); draw (lit_point); new_type = CSArrow; - retval = true; } } - - if (buttonPressed) { - retval = true; - } } else { // if (edited_point > -1) if (event->button.button == 3) { // do we edit another point? @@ -679,7 +674,6 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) newBoundaries.at(1).minVal = 0.; newBoundaries.at(1).maxVal = 1.; - retval = true; editedPos.at(0) = curve.x.at(edited_point); editedPos.at(1) = curve.y.at(edited_point); coordinateAdjuster->switchAdjustedPoint(editedPos, newBoundaries); diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index 9796141d5..ebd0a9d0c 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -556,7 +556,7 @@ bool MyFlatCurve::getHandles(int n) if (!n) { // first point, the left handle is then computed with the last point's right handle prevX = curve.x.at(N - 1) - 1.0; - nextX = curve.x.at(n + 1); + nextX = curve.x.at(1); } else if (n == N - 1) { // last point, the right handle is then computed with the first point's left handle prevX = curve.x.at(n - 1); @@ -745,7 +745,6 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) newBoundaries.at(2).maxVal = 1.; newBoundaries.at(3).minVal = 0.; newBoundaries.at(3).maxVal = 1.; - retval = true; editedPos.at(0) = curve.x.at(edited_point); editedPos.at(1) = curve.y.at(edited_point); editedPos.at(2) = curve.leftTangent.at(edited_point); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 952b08161..cb3d4151c 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1112,20 +1112,17 @@ void ParamsEdited::initFrom(const std::vector& wavelet.exptoning = wavelet.exptoning && p.wavelet.exptoning == other.wavelet.exptoning; wavelet.expnoise = wavelet.expnoise && p.wavelet.expnoise == other.wavelet.expnoise; - for (int i = 0; i < 9; i++) { - wavelet.c[i] = wavelet.c[i] && p.wavelet.c[i] == other.wavelet.c[i]; - } - - for (int i = 0; i < 9; i++) { - wavelet.ch[i] = wavelet.ch[i] && p.wavelet.ch[i] == other.wavelet.ch[i]; + for (int level = 0; level < 9; ++level) { + wavelet.c[level] = wavelet.c[level] && p.wavelet.c[level] == other.wavelet.c[level]; + wavelet.ch[level] = wavelet.ch[level] && p.wavelet.ch[level] == other.wavelet.ch[level]; } dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled; dirpyrequalizer.gamutlab = dirpyrequalizer.gamutlab && p.dirpyrequalizer.gamutlab == other.dirpyrequalizer.gamutlab; dirpyrequalizer.cbdlMethod = dirpyrequalizer.cbdlMethod && p.dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod; - for (int i = 0; i < 6; i++) { - dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i]; + for (int level = 0; level < 6; ++level) { + dirpyrequalizer.mult[level] = dirpyrequalizer.mult[level] && p.dirpyrequalizer.mult[level] == other.dirpyrequalizer.mult[level]; } dirpyrequalizer.threshold = dirpyrequalizer.threshold && p.dirpyrequalizer.threshold == other.dirpyrequalizer.threshold; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index eedff3029..79291c423 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -232,8 +232,6 @@ const ProcParams& Thumbnail::getProcParamsU () rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool returnParams, bool force, bool flaggingMode) { - static int index = 0; // Will act as unique identifier during the session - // try to load the last saved parameters from the cache or from the paramfile file ProcParams* ldprof = nullptr; @@ -285,6 +283,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu imageMetaData = rtengine::FramesMetaData::fromFile (fname, nullptr, true); } + static int index = 0; // Will act as unique identifier during the session Glib::ustring tmpFileName( Glib::build_filename(options.cacheBaseDir, Glib::ustring::compose("CPB_temp_%1.txt", index++)) ); const rtexif::TagDirectory* exifDir = nullptr; @@ -1020,9 +1019,7 @@ int Thumbnail::getRank () const void Thumbnail::setRank (int rank) { - if (pparams->rank != rank) { - pparams->rank = rank; - } + pparams->rank = rank; pparamsValid = true; } From 4c99c9cf014e10f40b79ccb460cdbcebfc8d3b54 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 7 Aug 2019 15:32:52 +0200 Subject: [PATCH 097/222] cppcheck: further fixes --- rtengine/dcp.cc | 14 ------ rtengine/ex1simple.cc | 94 ---------------------------------------- rtengine/hilite_recon.cc | 25 +++++------ rtengine/ipresize.cc | 71 ++++++++++++++---------------- rtengine/rtetest.cc | 82 ----------------------------------- rtengine/tmo_fattal02.cc | 14 +++--- 6 files changed, 52 insertions(+), 248 deletions(-) delete mode 100644 rtengine/ex1simple.cc delete mode 100644 rtengine/rtetest.cc diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 56855b604..6c948717a 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -334,8 +334,6 @@ double xyCoordToTemperature(const std::array& white_xy) // Search for line pair coordinate is between. double last_dt = 0.0; - double last_dv = 0.0; - double last_du = 0.0; for (uint32_t index = 1; index <= 30; ++index) { // Convert slope to delta-u and delta-v, with length 1. @@ -371,23 +369,11 @@ double xyCoordToTemperature(const std::array& white_xy) // Interpolate the temperature. res = 1.0e6 / (temp_table[index - 1].r * f + temp_table[index].r * (1.0 - f)); - - // Find delta from black body point to test coordinate. - uu = u - (temp_table [index - 1].u * f + temp_table [index].u * (1.0 - f)); - vv = v - (temp_table [index - 1].v * f + temp_table [index].v * (1.0 - f)); - // Interpolate vectors along slope. - du = du * (1.0 - f) + last_du * f; - dv = dv * (1.0 - f) + last_dv * f; - len = sqrt (du * du + dv * dv); - du /= len; - dv /= len; break; } // Try next line pair. last_dt = dt; - last_du = du; - last_dv = dv; } return res; diff --git a/rtengine/ex1simple.cc b/rtengine/ex1simple.cc deleted file mode 100644 index ddaa89177..000000000 --- a/rtengine/ex1simple.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include "rtengine.h" -#include -//#include -#include - -class PListener : - public rtengine::ProgressListener -{ -public: - void setProgressStr(const Glib::ustring& str) - { - std::cout << str << std::endl; - } - void setProgress (double p) - { - std::cout << p << std::endl; - } - void setProgressState(bool inProcessing) - { - } - void error(const Glib::ustring& descr) - { - } -}; - -int main (int argc, char* argv[]) -{ - if (argc < 4) { - std::cout << "Usage: rtcmd " << std::endl; - exit(1); - } - - Glib::thread_init (); - - // create and fill settings - rtengine::Settings* s = rtengine::Settings::create (); - s->demosaicMethod = "hphd"; - s->colorCorrectionSteps = 2; - s->iccDirectory = ""; - s->colorimetricIntent = 1; - s->monitorProfile = ""; - // init rtengine - rtengine::init (s); - // the settings can be modified later through the "s" pointer without calling any api function - - // Create a listener object. Any class is appropriate that inherits from rtengine::ProgressListener - PListener pl; - - // Load the image given in the first command line parameter - rtengine::InitialImage* ii; - int errorCode; - ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); - - if (!ii) { - ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); - } - - if (!ii) { - std::cout << "Input file not supported." << std::endl; - exit(2); - } - - // create an instance of ProcParams structure that holds the image processing settings. You find the memory map in a separate file and the non-basic types like strings and vectors can be manipulated through helper functions - rtengine::procparams::ProcParams params; - params.load (argv[2]); - - /* First, simplest scenario. Develop image and save it in a file */ - // create a processing job with the loaded image and the current processing parameters - rtengine::ProcessingJob* job = ProcessingJob::create (i, params); - // process image. The error is given back in errorcode. - rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); - // save image to disk - res->saveToFile (argv[3]); - // through "res" you can access width/height and pixel data, too -} - diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index b0a7e6229..7134ac34f 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -970,8 +970,8 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue for (int c = 0; c < 3; ++c) { lab[i2][c] = 0; - for (int j = 0; j < 3; ++j) { - lab[i2][c] += trans[c][j] * cam[i2][j]; + for (int j2 = 0; j2 < 3; ++j2) { + lab[i2][c] += trans[c][j2] * cam[i2][j2]; } } @@ -996,8 +996,8 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue for (int c = 0; c < 3; ++c) { cam[0][c] = 0.f; - for (int j = 0; j < 3; ++j) { - cam[0][c] += itrans[c][j] * lab[0][j]; + for (int j2 = 0; j2 < 3; ++j2) { + cam[0][c] += itrans[c][j2] * lab[0][j2]; } } @@ -1081,12 +1081,11 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue //now correct clipped channels if (pixel[0] > max_f[0] && pixel[1] > max_f[1] && pixel[2] > max_f[2]) { //all channels clipped - const float Y = 0.299f * clipfix[0] + 0.587f * clipfix[1] + 0.114f * clipfix[2]; - const float factor = whitept / Y; - red[i + miny][j + minx] = clipfix[0] * factor; - green[i + miny][j + minx] = clipfix[1] * factor; - blue[i + miny][j + minx] = clipfix[2] * factor; + const float mult = whitept / (0.299f * clipfix[0] + 0.587f * clipfix[1] + 0.114f * clipfix[2]); + red[i + miny][j + minx] = clipfix[0] * mult; + green[i + miny][j + minx] = clipfix[1] * mult; + blue[i + miny][j + minx] = clipfix[2] * mult; } else {//some channels clipped const float notclipped[3] = { pixel[0] <= max_f[0] ? 1.f : 0.f, @@ -1113,11 +1112,11 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue Y = 0.299f * red[i + miny][j + minx] + 0.587f * green[i + miny][j + minx] + 0.114f * blue[i + miny][j + minx]; if (Y > whitept) { - const float factor = whitept / Y; + const float mult = whitept / Y; - red[i + miny][j + minx] *= factor; - green[i + miny][j + minx] *= factor; - blue[i + miny][j + minx] *= factor; + red[i + miny][j + minx] *= mult; + green[i + miny][j + minx] *= mult; + blue[i + miny][j + minx] *= mult; } } } diff --git a/rtengine/ipresize.cc b/rtengine/ipresize.cc index 823beb23e..2a66e68cb 100644 --- a/rtengine/ipresize.cc +++ b/rtengine/ipresize.cc @@ -186,8 +186,8 @@ void ImProcFunctions::Lanczos (const Imagefloat* src, Imagefloat* dst, float sca void ImProcFunctions::Lanczos (const LabImage* src, LabImage* dst, float scale) { const float delta = 1.0f / scale; - const float a = 3.0f; - const float sc = min (scale, 1.0f); + constexpr float a = 3.0f; + const float sc = min(scale, 1.0f); const int support = static_cast (2.0f * a / sc) + 1; // storage for precomputed parameters for horizontal interpolation @@ -268,66 +268,61 @@ void ImProcFunctions::Lanczos (const LabImage* src, LabImage* dst, float scale) } // Do vertical interpolation. Store results. + int j = 0; #ifdef __SSE2__ - int j; __m128 Lv, av, bv, wkv; for (j = 0; j < src->W - 3; j += 4) { - Lv = _mm_setzero_ps(); - av = _mm_setzero_ps(); - bv = _mm_setzero_ps(); + Lv = ZEROV; + av = ZEROV; + bv = ZEROV; for (int ii = ii0; ii < ii1; ii++) { int k = ii - ii0; - wkv = _mm_set1_ps (w[k]); - Lv += wkv * LVFU (src->L[ii][j]); - av += wkv * LVFU (src->a[ii][j]); - bv += wkv * LVFU (src->b[ii][j]); + wkv = F2V(w[k]); + Lv += wkv * LVFU(src->L[ii][j]); + av += wkv * LVFU(src->a[ii][j]); + bv += wkv * LVFU(src->b[ii][j]); } - STVF (lL[j], Lv); - STVF (la[j], av); - STVF (lb[j], bv); + STVF(lL[j], Lv); + STVF(la[j], av); + STVF(lb[j], bv); } - -#else - int j = 0; #endif - for (; j < src->W; j++) { - float L = 0.0f, a = 0.0f, b = 0.0f; + for (; j < src->W; ++j) { + float Ll = 0.0f, La = 0.0f, Lb = 0.0f; - for (int ii = ii0; ii < ii1; ii++) { + for (int ii = ii0; ii < ii1; ++ii) { int k = ii - ii0; - L += w[k] * src->L[ii][j]; - a += w[k] * src->a[ii][j]; - b += w[k] * src->b[ii][j]; + Ll += w[k] * src->L[ii][j]; + La += w[k] * src->a[ii][j]; + Lb += w[k] * src->b[ii][j]; } - lL[j] = L; - la[j] = a; - lb[j] = b; + lL[j] = Ll; + la[j] = La; + lb[j] = Lb; } // Do horizontal interpolation - for (int j = 0; j < dst->W; j++) { + for (int x = 0; x < dst->W; ++x) { + float * wh = wwh + support * x; + float Ll = 0.0f, La = 0.0f, Lb = 0.0f; - float * wh = wwh + support * j; + for (int jj = jj0[x]; jj < jj1[x]; ++jj) { + int k = jj - jj0[x]; - float L = 0.0f, a = 0.0f, b = 0.0f; - - for (int jj = jj0[j]; jj < jj1[j]; jj++) { - int k = jj - jj0[j]; - - L += wh[k] * lL[jj]; - a += wh[k] * la[jj]; - b += wh[k] * lb[jj]; + Ll += wh[k] * lL[jj]; + La += wh[k] * la[jj]; + Lb += wh[k] * lb[jj]; } - dst->L[i][j] = L; - dst->a[i][j] = a; - dst->b[i][j] = b; + dst->L[i][x] = Ll; + dst->a[i][x] = La; + dst->b[i][x] = Lb; } } } diff --git a/rtengine/rtetest.cc b/rtengine/rtetest.cc deleted file mode 100644 index bd81dbb0d..000000000 --- a/rtengine/rtetest.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include "rtengine.h" -#include -//#include -#include - -class PListener : - public rtengine::ProgressListener -{ -public: - void setProgressStr(const Glib::ustring& str) - { - std::cout << str << std::endl; - } - void setProgress(double p) - { - std::cout << p << std::endl; - } - void setProgressState(bool inProcessing) - { - } - void error(const Glib::ustring& descr) - { - } -}; - -int main (int argc, char* argv[]) -{ - if (argc < 4) { - std::cout << "Usage: rtcmd " << std::endl; - exit(1); - } - - rtengine::Settings s; - s.demosaicMethod = "hphd"; - s.colorCorrectionSteps = 2; - s.iccDirectory = ""; - s.colorimetricIntent = 1; - s.monitorProfile = ""; - - Glib::thread_init (); - rtengine::init (s, ""); - PListener pl; - - rtengine::InitialImage* ii; - int errorCode; - ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); - - if (!ii) { - ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); - } - - if (!ii) { - std::cout << "Input file not supported." << std::endl; - exit(2); - } - - rtengine::procparams::ProcParams params; - params.load (argv[2]); - - rtengine::ProcessingJob* job = ProcessingJob::create (ii, params); - rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); - res->saveToFile (argv[3]); -} - diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index 32755319e..76da1f03d 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -476,14 +476,14 @@ void tmo_fattal02 (size_t width, Array2Df* H = new Array2Df (width, height); float temp = 100.f / maxLum; - float eps = 1e-4f; #ifdef _OPENMP #pragma omp parallel if(multithread) #endif { + const float eps = 1e-4f; #ifdef __SSE2__ - vfloat epsv = F2V (eps); - vfloat tempv = F2V (temp); + const vfloat epsv = F2V(eps); + const vfloat tempv = F2V(temp); #endif #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -926,13 +926,13 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/* // a solution which has no positive values: U_new(x,y)=U(x,y)-max // (not really needed but good for numerics as we later take exp(U)) //DEBUG_STR << "solve_pde_fft: removing constant from solution" << std::endl; - float max = 0.f; + float maxVal = 0.f; #ifdef _OPENMP - #pragma omp parallel for reduction(max:max) if(multithread) + #pragma omp parallel for reduction(max:maxVal) if(multithread) #endif for (int i = 0; i < width * height; i++) { - max = std::max (max, (*U) (i)); + maxVal = std::max(maxVal, (*U)(i)); } #ifdef _OPENMP @@ -940,7 +940,7 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/* #endif for (int i = 0; i < width * height; i++) { - (*U) (i) -= max; + (*U) (i) -= maxVal; } } From cf1d7e5920368238b244f9bf4dc646cac826abb2 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 7 Aug 2019 16:53:44 +0200 Subject: [PATCH 098/222] Update profilestorecombobox.cc Do not use std::move on return --- rtgui/profilestorecombobox.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index 96bbc32fa..53756f342 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -334,7 +334,7 @@ Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (Glib::ustring name) const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; if (pse->label == name) { - return std::move(currRow); + return currRow; } } } From d765c06cf44ab8167e14c7cbc32a37c81662d366 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 8 Aug 2019 11:43:47 +0200 Subject: [PATCH 099/222] 2 bugs in colour toning, fixes #5403 --- rtengine/improcfun.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 1e6e3842b..8d6272a06 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -2255,7 +2255,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer bool hasColorToningLabGrid = params->colorToning.enabled && params->colorToning.method == "LabGrid"; // float satLimit = float(params->colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; // float satLimitOpacity = 1.f-(float(params->colorToning.saturatedOpacity)/100.f); - float strProtect = (float (params->colorToning.strength) / 100.f); + float strProtect = pow_F((float (params->colorToning.strength) / 100.f), 0.4f); /* // Debug output - Color LUTf points @@ -2793,7 +2793,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer const float krh = rh / (rh + gh + bh); const float kgh = gh / (rh + gh + bh); const float kbh = bh / (rh + gh + bh); - strProtect = pow_F(strProtect, 0.4f); constexpr int mode = 0; for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { @@ -2806,7 +2805,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer else if (params->colorToning.method == "Splitco") { constexpr float reducac = 0.3f; constexpr int mode = 0; - strProtect = pow_F(strProtect, 0.4f); for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { const float r = rtemp[ti * TS + tj]; @@ -3483,7 +3481,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer const float krh = rh / (rh + gh + bh); const float kgh = gh / (rh + gh + bh); const float kbh = bh / (rh + gh + bh); - strProtect = pow_F(strProtect, 0.4f); constexpr int mode = 1; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 5) From 82e329ca836c2372456bea98c4141b1db1f10e96 Mon Sep 17 00:00:00 2001 From: Roel Baars <6567747+Thanatomanic@users.noreply.github.com> Date: Thu, 8 Aug 2019 13:10:55 +0200 Subject: [PATCH 100/222] Fix SHM-color toning behavior in shadows. Fixes #5403 --- rtengine/improcfun.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 8d6272a06..23dc4b1ba 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -3785,11 +3785,12 @@ void ImProcFunctions::toningsmh(float r, float g, float b, float &ro, float &go, { const float corr = 20000.f * RedLow * kl * rlo; + if (RedLow > 0.f) { + r += corr; + } else { g -= corr; b -= corr; - } else { - r += corr; } // r = CLIP(r); @@ -3799,27 +3800,28 @@ void ImProcFunctions::toningsmh(float r, float g, float b, float &ro, float &go, { const float corr = 20000.f * GreenLow * kl * rlo; + if (GreenLow > 0.f) { + g += corr; + } else { r -= corr; b -= corr; - } else { - g += corr; } // r = CLIP(r); - // b = CLIP(b); // g = CLIP(g); + // b = CLIP(b); } { - const float corr = 20000.f * BlueLow * kl * rlob; + const float corr = 20000.f * BlueLow * kl * rlo; if (BlueLow > 0.f) { + b += corr; + } else { r -= corr; g -= corr; - } else { - b += corr; } // r = CLIP(r); From 4bf4b818c0f8d67ac8c68b7542b9dc9e01a1d0b2 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 8 Aug 2019 13:41:14 +0200 Subject: [PATCH 101/222] cppcheck fixes --- rtengine/ipdehaze.cc | 2 +- rtengine/iplab2rgb.cc | 17 ++---- rtengine/lcp.cc | 7 +-- rtengine/profilestore.cc | 6 +- rtengine/profilestore.h | 8 +-- rtgui/filebrowser.cc | 28 ++++----- rtgui/profilestorecombobox.cc | 110 ++++++++++++++-------------------- rtgui/profilestorecombobox.h | 30 +++++----- rtgui/thumbbrowserbase.cc | 24 ++++---- 9 files changed, 103 insertions(+), 129 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index c1092e335..42a5f92b3 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -228,12 +228,12 @@ void ImProcFunctions::dehaze(Imagefloat *img) array2D dark(W, H); int patchsize = max(int(5 / scale), 2); - int npatches = 0; float ambient[3]; array2D &t_tilde = dark; float max_t = 0.f; { + int npatches = 0; array2D R(W, H); array2D G(W, H); array2D B(W, H); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 8790f003c..8b5a2cb71 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -356,24 +356,19 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, { const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); - double dx = Color::D50x; - double dz = Color::D50z; - { - dx = dz = 1.0; - } const float toxyz[3][3] = { { - static_cast(wprof[0][0] / (dx * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x - static_cast(wprof[0][1] / (dx * (normalizeIn ? 65535.0 : 1.0))), - static_cast(wprof[0][2] / (dx * (normalizeIn ? 65535.0 : 1.0))) + static_cast(wprof[0][0] / ((normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x + static_cast(wprof[0][1] / ((normalizeIn ? 65535.0 : 1.0))), + static_cast(wprof[0][2] / ((normalizeIn ? 65535.0 : 1.0))) }, { static_cast(wprof[1][0] / (normalizeIn ? 65535.0 : 1.0)), static_cast(wprof[1][1] / (normalizeIn ? 65535.0 : 1.0)), static_cast(wprof[1][2] / (normalizeIn ? 65535.0 : 1.0)) }, { - static_cast(wprof[2][0] / (dz * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z - static_cast(wprof[2][1] / (dz * (normalizeIn ? 65535.0 : 1.0))), - static_cast(wprof[2][2] / (dz * (normalizeIn ? 65535.0 : 1.0))) + static_cast(wprof[2][0] / ((normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z + static_cast(wprof[2][1] / ((normalizeIn ? 65535.0 : 1.0))), + static_cast(wprof[2][2] / ((normalizeIn ? 65535.0 : 1.0))) } }; diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index 7156f17e2..cf025ddbe 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -234,8 +234,6 @@ rtengine::LCPProfile::LCPProfile(const Glib::ustring& fname) : pCurCommon(nullptr), aPersModel{} { - const int BufferSize = 8192; - char buf[BufferSize]; XML_Parser parser = XML_ParserCreate(nullptr); @@ -250,6 +248,8 @@ rtengine::LCPProfile::LCPProfile(const Glib::ustring& fname) : FILE* const pFile = g_fopen(fname.c_str (), "rb"); if (pFile) { + constexpr int BufferSize = 8192; + char buf[BufferSize]; bool done; do { @@ -362,9 +362,8 @@ void rtengine::LCPProfile::calcParams( const float focDist = aPersModel[pm]->focDist; const float focDistLog = std::log(focDist) + euler; - double meanErr = 0.0; - if (aPersModel[pm]->hasModeData(mode)) { + double meanErr = 0.0; double lowMeanErr = 0.0; double highMeanErr = 0.0; diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 82074053f..7c3e94da3 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -261,10 +261,10 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath return fileFound; } -int ProfileStore::findFolderId (const Glib::ustring &path) +int ProfileStore::findFolderId (const Glib::ustring &path) const { // initialization must have been done when calling this - for (std::vector::iterator i = folders.begin(); i != folders.end(); ++i) { + for (std::vector::const_iterator i = folders.begin(); i != folders.end(); ++i) { if (*i == path) { return i - folders.begin(); } @@ -454,7 +454,7 @@ const PartialProfile* ProfileStore::getDefaultPartialProfile (bool isRaw) return pProf; } -const Glib::ustring ProfileStore::getPathFromId (int folderId) +const Glib::ustring ProfileStore::getPathFromId (int folderId) const { // initialization must have been done when calling this return folders.at (folderId); diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index 5b4c94b20..d8c193935 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -185,7 +185,7 @@ public: bool init (bool loadAll = true); void parseProfiles (); - int findFolderId (const Glib::ustring &path); + int findFolderId (const Glib::ustring &path) const; const ProfileStoreEntry* findEntryFromFullPath (Glib::ustring path); const rtengine::procparams::PartialProfile* getProfile (Glib::ustring path); const rtengine::procparams::PartialProfile* getProfile (const ProfileStoreEntry* entry); @@ -193,13 +193,13 @@ public: void releaseFileList (); const rtengine::procparams::ProcParams* getDefaultProcParams (bool isRaw); const rtengine::procparams::PartialProfile* getDefaultPartialProfile (bool isRaw); - const Glib::ustring getPathFromId (int folderId); - const ProfileStoreEntry* getInternalDefaultPSE() + const Glib::ustring getPathFromId (int folderId) const; + const ProfileStoreEntry* getInternalDefaultPSE() const { return internalDefaultEntry; } - const ProfileStoreEntry* getInternalDynamicPSE() + const ProfileStoreEntry* getInternalDynamicPSE() const { return internalDynamicEntry; } diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 90a3cc68d..88220a688 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -840,10 +840,10 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) } for (size_t i = 0; i < mselected.size(); i++) { - rtengine::procparams::ProcParams pp = mselected[i]->thumbnail->getProcParams(); - pp.raw.dark_frame = fc.get_filename(); - pp.raw.df_autoselect = false; - mselected[i]->thumbnail->setProcParams(pp, nullptr, FILEBROWSER, false); + rtengine::procparams::ProcParams lpp = mselected[i]->thumbnail->getProcParams(); + lpp.raw.dark_frame = fc.get_filename(); + lpp.raw.df_autoselect = false; + mselected[i]->thumbnail->setProcParams(lpp, nullptr, FILEBROWSER, false); } if (bppcl) { @@ -916,10 +916,10 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) } for (size_t i = 0; i < mselected.size(); i++) { - rtengine::procparams::ProcParams pp = mselected[i]->thumbnail->getProcParams(); - pp.raw.ff_file = fc.get_filename(); - pp.raw.ff_AutoSelect = false; - mselected[i]->thumbnail->setProcParams(pp, nullptr, FILEBROWSER, false); + rtengine::procparams::ProcParams lpp = mselected[i]->thumbnail->getProcParams(); + lpp.raw.ff_file = fc.get_filename(); + lpp.raw.ff_AutoSelect = false; + mselected[i]->thumbnail->setProcParams(lpp, nullptr, FILEBROWSER, false); } if (bppcl) { @@ -1079,17 +1079,17 @@ void FileBrowser::partPasteProfile () bppcl->beginBatchPParamsChange(mselected.size()); } - for (unsigned int i = 0; i < mselected.size(); i++) { + for (auto entry : mselected) { // copying read only clipboard PartialProfile to a temporary one, initialized to the thumb's ProcParams - mselected[i]->thumbnail->createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file + entry->thumbnail->createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file const rtengine::procparams::PartialProfile& cbPartProf = clipboard.getPartialProfile(); - rtengine::procparams::PartialProfile pastedPartProf(&mselected[i]->thumbnail->getProcParams (), nullptr); + rtengine::procparams::PartialProfile pastedPartProf(&entry->thumbnail->getProcParams (), nullptr); // pushing the selected values of the clipboard PartialProfile to the temporary PartialProfile partialPasteDlg.applyPaste (pastedPartProf.pparams, pastedPartProf.pedited, cbPartProf.pparams, cbPartProf.pedited); // applying the temporary PartialProfile to the thumb's ProcParams - mselected[i]->thumbnail->setProcParams (*pastedPartProf.pparams, pastedPartProf.pedited, FILEBROWSER); + entry->thumbnail->setProcParams (*pastedPartProf.pparams, pastedPartProf.pedited, FILEBROWSER); pastedPartProf.deleteInstance(); } @@ -1502,8 +1502,8 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) const // true -> std::transform(FileName.begin(), FileName.end(), FileName.begin(), ::toupper); int iFilenameMatch = 0; - for (const auto& entry : filter.vFilterStrings) { - if (FileName.find(entry) != std::string::npos) { + for (const auto& filter : filter.vFilterStrings) { + if (FileName.find(filter) != std::string::npos) { ++iFilenameMatch; break; } diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index 53756f342..71371afaa 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -37,23 +37,22 @@ ProfileStoreComboBox::ProfileStoreComboBox () setPreferredWidth (50, 120); } -Glib::ustring ProfileStoreComboBox::getCurrentLabel() +Glib::ustring ProfileStoreComboBox::getCurrentLabel() const { - Glib::ustring currLabel; - Gtk::TreeModel::iterator currRow = get_active(); + const Gtk::TreeModel::const_iterator currRow = get_active(); if (currRow) { const ProfileStoreEntry *currEntry = (*currRow)[methodColumns.profileStoreEntry]; return currEntry->label; } - return currLabel; + return {}; } -const ProfileStoreEntry* ProfileStoreComboBox::getSelectedEntry() +const ProfileStoreEntry* ProfileStoreComboBox::getSelectedEntry() const { - Gtk::TreeModel::iterator currRow_ = get_active(); - Gtk::TreeModel::Row currRow = *currRow_; + const Gtk::TreeModel::const_iterator currRow_ = get_active(); + const Gtk::TreeModel::Row currRow = *currRow_; if (currRow) { return currRow[methodColumns.profileStoreEntry]; @@ -145,18 +144,16 @@ void ProfileStoreComboBox::updateProfileList () cellRenderer->property_ellipsize_set() = true; } -Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) const { - Gtk::TreeModel::Row row; - Gtk::TreeIter rowInSubLevel; - for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - row = *iter; + for (const auto iter : childs) { + const Gtk::TreeModel::Row row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse_ = row[methodColumns.profileStoreEntry]; if (pse_->type == PSET_FOLDER) { - rowInSubLevel = findRowFromEntry_ (iter->children(), pse); + const Gtk::TreeIter rowInSubLevel = findRowFromEntry_ (iter->children(), pse); if (rowInSubLevel) { // entry found @@ -171,30 +168,27 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children return childs.end(); } -Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *pse) +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *pse) const { Gtk::TreeModel::Children childs = refTreeModel->children(); if (pse) { - Gtk::TreeIter row = findRowFromEntry_ (childs, pse); - return row; + return findRowFromEntry_ (childs, pse); } return childs.end(); } -Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name) +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, const Glib::ustring &name) const { - Gtk::TreeModel::Row row; - Gtk::TreeIter rowInSubLevel; - for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - row = *iter; + for (const auto iter : childs) { + const Gtk::TreeModel::Row row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse = row[methodColumns.profileStoreEntry]; if (pse->type == PSET_FOLDER) { - rowInSubLevel = findRowFromFullPath_ (iter->children(), parentFolderId, name); + const Gtk::TreeIter rowInSubLevel = findRowFromFullPath_ (iter->children(), parentFolderId, name); if (rowInSubLevel) { // entry found @@ -209,88 +203,77 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Childr return childs.end(); } -Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (Glib::ustring path) +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (const Glib::ustring &path) const { - Gtk::TreeIter row; - ProfileStore *profileStore = ProfileStore::getInstance(); if (path.empty()) { - return row; + return {}; } + const ProfileStore *profileStore = ProfileStore::getInstance(); + if (path == DEFPROFILE_INTERNAL) { - row = findRowFromEntry (profileStore->getInternalDefaultPSE()); - return row; + return findRowFromEntry (profileStore->getInternalDefaultPSE()); } if (path == DEFPROFILE_DYNAMIC) { - row = findRowFromEntry (profileStore->getInternalDynamicPSE()); - return row; + return findRowFromEntry (profileStore->getInternalDynamicPSE()); } // removing the filename - Glib::ustring fName = Glib::path_get_basename (path); + const Glib::ustring fName = Glib::path_get_basename(path); if (!fName.empty()) { - path = path.substr (0, path.length() - fName.length()); - } else { - // path is malformed; - return row; + int parentFolderId = profileStore->findFolderId (Glib::path_get_dirname (path.substr (0, path.length() - fName.length()))); + // 1. find the path in the folder list + if (parentFolderId != -1) { + return findRowFromFullPath_ (refTreeModel->children(), parentFolderId, fName); + } } - path = Glib::path_get_dirname (path); - int parentFolderId = profileStore->findFolderId (path); - - // 1. find the path in the folder list - if (parentFolderId != -1) { - row = findRowFromFullPath_ (refTreeModel->children(), parentFolderId, fName); - } - - return row; + return {}; } /** @brief Get the absolute full path of the active row entry. * @return The absolute full path of the active row entry, or the "Internal" keyword, * or an empty string if the ComboBox is in an invalid state */ -Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() +Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() const { - Glib::ustring path; - Gtk::TreeModel::iterator currRowI = get_active(); - ProfileStore *profileStore = ProfileStore::getInstance(); + const Gtk::TreeModel::const_iterator currRowI = get_active(); if (!currRowI) { - return path; + return {}; } Gtk::TreeModel::Row currRow = *currRowI; if (currRow) { - const ProfileStoreEntry *currEntry = currRow[methodColumns.profileStoreEntry]; if (!currEntry) { - return path; + return {}; } + const ProfileStore *profileStore = ProfileStore::getInstance(); if (currEntry == profileStore->getInternalDefaultPSE()) { - return Glib::ustring (DEFPROFILE_INTERNAL); + return DEFPROFILE_INTERNAL; } if (currEntry == profileStore->getInternalDynamicPSE()) { - return Glib::ustring (DEFPROFILE_DYNAMIC); + return DEFPROFILE_DYNAMIC; } - path = Glib::build_filename (profileStore->getPathFromId (currEntry->parentFolderId), currEntry->label); + return Glib::build_filename (profileStore->getPathFromId (currEntry->parentFolderId), currEntry->label); } - return path; + return {}; } -bool ProfileStoreComboBox::setActiveRowFromFullPath (Glib::ustring path) +bool ProfileStoreComboBox::setActiveRowFromFullPath (const Glib::ustring &path) { if (!path.empty()) { - Gtk::TreeIter row = findRowFromFullPath (path); + const Gtk::TreeIter row = findRowFromFullPath (path); if (row) { set_active (row); @@ -304,7 +287,7 @@ bool ProfileStoreComboBox::setActiveRowFromFullPath (Glib::ustring path) bool ProfileStoreComboBox::setActiveRowFromEntry (const ProfileStoreEntry *pse) { if (pse) { - Gtk::TreeIter row = findRowFromEntry (pse); + const Gtk::TreeIter row = findRowFromEntry (pse); if (row) { set_active (row); @@ -321,16 +304,13 @@ bool ProfileStoreComboBox::setInternalEntry () } /** @brief Get the row from the first level of the tree that match the provided name */ -Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (Glib::ustring name) +Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (const Glib::ustring &name) const { - Gtk::TreeIter row; - Gtk::TreeModel::Children childs = refTreeModel->children(); + const Gtk::TreeModel::Children childs = refTreeModel->children(); if (!name.empty()) { - Gtk::TreeModel::Row currRow; - - for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - currRow = *iter; + for (const auto iter : childs) { + const Gtk::TreeModel::Row currRow = *iter; const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; if (pse->label == name) { diff --git a/rtgui/profilestorecombobox.h b/rtgui/profilestorecombobox.h index 9c31ad60a..3796e0471 100644 --- a/rtgui/profilestorecombobox.h +++ b/rtgui/profilestorecombobox.h @@ -24,7 +24,6 @@ #include #include "../rtengine/rtengine.h" -#include "../rtengine/noncopyable.h" #include "../rtengine/profilestore.h" #include "threadutils.h" @@ -35,7 +34,7 @@ /** * @brief subclass of Gtk::Label with extra fields for Combobox and Menu, to link with a ProfileStoreEntry */ -class ProfileStoreLabel : public Gtk::Label +class ProfileStoreLabel final : public Gtk::Label { public: @@ -44,7 +43,7 @@ public: #ifndef NDEBUG ProfileStoreLabel() : Gtk::Label ("*** error ***"), entry (nullptr) {} #else - ProfileStoreLabel() : Gtk::Label (""), entry (NULL) {} + ProfileStoreLabel() : Gtk::Label (""), entry (nullptr) {} #endif /** @brief Create a new ProfileStoreLabel @@ -55,11 +54,11 @@ public: ProfileStoreLabel (const ProfileStoreLabel &other); }; -class ProfileStoreComboBox : public MyComboBox +class ProfileStoreComboBox final : public MyComboBox { -protected: - class MethodColumns : public Gtk::TreeModel::ColumnRecord +private: + class MethodColumns final : public Gtk::TreeModel::ColumnRecord { public: Gtk::TreeModelColumn label; @@ -74,21 +73,22 @@ protected: Glib::RefPtr refTreeModel; MethodColumns methodColumns; void refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList); - Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse); - Gtk::TreeIter findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name); + Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) const; + Gtk::TreeIter findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, const Glib::ustring &name) const; + Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse) const; + Gtk::TreeIter findRowFromFullPath (const Glib::ustring &path) const; + public: ProfileStoreComboBox(); void updateProfileList(); - Glib::ustring getCurrentLabel(); - const ProfileStoreEntry* getSelectedEntry(); - Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse); - Gtk::TreeIter findRowFromFullPath (Glib::ustring path); - Glib::ustring getFullPathFromActiveRow (); - bool setActiveRowFromFullPath (Glib::ustring oldPath); + Glib::ustring getCurrentLabel() const; + const ProfileStoreEntry* getSelectedEntry() const; + Glib::ustring getFullPathFromActiveRow () const; + bool setActiveRowFromFullPath (const Glib::ustring &oldPath); bool setActiveRowFromEntry (const ProfileStoreEntry *pse); bool setInternalEntry (); - Gtk::TreeIter getRowFromLabel (Glib::ustring name); + Gtk::TreeIter getRowFromLabel (const Glib::ustring &name) const; Gtk::TreeIter addRow (const ProfileStoreEntry *profileStoreEntry); void deleteRow (const ProfileStoreEntry *profileStoreEntry); }; diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 16566ae21..caf7d7b97 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -225,21 +225,21 @@ void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* clicked) static void scrollToEntry (double& h, double& v, int iw, int ih, ThumbBrowserEntryBase* entry) { - const int hmin = entry->getX (); - const int hmax = hmin + entry->getEffectiveWidth () - iw; - const int vmin = entry->getY (); - const int vmax = vmin + entry->getEffectiveHeight () - ih; + const int hMin = entry->getX(); + const int hMax = hMin + entry->getEffectiveWidth() - iw; + const int vMin = entry->getY(); + const int vMax = vMin + entry->getEffectiveHeight() - ih; - if (hmin < 0) { - h += hmin; - } else if (hmax > 0) { - h += hmax; + if (hMin < 0) { + h += hMin; + } else if (hMax > 0) { + h += hMax; } - if(vmin < 0) { - v += vmin; - } else if (vmax > 0) { - v += vmax; + if (vMin < 0) { + v += vMin; + } else if (vMax > 0) { + v += vMax; } } From 8744f8f82693667a169d0d2112f460c98338dd67 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 8 Aug 2019 19:10:29 +0200 Subject: [PATCH 102/222] cppcheck: further fixes --- rtengine/colortemp.cc | 17 +++++++++-------- rtgui/gradient.cc | 4 +--- rtgui/guiutils.cc | 33 +++++++++++---------------------- rtgui/mydiagonalcurve.cc | 3 --- rtgui/placesbrowser.cc | 8 ++++---- rtgui/preferences.cc | 2 +- 6 files changed, 26 insertions(+), 41 deletions(-) diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index a7a769d93..a22caddb8 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -1088,11 +1088,11 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, //}; gmul /= green; //printf("rmul=%f gmul=%f bmul=%f\n",rmul, gmul, bmul); - double max = rtengine::max(rmul, gmul, bmul); + double maxRGB = rtengine::max(rmul, gmul, bmul); - rmul /= max; - gmul /= max; - bmul /= max; + rmul /= maxRGB; + gmul /= maxRGB; + bmul /= maxRGB; if(settings->CRI_color != 0) { //activate if CRi_color !=0 @@ -1104,7 +1104,6 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, // and calcul with : blackbody at equivalent temp of lamp // CRI_color-1 = display Lab values of color CRI_color -1 const double whiteD50[3] = {0.9646019585, 1.0, 0.8244507152}; //calculate with this tool : spect 5nm - double CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22; //for CIECAT02 double Xchk[50], Ychk[50], Zchk[50]; //50 : I think it's a good limit for number of color : for CRI and Palette double Xcam02[50], Ycam02[50], Zcam02[50]; @@ -1113,9 +1112,6 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, const double epsilon = 0.008856; //Lab double xr[50], yr[50], zr[50]; - double fx[50], fy[50], fz[50]; - double x, y, z; - double Ywb = 1.0; int illum; int numero_color = settings->CRI_color - 1; @@ -1223,6 +1219,9 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, } if (CRI_type) { + double x, y, z; + double Ywb = 1.0; + const double* spect_illum[] = { Daylight5300_spect, Cloudy6200_spect, Shade7600_spect, A2856_spect, FluoF1_spect, FluoF2_spect, FluoF3_spect, FluoF4_spect, FluoF5_spect, FluoF6_spect, FluoF7_spect, FluoF8_spect, FluoF9_spect, FluoF10_spect, FluoF11_spect, @@ -1281,6 +1280,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, //calculate Matrix CAM02 : better than Von Kries and Bradford==> for Lamp double adap = 1.0; + double CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22; //for CIECAT02 cieCAT02(Xwb, Ywb, Zwb, CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22, adap); //here new value of X,Y,Z for lamp with chromatic CAM02 adaptation @@ -1306,6 +1306,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, //now conversion to Lab // Lamp + double fx[50], fy[50], fz[50]; for(int i = 0; i < N_c; i++) { xr[i] = Xcam02Lamp[i] / whiteD50[0]; diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index d7b2cb7c2..3f13dfe4d 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -422,9 +422,7 @@ bool Gradient::button1Pressed(int modifierKey) double diagonal = sqrt(double(imW) * double(imW) + double(imH) * double(imH)); // trick to get the correct angle (clockwise/counter-clockwise) - int p = centerPos.y; - centerPos.y = currPos.y; - currPos.y = p; + std::swap(centerPos.y, currPos.y); draggedPoint = currPos - centerPos; // compute the projected value of the dragged point diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index eda07af03..ec0bf6588 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -952,38 +952,27 @@ bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) Gtk::Scrollbar *scroll = get_vscrollbar(); if (adjust && scroll) { - double upper = adjust->get_upper(); - double lower = adjust->get_lower(); + const double upperBound = adjust->get_upper(); + const double lowerBound = adjust->get_lower(); double value = adjust->get_value(); double step = adjust->get_step_increment(); double value2 = 0.; -// printf("MyScrolledwindow::on_scroll_event / delta_x=%.5f, delta_y=%.5f, direction=%d, type=%d, send_event=%d\n", -// event->delta_x, event->delta_y, (int)event->direction, (int)event->type, event->send_event); - if (event->direction == GDK_SCROLL_DOWN) { - value2 = value + step; - - if (value2 > upper) { - value2 = upper; - } + value2 = rtengine::min(value + step, upperBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_UP) { - value2 = value - step; - - if (value2 < lower) { - value2 = lower; - } + value2 = rtengine::max(value - step, lowerBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { if (abs(event->delta_y) > 0.1) { - value2 = rtengine::LIM(value + (event->delta_y > 0 ? step : -step), lower, upper); + value2 = rtengine::LIM(value + (event->delta_y > 0 ? step : -step), lowerBound, upperBound); } if (value2 != value) { scroll->set_value(value2); @@ -1032,8 +1021,8 @@ bool MyScrolledToolbar::on_scroll_event (GdkEventScroll* event) Gtk::Scrollbar *scroll = get_hscrollbar(); if (adjust && scroll) { - double upper = adjust->get_upper(); - double lower = adjust->get_lower(); + const double upperBound = adjust->get_upper(); + const double lowerBound = adjust->get_lower(); double value = adjust->get_value(); double step = adjust->get_step_increment() * 2; double value2 = 0.; @@ -1042,20 +1031,20 @@ bool MyScrolledToolbar::on_scroll_event (GdkEventScroll* event) // event->delta_x, event->delta_y, (int)event->direction, (int)event->type, event->send_event); if (event->direction == GDK_SCROLL_DOWN) { - value2 = rtengine::min(value + step, upper); + value2 = rtengine::min(value + step, upperBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_UP) { - value2 = rtengine::max(value - step, lower); + value2 = rtengine::max(value - step, lowerBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { if (event->delta_x) { // if the user use a pad, it can scroll horizontally - value2 = rtengine::LIM(value + (event->delta_x > 0 ? 30 : -30), lower, upper); + value2 = rtengine::LIM(value + (event->delta_x > 0 ? 30 : -30), lowerBound, upperBound); } else if (event->delta_y) { - value2 = rtengine::LIM(value + (event->delta_y > 0 ? 30 : -30), lower, upper); + value2 = rtengine::LIM(value + (event->delta_y > 0 ? 30 : -30), lowerBound, upperBound); } if (value2 != value) { scroll->set_value(value2); diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index 8dc8aca56..cb96c039f 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -685,12 +685,9 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) stopNumericalAdjustment(); } } - - retval = true; } } } - retval = true; } diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc index 9935064ee..6fb04ac53 100644 --- a/rtgui/placesbrowser.cc +++ b/rtgui/placesbrowser.cc @@ -230,15 +230,15 @@ void PlacesBrowser::refreshPlacesList () } for (size_t i = 0; i < options.favoriteDirs.size(); i++) { - Glib::RefPtr hfile = Gio::File::create_for_path (options.favoriteDirs[i]); + Glib::RefPtr fav = Gio::File::create_for_path (options.favoriteDirs[i]); - if (hfile && hfile->query_exists()) { + if (fav && fav->query_exists()) { try { - if (auto info = hfile->query_info ()) { + if (auto info = fav->query_info ()) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.icon] = info->get_icon (); - newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.root] = fav->get_parse_name (); newrow[placesColumns.type] = 5; newrow[placesColumns.rowSeparator] = false; } diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index b7d10c8de..16a58f334 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -56,6 +56,7 @@ Glib::RefPtr fontcss; Preferences::Preferences (RTWindow *rtwindow) : Gtk::Dialog (M ("MAIN_BUTTON_PREFERENCES"), *rtwindow, true) + , regex(Glib::Regex::create (THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS)) , splash (nullptr) , rprofiles (nullptr) , iprofiles (nullptr) @@ -63,7 +64,6 @@ Preferences::Preferences (RTWindow *rtwindow) , newFont (false) , newCPFont (false) { - regex = Glib::Regex::create (THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS); moptions.copyFrom (&options); From 9cbc49d8176c4855af847d49a78cf4007c4bd2a7 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 8 Aug 2019 20:33:57 +0200 Subject: [PATCH 103/222] make xtrans_demosaic.cc cppcheck-clean --- rtengine/xtrans_demosaic.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index cd925fc33..8e3f332ad 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -39,9 +39,9 @@ const float d65_white[3] = { 0.950456, 1, 1.088754 }; void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]) { static LUTf cbrt(0x14000); - static bool cbrtinit = false; if (!rgb) { + static bool cbrtinit = false; if(!cbrtinit) { #pragma omp parallel for for (int i = 0; i < 0x14000; i++) { @@ -291,8 +291,6 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, #endif { int progressCounter = 0; - int c; - float color[3][6]; float *buffer = (float *) malloc ((ts * ts * (ndir * 4 + 3) + 128) * sizeof(float)); float (*rgb)[ts][ts][3] = (float(*)[ts][ts][3]) buffer; @@ -521,6 +519,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, /* Interpolate red and blue values for solitary green pixels: */ int sgstartcol = (left - sgcol + 4) / 3 * 3 + sgcol; + float color[3][6]; for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) { for (int col = sgstartcol, h = fcol(row, col + 1); col < mcol - 2; col += 3, h ^= 2) { @@ -564,7 +563,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, } int coloffset = (RightShift[row % 3] == 1 ? 3 : 1); - c = (row - sgrow) % 3 ? ts : 1; + int c = ((row - sgrow) % 3) ? ts : 1; int h = 3 * (c ^ ts ^ 1); if(coloffset == 3) { @@ -629,13 +628,13 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, if (hex[d] + hex[d + 1]) { float g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; - for (c = 0; c < 4; c += 2) { + for (int c = 0; c < 4; c += 2) { rix[0][c] = CLIP((g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.33333333f); } } else { float g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; - for (c = 0; c < 4; c += 2) { + for (int c = 0; c < 4; c += 2) { rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.5f); } } @@ -656,10 +655,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, // (presumably coming from original AHD) and converts taking // camera matrix into account. We use this in RT. for (int d = 0; d < ndir; d++) { - float *l = &lab[0][0][0]; - float *a = &lab[1][0][0]; - float *b = &lab[2][0][0]; - cielab(&rgb[d][4][4], l, a, b, ts, mrow - 8, ts - 8, xyz_cam); + cielab(&rgb[d][4][4], &lab[0][0][0], &lab[1][0][0], &lab[2][0][0], ts, mrow - 8, ts - 8, xyz_cam); int f = dir[d & 3]; f = f == 1 ? 1 : f - 8; From 55a2aae381773a81e1655b5e6ab62f6090002ffc Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 8 Aug 2019 22:17:00 +0200 Subject: [PATCH 104/222] cppcheck: further fixes --- rtengine/ahd_demosaic_RT.cc | 16 ++++++---- rtengine/amaze_demosaic_RT.cc | 6 ++-- rtengine/cfa_linedn_RT.cc | 6 ++-- rtengine/curves.cc | 60 +++++++++++++++++------------------ rtengine/rcd_demosaic.cc | 4 +-- 5 files changed, 47 insertions(+), 45 deletions(-) diff --git a/rtengine/ahd_demosaic_RT.cc b/rtengine/ahd_demosaic_RT.cc index de331fd53..13cbd4d2a 100644 --- a/rtengine/ahd_demosaic_RT.cc +++ b/rtengine/ahd_demosaic_RT.cc @@ -40,7 +40,7 @@ void RawImageSource::ahd_demosaic() { BENCHFUN - constexpr int dir[4] = { -1, 1, -TS, TS }; + constexpr int dirs[4] = { -1, 1, -TS, TS }; float xyz_cam[3][3]; LUTf cbrt(65536); @@ -55,9 +55,10 @@ void RawImageSource::ahd_demosaic() constexpr float d65_white[3] = { 0.950456, 1, 1.088754 }; double progress = 0.0; + if (plistener) { plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_AHD"))); - plistener->setProgress (0.0); + plistener->setProgress (progress); } for (int i = 0; i < 65536; i++) { @@ -65,16 +66,17 @@ void RawImageSource::ahd_demosaic() cbrt[i] = r > 0.008856 ? std::cbrt(r) : 7.787 * r + 16 / 116.0; } - for (int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { for (unsigned int j = 0; j < 3; j++) { xyz_cam[i][j] = 0; for (int k = 0; k < 3; k++) { xyz_cam[i][j] += xyz_rgb[i][k] * imatrices.rgb_cam[k][j] / d65_white[i]; } } - + } border_interpolate2(W, H, 5, rawData, red, green, blue); + #ifdef _OPENMP #pragma omp parallel #endif @@ -153,9 +155,9 @@ void RawImageSource::ahd_demosaic() auto lix = &lab[d][tr][tc]; for (int i = 0; i < 4; i++) { - ldiff[d][i] = std::fabs(lix[0][0] - lix[dir[i]][0]); - abdiff[d][i] = SQR(lix[0][1] - lix[dir[i]][1]) - + SQR(lix[0][2] - lix[dir[i]][2]); + ldiff[d][i] = std::fabs(lix[0][0] - lix[dirs[i]][0]); + abdiff[d][i] = SQR(lix[0][1] - lix[dirs[i]][1]) + + SQR(lix[0][2] - lix[dirs[i]][2]); } } diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index ffb68dbdd..9db2caac5 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -49,11 +49,11 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c stop.reset(new StopWatch("amaze demosaic")); } - volatile double progress = 0.0; + double progress = 0.0; if (plistener) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_AMAZE"))); - plistener->setProgress (0.0); + plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_AMAZE"))); + plistener->setProgress(progress); } const int width = winw, height = winh; diff --git a/rtengine/cfa_linedn_RT.cc b/rtengine/cfa_linedn_RT.cc index b5d171034..a7b789caf 100644 --- a/rtengine/cfa_linedn_RT.cc +++ b/rtengine/cfa_linedn_RT.cc @@ -54,15 +54,15 @@ void RawImageSource::CLASS cfa_linedn(float noise, bool horizontal, bool vertica // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + double progress = 0.0; if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_LINEDENOISE"); - plistener->setProgress (0.0); + plistener->setProgressStr("PROGRESSBAR_LINEDENOISE"); + plistener->setProgress(progress); } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% float noisevar = SQR(3 * noise * 65535); // _noise_ (as a fraction of saturation) is input to the algorithm float noisevarm4 = 4.0f * noisevar; - volatile double progress = 0.0; float* RawDataTmp = (float*)malloc( width * height * sizeof(float)); #ifdef _OPENMP #pragma omp parallel diff --git a/rtengine/curves.cc b/rtengine/curves.cc index f03a43e60..ef2a5bf92 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -641,15 +641,15 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou } // gamma correction - float val = Color::gammatab_srgb1[0]; + float val0 = Color::gammatab_srgb1[0]; // apply brightness curve if (brightcurve) { - val = brightcurve->getVal(val); // TODO: getVal(double) is very slow! Optimize with a LUTf + val0 = brightcurve->getVal(val0); // TODO: getVal(double) is very slow! Optimize with a LUTf } // store result in a temporary array - dcurve[0] = LIM01(val); + dcurve[0] = LIM01(val0); for (int i = 1; i < 0x10000; i++) { @@ -1508,10 +1508,10 @@ void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], Color::gamutLchonly(h1, Lr, c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f); #endif L1 = Lr * 327.68f; - float a, b, X, Y, Z; + float La, Lb, X, Y, Z; // converting back to rgb - Color::Lch2Lab(c1, h1, a, b); - Color::Lab2XYZ(L1, a, b, X, Y, Z); + Color::Lch2Lab(c1, h1, La, Lb); + Color::Lab2XYZ(L1, La, Lb, X, Y, Z); lut1[i] = X; lut2[i] = Y; lut3[i] = Z; @@ -1822,12 +1822,12 @@ float PerceptualToneCurve::calculateToneCurveContrastValue() const { // look at midtone slope const float xd = 0.07; - const float tx[] = { 0.30, 0.35, 0.40, 0.45 }; // we only look in the midtone range + const float tx0[] = { 0.30, 0.35, 0.40, 0.45 }; // we only look in the midtone range - for (size_t i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { - float x0 = tx[i] - xd; + for (size_t i = 0; i < sizeof(tx0) / sizeof(tx0[0]); i++) { + float x0 = tx0[i] - xd; float y0 = CurveFactory::gamma2(lutToneCurve[CurveFactory::igamma2(x0) * 65535.f] / 65535.f) - k * x0; - float x1 = tx[i] + xd; + float x1 = tx0[i] + xd; float y1 = CurveFactory::gamma2(lutToneCurve[CurveFactory::igamma2(x1) * 65535.f] / 65535.f) - k * x1; float slope = 1.0 + (y1 - y0) / (x1 - x0); @@ -1967,15 +1967,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float saturated_scale_factor = 1.f; } else if (C < hilim) { // S-curve transition between low and high limit - float x = (C - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim + float cx = (C - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1.f - cx); } - saturated_scale_factor = (1.f - x) + saturated_scale_factor * x; + saturated_scale_factor = (1.f - cx) + saturated_scale_factor * cx; } else { // do nothing, high saturation color, keep scale factor } @@ -1995,15 +1995,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float // do nothing, keep scale factor } else if (nL < hilim) { // S-curve transition - float x = (nL - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim + float cx = (nL - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1 - cx); } - dark_scale_factor = dark_scale_factor * (1.0f - x) + x; + dark_scale_factor = dark_scale_factor * (1.0f - cx) + cx; } else { dark_scale_factor = 1.f; } @@ -2021,15 +2021,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float // do nothing, keep scale factor } else if (J < hilim) { // S-curve transition - float x = (J - lolim) / (hilim - lolim); + float cx = (J - lolim) / (hilim - lolim); - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1 - cx); } - dark_scale_factor = dark_scale_factor * (1.f - x) + x; + dark_scale_factor = dark_scale_factor * (1.f - cx) + cx; } else { dark_scale_factor = 1.f; } @@ -2089,15 +2089,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float keep = 1.f; } else if (sat_scale < hilim) { // S-curve transition - float x = (sat_scale - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim + float cx = (sat_scale - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1 - cx); } - keep = (1.f - x) + keep * x; + keep = (1.f - cx) + keep * cx; } else { // do nothing, very high increase, keep minimum amount } diff --git a/rtengine/rcd_demosaic.cc b/rtengine/rcd_demosaic.cc index 904daea71..95c5b4792 100644 --- a/rtengine/rcd_demosaic.cc +++ b/rtengine/rcd_demosaic.cc @@ -49,11 +49,11 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) stop.reset(new StopWatch("rcd demosaic")); } - volatile double progress = 0.0; + double progress = 0.0; if (plistener) { plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_RCD"))); - plistener->setProgress(0); + plistener->setProgress(progress); } constexpr int rcdBorder = 9; From 63abfb4d66061ff4c640238cad52d24c249bf6bd Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 9 Aug 2019 15:45:11 +0200 Subject: [PATCH 105/222] make StopWatch more robust --- rtengine/StopWatch.h | 33 +++++++++++---------------------- rtengine/mytime.h | 10 +++------- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/rtengine/StopWatch.h b/rtengine/StopWatch.h index 9e4400b94..5eb103da4 100644 --- a/rtengine/StopWatch.h +++ b/rtengine/StopWatch.h @@ -18,10 +18,10 @@ * * Author: reine */ +#pragma once -#ifndef STOPWATCH_H -#define STOPWATCH_H #include +#include #include "mytime.h" #ifdef BENCHMARK @@ -36,45 +36,34 @@ class StopWatch { public: - explicit StopWatch( const char* msg, bool microseconds = false ) : microseconds(microseconds) + explicit StopWatch(const char* msg, bool microSeconds = false) : message(msg), unit(microSeconds ? " us" : " ms"), divisor(microSeconds ? 1 : 1000) { - message = msg; start(); stopped = false; } ~StopWatch() { - if(!stopped) { + if (!stopped) { stop(); } } void start() { startTime.set(); - }; + } void stop() { stopTime.set(); - if(!microseconds) { - long elapsedTime = stopTime.etime(startTime) / 1000; - std::cout << message << " took " << elapsedTime << " ms" << std::endl; - } else { - long elapsedTime = stopTime.etime(startTime); - std::cout << message << " took " << elapsedTime << " us" << std::endl; - } + const long elapsedTime = stopTime.etime(startTime) / divisor; + std::cout << message << " took " << elapsedTime << unit << std::endl; stopped = true; } - void stop(const char *msg) - { - message = msg; - stop(); - }; + private: - bool microseconds; MyTime startTime; MyTime stopTime; - const char *message; + const std::string message; + const std::string unit; + const int divisor; bool stopped; }; - -#endif /* STOPWATCH_H */ diff --git a/rtengine/mytime.h b/rtengine/mytime.h index f73d563d2..a0ce15bc7 100644 --- a/rtengine/mytime.h +++ b/rtengine/mytime.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MYTIME_ -#define _MYTIME_ +#pragma once #ifdef WIN32 #include @@ -58,11 +57,11 @@ public: t.tv_sec = tv.tv_sec; t.tv_nsec = tv.tv_usec * 1000; #else - clock_gettime (CLOCK_REALTIME, &t); + clock_gettime(CLOCK_REALTIME, &t); #endif } - int etime (MyTime a) + int etime (const MyTime &a) const { #ifndef WIN32 return (t.tv_sec - a.t.tv_sec) * 1000000 + (t.tv_nsec - a.t.tv_nsec) / 1000; @@ -71,6 +70,3 @@ public: #endif } }; - - -#endif From 9293e8e69b9205ad5cc60daa0adbcdc732107945 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 9 Aug 2019 15:45:52 +0200 Subject: [PATCH 106/222] Fix some coverity issues --- rtengine/pipettebuffer.cc | 8 +++++--- rtgui/rgbcurves.cc | 2 +- rtgui/rtimage.cc | 2 -- rtgui/rtscalable.cc | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rtengine/pipettebuffer.cc b/rtengine/pipettebuffer.cc index 34a52a5c0..4ad8afad1 100644 --- a/rtengine/pipettebuffer.cc +++ b/rtengine/pipettebuffer.cc @@ -176,9 +176,11 @@ void PipetteBuffer::getPipetteData(int x, int y, const int squareSize) } } - dataProvider->setPipetteVal1(-1.f); - dataProvider->setPipetteVal2(-1.f); - dataProvider->setPipetteVal3(-1.f); + if (dataProvider) { + dataProvider->setPipetteVal1(-1.f); + dataProvider->setPipetteVal2(-1.f); + dataProvider->setPipetteVal3(-1.f); + } } } diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index 560ee7e57..81d997add 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -23,7 +23,7 @@ using namespace rtengine; using namespace rtengine::procparams; -RGBCurves::RGBCurves () : FoldableToolPanel(this, "rgbcurves", M("TP_RGBCURVES_LABEL"), false, true) +RGBCurves::RGBCurves () : FoldableToolPanel(this, "rgbcurves", M("TP_RGBCURVES_LABEL"), false, true), lastLumamode(false) { lumamode = Gtk::manage (new Gtk::CheckButton (M("TP_RGBCURVES_LUMAMODE"))); diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 593ac95df..3fdf743f5 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -39,8 +39,6 @@ RTImage::RTImage () {} RTImage::RTImage (RTImage &other) : surface(other.surface), pixbuf(other.pixbuf) { - dpiBack = other.dpiBack; - scaleBack = other.scaleBack; if (pixbuf) { set(pixbuf); } else if (surface) { diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index aaa10bd21..079ece8d2 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -220,7 +220,7 @@ Cairo::RefPtr RTScalable::loadImage(const Glib::ustring &fn GError **error = nullptr; RsvgHandle *handle = rsvg_handle_new_from_data((unsigned const char*)updatedSVG.c_str(), updatedSVG.length(), error); - if (handle == nullptr) { + if (error && !handle) { std::cerr << "ERROR: Can't use the provided data for \"" << fname << "\" to create a RsvgHandle:" << std::endl << Glib::ustring((*error)->message) << std::endl; Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); From 259a7f4e782fc10b8bcd2d79d510924b2ca3535f Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 12 Aug 2019 13:46:33 +0200 Subject: [PATCH 107/222] Fix a bug in xtrans 1-pass --- rtengine/xtrans_demosaic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index cd925fc33..bdffca527 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -704,7 +704,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, // which appears less good with specular highlights vfloat redv, greenv, bluev; vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[d][row][col], redv, greenv, bluev); - vfloat yv = zd2627v * redv + zd6780v * bluev + zd0593v * greenv; + vfloat yv = zd2627v * redv + zd6780v * greenv + zd0593v * bluev; STVFU(yuv[0][row - 4][col - 4], yv); STVFU(yuv[1][row - 4][col - 4], (bluev - yv) * zd56433v); STVFU(yuv[2][row - 4][col - 4], (redv - yv) * zd67815v); From 4afe2d8f2830d72009da7c9b7992f9da573b38de Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 14 Aug 2019 10:57:04 +0200 Subject: [PATCH 108/222] Added camconst_creator.ods Automatically create dcraw_matrix entry for camconst.json --- tools/camconst_creator.ods | Bin 0 -> 12371 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tools/camconst_creator.ods diff --git a/tools/camconst_creator.ods b/tools/camconst_creator.ods new file mode 100644 index 0000000000000000000000000000000000000000..954abe6ac4cca0e88b754053be164394cabdd30e GIT binary patch literal 12371 zcmdUVWmsIx(k>p{gS)$1aCi6MFbocZyN2Kz+}(l)3la!6xVyV+f(8qhobNeb_TFdj zbD#V3)~q$tYi8>0)wTMmuBx|H6`*0TAt2x(AXFn#l|$^_M6y6YK>RvizJjo~wg)i1khT_+Ck3FNx{io z+0{$c(@z5c0NC2vy12Ob`1tq*YX^nC4T&-ck2Q);G>uOIB&GvXv#ru{tuqVl@=8JZ zWuW3p=dv2tiaPh|M$g*M-VJTO!NI{%QBjGBiJ6(1WmO@Cg@qLr74`M?Z7Vm@zfBY9ynWqCJk?I2_8Bzx~$?*4i0-nYDii~OU@isQ@ro}QlJ z;o<4&>E-3+?d|R3WbHM2%BLoEU4>?IOP0yv%3?z?L9_Rkm6Njc* z`wTZ%ge9lCK1wIe(xuih3=&vTt@0&+LfdC>Fhs{Q?O|Y&xxn#>1JQ7@Td0gqDvTVu z2r}C<{>5{!+U;cO7+*BT=AZbib5&3Q@ z@u7G+54AB3qPMbH!R;{-4G9sYRfu3(GlSJWtJmY4D*>Fk$=IhyvibcoR*i5PWfKTR z^X@cN9Xxf2Z}(H*o`Tg~3Jb=HLn_p_1?7TW(j!k=2!9CH7--|vQO|u8**-6%r zK%sBipSd~YBd(|vn+h-r3#mxh;~uv61hPuF;Nw(NY37*NP;C**QAMVAVpM4>TU1ho z4_Qt3InX;Icz~1p$Qql5?3r!}`SQByZ9iX!o+MvprM=6a)t^6w?J2Ui6vof)6z#E1 z%l}>nu=b;6b4Kb}G zz8Yhca$0uQt%xknNNglgTqamZ@t8{j5jtorsBZWz4k$W$v)so1)kMQ_G%V-)Llnmy zQJU`arDj?Bqr3`O)QI zwVoVJqAvrIEb~$d^}{)wF|_tc`Qlc@o#2N_Oqtfi>%v2W=IPnxJ z(Z|Z77@Os4s*cyFKLf^5l(|*CWlpVR3;d(?pZ#Bxi4S1#MlrTW&9@<@4OpbCsbIbMM zlr%!nRGE#4qUz%3XlYuKvux%MW{prr!bq-_lSTRd$`RQ8R-U9I6QFo2oDjX+DfMA= zETW0weXcmrF*j%Q0i1DQB}iOVndM@eP&||GPd?AQRSrTd^*IhXW4&8CMmn**^VUTw zy|C;ySZA38dKX_a_j^Ed*xm=!AP84)J`PxWFp|{_1CC2IDsp$$;1QnphTRX_k7>GP z*fFVzOLL@dw?94WOT?ZPdbjppYJJG_Rs2u~aj&`#l?mH^0^KJ^yiP9|^a#+vt!^oo zqKCZ#)ou{IEr|qI;lHh4MxMgDo$3thO?~fT#36$!-q0wN?L;=a>M>0rM#vLsUM-Ej z&2BZWxxckSx5#Pufh-j$9W+)m3`;TpK@RTF6jvk#CR-AqkV2K}SIY(r?L&15lzlJ?U6%8@fP`q&#WIF|bEe^w( zGgawUwKBvGwMR4vbqjZ8Dd*H(>(J$+}^pkC|h?7{=bAW;E9)#GJ4hPBRrBC9_YfsKkZSV5tv^0C%JWX4#im&?o zbQHYE=JOESF=@BMb`vsZ&sAm*n6wboOWWhMp2cFhsLQChVNjJ@tyW5_7u#)icADz7 zX?o2H4;d@j`58;w5zda&8xyE+mwj~gYjgrjW$<8mdoMf)+Il}cFGCc z5NuoR#IfY*;-AEq`qDaT*QtX7ofGAPrdqm-!^onRm>sLk{958S42-|h8s;8i0$8}C z{fKV3(rwoJ?#WM+Inzs9J8~fy zd}U|w8i-&#N{A`XXp9LFzFOetvYB0Fdz;GWwNxp#nmMmo71M(H;N3MV3H_vt`}l<7 z81ts)dk>xv0BEzOO}yvX;(EknzO&JC9519qannnmmQ|2mamrG?6rnx8t#z0%0dD1A zs58fRuxCB+t{&4`H(Pj@`1;HIL`7CNpNfV1hUt{x9sLqdmr_@e@fbIJ$JKg5Q>|Bn zMV+_TXkPZ^kc=`;b2p2zmt8QwACOyIp#?>q_JUE>Clc@jQ7X5(^($;Go@~4pawfa2ng0f@9Zn z!xLqYEYK}HjHox7swYB@gJy2L0tYrloyCTA-UL4W0#dZ%-;epI8j+1yp6o8V!2q%+ z4;ZXn`s)!sY-YLSj4=u5Xp7x@<$>nDEx|VuxGdZ6PC^-%VGPY}KI`n7JR~c$A&l)A z4>fXUPV{u%N30-jL`vcj-!qb`q+iZN&KgO?ODqPLi0#zy_{H?WqiU-sh{4q;q9v@h zbM1)L)sE`R`qo$=L`zU6S#V~5o-m>vrn!Z;C+aQrB8+fZuJy2Iwf}rsk|1!j4}COm zyi?BK=bhSY!^B+LQk#$pE3R7I!W2H-W|2nu)X0Z@r6Ny?GJoK8H}j#l@>Ik;vl$Tj zc5XE=GI%qdHqNP`QdNYZxHK+Af#cOyA@gxZ*;g7X7y^}6ff+ZebbUFhqOoZ*X$7r2 z-DdSd>*XTLx$E8W3)OZ}L!ZMd#*mL~=o<1Kl&i=XAb$7bO|D&g8^=@%eK|}F(>yQp!M8r62UgUj^_Mr@ zO*9sH*xa2CUcC#pG&cIe$Iri>{nP{GHYQ!?sP0%55m**^el+v=^l;+qaRDy;D)MxH zDdLL~)>arCMr$1Ku=@mZSIK>{_PC%nctq|yJzUSO@-X`HrEY$ZdB@w+`ODXb6Y$;L z+2tyDyAb!Q(DN#9F7vkI=6z`t^alS*cCK%uv!U)8zy9;bdF|8ucstUz#2-TUKZf!DU$m=@JDy0#SEf<{atVGf*${-B zl(J;CxXHUe=b*oS`L__fG$cR{7S@(-&i~42T{u`>K_ELvQwN|O>p$!L%3c4e_mcU# znVCBO7cHW{(J}=9fOf!_&O!f8^Y8A{#nsf+&E@~SM@MInr8Cgw|DySKJvxFM-5h@n z^S_Mo?<`|s2Qqa9{mMo^FV$6h zEc33}`Z&t+b*IQ$Gm!Vx`vAjwOgMXH<{ZNHCxwNSjM>Z(ZLo$}jv4A+)lzh7Q3%64 z_Kc+{5xs`r>6bW)=nzWZduXGic#f8{(?ZFbv<@7s`xgOojSq9B91EFj$Vr|hNL`3K}gr9D_1e5 zFWQq|v;71;_NjUqw>BKiD8t|PPRer{;OD!QKH$)@Z`Y|tzxeNWjag932B8f?Ze@#E zu6;r^AFwx~nPe%^d;8o(an`k*k1YcD>eLIIg;xhm(3qt(-czOdBtPC&^5y!bNaiR* z>*1T@W0926D{3@3Nr^88(=UseyO$(WX=3_`T9G_~QwYFp7Vn|5AhUA7+n65LD;t}2 znS8qkBbUdRwqoaq>9rL+r=ArzUQ$TJ)b0VG91POlmg zI9ll{k%|b(!f&=m3GeHzN&lG&-_@kI0V_*2t9 zutKTKlEu21keq@!Rz(rUX&lEif&>;g!)|yMJTtfW^k)LQWbu=8)Pr3xNA}_cPW^Pf zIF}^RgTWl|?A$|@3AE;f6U>OKunho`C6!R0E0gBz4_?i;lFif(?g_qZ@8?1sDf>9h zcH|cO5t18~l6i_AWLeSK!Myl6iW%h|`3hV!AGq;V9R?0@K1nZOLgsVjMzHIk_}&94 zO~4Hfa9Rj>X>j!e=uDgC$6*p&xTsq6UEpcRv~JD#8AYVn?HPh{2UTO|6kBSNAvR`g z)MJRF5p|MRUp(QiF7>o^A=L#1dW(*!{e zUk7g>wawE~T~+NFZZMx#dnU`O-+S!{+;A(k&oX$^?^tmZ)j-s`Y;%Zz>Ur+;WEQzv zfvujaMfT4b|Soxp`f%k={wyyRr%b|C3^Zvoc6h&Yr6pwNo5!f?mHA|wk8lRV79_3nR;Q+TS#zH5+44-?fW|=B85rvW(Be26I`d&~@w_s`AD9KO5 zTf4?JAqy;xz12#VM}TrI?cV!=M1WsuzEP>H6~Rg6aZDtX?r-s4FJ>PxFPk%!xuDve!FTZq0B!Bv zpRu}ZC2$m2Gl5Eq&RQhz@0Q&=6&ht!C9PyWDyA)D zP=+fxn~WSSLcus;$`0e{thkN^N)8H>g)Qe;#N+d`=ZBuL5&pC16G2p0iTx!o?RQtG z&KgA|Nf`bCXo3r~kUEp5nX%UExN=62V&>)gBn}S7SJ5#W=1xY1=in^r8Hu5> zR}ZXe6qt&KD9-*1%3o0qe1~c)34AylGbU}8k_peuRz`QhfGoNrdo4NyTIjtvTK?mc z^n>-IcEW~~xCtbpzM6^iz43?C#jo`dWC_T{W&y$z5`+>|tj^Ol(k1gHZrPDL4i3(r zvmPu1Nj;*<9`Ky5;4vD}Fr=Vw8FY}lKZFT}u62sV7>#t+;);fgx|DkJvVI7+Cc~i8 z;lnkg7zuN~oGfhin)NP3nX9n8cSvd<>s|cjM)uAcVy;b%8Ksynv%-FA#`2wx!@oU23} zL3;C9sUIEgb6%c29j1=&=dK&2;eLH||Gs(opt62E^c|?J*&%NI(Tj^mgvjt`t)I{v z--wKW)>-MQlkvjZfau75+jFy;$@GTLNg_h2+u(p6_5A{o{)5|*&ymu7By;@f3g&N@ zU4?}$O{X>BG%Z)!R@Oq6n+kcRj&g1F9hbz8_R&=?(|$zoTsp=j#dQSH4y{i27INF8 zoYiBlC5CMtzxV3DWp+;(EwS+y{jOxa@6_~c6?P^KSn6r-d3t&hmRd(;Op$SJv7xT< zg*LkP+Z?L$5iUF5y#!r97w_)`s4BdICkg9v{D1%fu_yCFN&SmR`nyQ(U*r_f)$~^w z7n7(Gm&t|>K7YavKYJam1m8tbxg;-iTCSBT-!2uKZr;w#Q#YF6|Bw-2-IOVTMuhjg z_JtQfcRn72Y}BcnKg-kWgbA0|Tphx1-$U9qK1uVXW-a;N6Pw7Y%48x;tMaU3)vryPi7w1iW#L1 zyAWFeN}2LKcq(L6oK3vK5Ms=qpt7L$*rLV`Jd_{U-VKy;b>he84v#ev2enPd zqkA_v4haE~@xuN6^Cb916}q^3*#TXCO@mcE{g-GS+kd?VUDISCa4>0yE2eRwtEp)@ zkOptb!H3BzBB4dSKy)(oYCev4u$4a&i*_|D@8jS(QO;#HlH6jdPFs>LVK1U$eaoqm z!Ls;US;{PGmxu8)y|4hJyTw7r&N3w z_G?Hq=#0WjY{a7jQRZTqq`FUAhz6;9R{i~m3U(4WEd4c=ooPlKQL#z2gR ze;m6xonhL_w_LHX)eiB_hO7g3Lr<|hpnCoEGO`#jpRfR@Mc#8~#mn8wqC#J#m<-jr zklfO7oCEpP5xPe59)!OaKD)6g<_RyS%dR{vJOwib4YipUqj-loS~MM;VGI@OJmd+K z73^3+h=95XfgY zI6BfKMDK|ywW{4ovG4lj|M)>N@J8m0p#YTOW|R35#5$DCSzd#tCx@ z7rbhaFJ9y56Jv99OZfUzjw%z&b=P>-Gr@Ou{QV{7c;H$wpN1bFhBJmT8>=L=7SisJaR+u-VAz_#@K*;eW!Rq-*gq^O z&Tjzs@<|cf_*4&@%-w_XCsGRX1$x+LWZ)mygB~JUa@3f@wBP2e$(YXR))m%bZ&ury z!_F-p@y?%m)*i-p+5^PTMG$RCk|tgqNi|@*COH5#!8+8FX7&g@;|PiSqNP-9I5li5 zG8i;m!M$%W!|E+Os`i@Gs`rYthbX*w-Dqnh!Ea%y`Ra@enlCJy&*$IqY1JsBuVTS{ zXD$}>A*u^|;=qpnjuh3yiAtK!1qva)hXf-KCvt~Pv_ol6(@&`^hRa6}r9lqh$XryT z&S#;Lg+}wIbfXbnxH*+0J||Bd(5?1W0&E14wPNDvrRIf1&JRmVnZSe%dv>`LDpHZw zz5vdNaZW<~SMuRlA-N{GyK*9*9z3ARI!011z>K(JKA5g$ zeeu4O4Le78Jb81+fw-C7s`CRboWv4)i%FVifk89K>%^L{*#>VZw#`~Fu*oM2l$+di zD7I9hqNHDBWGEwg+>+$QIPOQk!{<5_F;xchrkk*J59Mpk*n3N_COC(t zbkx|OoYib+5A;b~wh&iGM<+E;$V&PG2cc?Un2v`xu7y}aol6+*!-{6bGr1o-sA%yX zTVG;F~9IF4dVM1IY$ z&m9u70B~P?c~Q!1jGf||qr{VYe?LlPnb!l0qID^8{f3~uX3JQSM%-$onVMq)Mk>ee z!CC}aYgKyhzM|ZZVoT>JZF^ z{{CDr1UR-J$_fkXOgGeGliSH1ste0{k%76^5u2#3R#bkJJF{Ia&AA@ika=oKG!Ru+ z)}_e>pr;;^wQ4+Mp$c)Lx5zpqm!nPhRCsT{Qlcs=j`WEp?P->PYFm$VZdE3~|i-*31e)sm_CWxj@6 zt0~x**dX}7#sm129IlfF-Gx|_-sd2@~i#*Xbh z@1l`t43ifXzJ$LYkVOaqi~`%{!mmL>raSeyVz#tBhMYs-^vf;J?4SpZQch)Y(SK`}Pt%rJDkNyxm_FcRNcpr{5>z|_ux z6y%VaY&^zN^S&yV3BE*ycS&)m)_|_p>5-+wv;RkfDpRt2$n1f8dH(^73fk+&oF{c` zz)4%4d6!;#GMmIaE7I}#(xUVrZV7wC&>ZUWsZKR7)Ew!)u6X>yp4}y%+Nrb##jp$V zcaI9|hq-p6ZId8FD4JI@mibM@NyDlrW()XqXQ-le^x^rLA3HHx~!Tx9~AX^KNt>BI{^7RVuM*sXo%p9^438_cDDe*m( zOG(t@>Vy&){~6n_y*CGPU<(qaQp$jB4G5(GepU+=^on^*BX^E+dK@W}>_tULxg7~J zyd1|93EJ$WzPS)zpY*rQV*(v0Jh^o83PtSKihoAWE=k+pK)NUJtpN2I*&^8%wEa8^~p$9fcI+6k6tq1O(i*tnbg>Qh z7IlV?vO*neeYh62eIFsXBBt*PsjL))aVkBNh_R%RU_oBSBSGYK1T~|J?ugIX29xmiR*{JieZM5aMs2ljhbta*lh$Mp90sHTvWYWiB!Gb z%#7#ZdC^-!KlR4!&!wnJmuuM1r-cp~oC0@Ovzf$6wX=2yaZN2{ljTbfK7N8WsZ2c) zeTCzj+jUEqP?&d0mT!^dZC2C*cwM=eqzp^>Z_65ei7?x7T=$F;(a+x+&%E0jL3*4( zsl+cBt6yirOudo6ZRG1{;|90m`@6+}SCEqY^l^@FmRl2^PI!m`g3$^#f+W2CD%+EM zzFcs{sh3ZIzQniJ&C=yU6>I6VmN0I%d%VZSaHDX<0@>*Ay0mK6Ijd5z7)OS~N^f0w z@zN|B?QgEsEmc9t(yhD5M^SyXYDZUY6;6aY$3M#$`U>Cnb2D9h<35QE?$1oLnpZPc zFYlsJ-B=J<9uaJZTsBz&cc5K8Gzzs7`-B~EiHq_YPzwf1(J73VpL0is?6sS1g~FZd@$#h{1Q%~~8G`!WKQ^xt={q7241{oET1RYt;`N51)*+A=q8NGl>=<~X7uZ72%q1(H(%KlKl zZywr^O-A}B1UG&^%0(6(+Lo>mtAZq*^)z=$N|u{U-xORiEK;dm$5S;Pznz62gDfDHACdz_+l!51OP8LOx5k-N2Ddi! z4-~E3&8i?=%{g#542mQNt^;f+=#<;&C+20aC`RBCYubO}Kynoj0p!#z}{8!CCdXHb8`L~!c d{DYrXRe*iTV;~?fUS7Z#r?c>~4IKjF{{ZWg)nfnv literal 0 HcmV?d00001 From 6d777ce94b7066175dc4547b278a0785938cb7ec Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 14 Aug 2019 11:36:44 +0200 Subject: [PATCH 109/222] Improved Panasonic DC-GF10 raw support, closes #5411 --- rtengine/camconst.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 9d96975c8..2fc064ffa 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1759,6 +1759,15 @@ Camera constants: } }, + { // Quality C, only color matrix + "make_model" : "Panasonic DC-GF10", + "dcraw_matrix": [ 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 ], // ColorMatrix2 from Adobe DNG Converter 11.3 + "raw_crop": [ 0, 0, 4600, 0 ], // SensorWidth=4816 SensorHeight=3464. Width=4600 to match DNG. + "ranges": { + "black": 15 + } + }, + { // Quality B, CameraPhone, some samples are missing but has the same sensor as FZ1000 .. "make_model": [ "Panasonic DMC-CM1", "Panasonic DMC-CM10" ], "dcraw_matrix": [ 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 ], // dcp_v8.7 d65 From 4fdcaada1c9dedfcadb87d03a80c7f2973164d55 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 14 Aug 2019 12:01:17 +0200 Subject: [PATCH 110/222] Formatting and whitespace fixes in camconst.json --- rtengine/camconst.json | 93 ++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 2fc064ffa..4dbfe80f9 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -48,7 +48,7 @@ Examples: // For new models that are still not supported by the dcraw version used in current RT, we have to fill all the // alternate names or else RT will not recognize the alternate model names. // For models supported by dcraw, filling the alternate names is simply desired (for better user info). - // The format of multiple naming is to write all names in brackets i.e instead of + // The format of multiple naming is to write all names in brackets i.e instead of // "make_model": "Canon EOS 550D", // type // "make_model": [ "Canon EOS 550D", "Canon EOS Rebel T2i", "Canon EOS Kiss X4" ], @@ -115,9 +115,9 @@ How to Measure White Levels: dcraw provides the default values used by RawTherapee, but often provides too high white levels, and only provides a single value regardless of color channel, ISO or aperture. If you open an image with a large clipped area and that is rendered in a pink/magenta color rather than white it usually means that the white level constant is too high. You can - fix this by adjusting the"Raw White Point" in the raw tab inside RawTherapee, or permanently fix it by measuring and + fix this by adjusting white-point correction in the Raw tab > Raw White Points, or permanently fix it by measuring and providing a more exact white level in camconst.json so RawTherapee gets to know from start where the camera actually - clips. Providing a complete and detailed white-level profile can be a quite large and complicated effort. As an + clips. Providing a complete and detailed white-level profile can be a quite large and complicated effort. As an alternative you can provide a simpler profile.We suggest one of the following alternatives in rising difficulty (and generally diminishing return): A) Provide a single white-level value measured on the native ISO (base ISO). For many cameras this will actually be @@ -159,7 +159,7 @@ How to Measure White Levels: histogram. While it's common to with very little variation, say only +/-2 units, some can have +/-500 or more (some may have different variation depending on ISO). There can also be camera-to-camera variation. - If the white level is set too high RawTherapee will not think the pixels are clipped and you can get discoloured + If the white level is set too high RawTherapee will not think the pixels are clipped and you can get discolored highlights (usually pink), this is what we want to avoid. If white level is set too low RawTherapee will clip early, ie you lose a little highlight detail, but the color is rendered correctly and highlight reconstruction can work properly, so this is not as bad. This is why we want conservative values. @@ -167,21 +167,21 @@ How to Measure White Levels: By conservative values we mean that if you see a white level of most often 15760 and occasionally 15759 (i.e. very small variation of white level which is a common case), you set the white level around 50-100 14-bit units below or 10-20 12-bit units. Say at 15700 in this example, or 4080 instead of 4095 for 12-bit raws. This way we get a little margin - from noise and camera variation. Since sensor raw values are linear, you lose, for example, + from noise and camera variation. Since sensor raw values are linear, you lose, for example, log2(1-50/15760) = -0.005 stops of detail, i.e. irrelevant. Thus it is better to provide RawTherapee with knowledge where the image clips rather than keeping that last 0.005 stop of highlight information and risking that clipping will not be detected properly. It is very usual for white level to be a bell distribution instead of a candle when the camera applies long exposure noise reduction (LENR) by subtracting a black frame and/or when the system is destabilized due to temperature. Some models have - always a bell distribution at WL. If you have a fuzzy white level look at the linear histogram; you will probably see a + always a bell distribution at WL. If you have a fuzzy white level look at the linear histogram; you will probably see a normal/Gaussian distribution (bell shape) noise peak at clipping and probably also a peak at a hard raw data clip level usually at or close to a power of two - 1, such as 4095 or 16383. Then you pick a value just before the bell shape rises, i.e. to the left of the bell meaning that you cut away the whole fuzzy noise peak. If a little of the starting edge - of the noise will be included it's not harmful, but 99% of it should be above. This would mean that it's better to + of the noise will be included it's not harmful, but 99% of it should be above. This would mean that it's better to measure white level on long exposure/high temp raws but since this if difficult and time consuming we choose to measure - on normal raws and cover the abnormalities with the conservative WL values. A more detailed approach when we only have - non-LENR measures is to subtract a value according to per ISO read noise. We can find data regarding read noise (stdev + on normal raws and cover the abnormalities with the conservative WL values. A more detailed approach when we only have + non-LENR measures is to subtract a value according to per ISO read noise. We can find data regarding read noise (stdev of Gaussian distribution) at http://www.photonstophotos.net/Charts/RN_ADU.htm . We find the per ISO tead_noise and subtract from the measured value 6*read_noise. This gives confidence that 99.5% of the bell is clipped out. @@ -201,7 +201,7 @@ How to Measure White Levels: need a margin on white_max as it clips there as a result of an in-camera math operation. Note that aperture scaling can be quite small, for the 5D mark II it's only 0.2 stop down to f/1.2 and then it can be - discussed if it's worthwhile to care. The "worst" cameras scale about 0.6 stops though, and then it's more valuable to + discussed if it's worthwhile to care. The "worst" cameras scale about 0.6 stops though, and then it's more valuable to compensate. If you skip aperture scaling RawTherapee will clip the files a little bit too early and you miss that last fraction of highlight detail, but you get no processing problems. Setting un-conservative scale factors can on the other hand cause a too high white level and break highlight processing, so be careful. @@ -209,7 +209,7 @@ How to Measure White Levels: Scaling can vary slightly depending on ISO (if white levels vary) so make sure to provide conservative scalings so regardless of ISO you don't get a too high white level. We recommend to keep a small margin here also white levels, i.e. 0.5% lower or so. For example if base (not conservative!) white level is 15750 and the scaled is 16221 we have a - scaling factor of 16221/15750=1.0299 i.e. +2.9% we set the factor to 1.025 to keep a margin. The abnormal cases are + scaling factor of 16221/15750=1.0299 i.e. +2.9% we set the factor to 1.025 to keep a margin. The abnormal cases are already covered by setting conservative per ISO White levels. The scale factor you provide here is applied on the white level before black level subtraction (if any), i.e. directly on @@ -239,10 +239,10 @@ How to Measure White Levels: You can use RawTherapee for analysis too, it's safer as you are using it's own raw decoder but it's not as user-friendly: enable verbose mode in options so you get output on the console. When you load a file you will see a - message of current black and white levels and if they came from dcraw or camconst.json. If you're adjusting an existing + message of current black and white levels and if they came from dcraw or camconst.json. If you're adjusting an existing camconst.json value you can just read what it is in the file and not need to enable verbose output. - Reset exposure sliders to neutral, and zoom in on a large clipped highlight. Move around the mouse pointer within, it + Reset exposure sliders to neutral, and zoom in on a large clipped highlight. Move around the mouse pointer within, it should show stable 100% on R G B. If so, the white level is not too high, it could however be too low. To test that, go to the raw tab and adjust the "white point linear correction factor", reduce it until one of the channels is no longer 100%, and then increase in steps of 0.01 until all are 100 again. Usually you play around in the range 0.90 to 0.99, i.e. @@ -438,7 +438,7 @@ Camera constants: { "iso": [ 160 ], "levels": 13000 }, // nominal f8-13105 { "iso": [ 320, 640, 1250, 2500 ], "levels": 13300 }, // G1,G2 F4.0-13422-F2.8-13562-13616 { "iso": [ 5000, 10000, 20000 ], "levels": 13200 }, // G1,G2 F4.0-13422-F2.8-13562-13616 - { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 16100 }, // nominal 16383, + { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 16100 }, // nominal 16383, { "iso": [ 6400, 8000, 12800, 16000, 25600, 32000 ], "levels": 16000 }, // R,G1,G2 16383, LENR? { "iso": [ 40000, 51200, 102400 ], "levels": 15800 } // 16383, LENR? ], @@ -462,7 +462,7 @@ Camera constants: "make_model": [ "Canon EOS 5DS R", "Canon EOS 5DS" ], //"dcraw_matrix": [ 6848,-1661,-221,-3904,10931,3434,-470,1251,6039 ], // DNG_V9.0 A "dcraw_matrix": [ 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 ], // DNG_V9.0 D65 - "raw_crop": [ 192, 96, 8696, 5800 ], // 800, 300, 7500, 4700 - 160,64,8730x5800 - sensor 8896x5920 top64, left160, official crop left196, top100, right 8883, bottom 5891, 8688X5792 + "raw_crop": [ 192, 96, 8696, 5800 ], // 800, 300, 7500, 4700 - 160,64,8730x5800 - sensor 8896x5920 top64, left160, official crop left196, top100, right 8883, bottom 5891, 8688X5792 "masked_areas": [ 100, 40, 5892, 158 ], // left out 40 first columns from calculations because possibly the BL is still imbalanced there "ranges": { "white": [ @@ -497,7 +497,7 @@ Camera constants: { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 13100 }, // typical 13225 { "iso": [ 5000, 10000 ], "levels": 13000 }, // typical 13225 { "iso": [ 20000 ], "levels": 12800 }, // typical 13225 - { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 + { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 ], "white_max": 16383, "aperture_scaling": [ @@ -522,7 +522,7 @@ Camera constants: "dcraw_matrix": [ 6875,-970,-932,-4691,12459,2501,-874,1953,5809 ], // DNG v_9.12 D65 "raw_crop": [ 120, 44, 6264, 4180 ], // fullraw size 6384x4224 useful 120,44,6264x4180 // "raw_crop": [ 128, 52, 6248, 4168 ], // official jpeg crop 120+12,44+12,6240x4160 - "masked_areas": [ 44, 4, 4220, 116 ], + "masked_areas": [ 44, 4, 4220, 116 ], "ranges": { "white": [ { "iso": [ 50, 100, 125, 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200 ], "levels": 16300 }, // typical 16383 @@ -532,7 +532,7 @@ Camera constants: { "iso": [ 320, 640, 1250, 2500 ], "levels": 13250 }, // typical 13337 { "iso": [ 5000, 10000 ], "levels": 13100 }, // typical 13367 { "iso": [ 20000, 40000 ], "levels": 12900 }, // typical 13367 - { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 + { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 ], "white_max": 16383, "aperture_scaling": [ @@ -588,8 +588,8 @@ Camera constants: { "iso": [ 100, 125 ], "levels": 13500 }, // typical 13583 - LENR 13550 { "iso": [ 160, 320, 640, 1250, 2500, 5000 ], "levels": 12500 }, // typical 12559 { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15200 }, // typical 15303 - LENR 15270,15260,15240,15220, - { "iso": [ 6400, 8000, 10000, 12800, 16000, 20000, 25600 ], "levels": 15100 }, // typical G1,G2 15303, R,B = 15430 LENR 15200 .. 15100 - { "iso": 51200, "levels": 16300 } // typical 16383 red 16371 + { "iso": [ 6400, 8000, 10000, 12800, 16000, 20000, 25600 ], "levels": 15100 }, // typical G1,G2 15303, R,B = 15430 LENR 15200 .. 15100 + { "iso": 51200, "levels": 16300 } // typical 16383 red 16371 ], "white_max": 16383, "aperture_scaling": [ @@ -620,7 +620,7 @@ Camera constants: { "iso": [ 200, 400 ], "levels": 16100 }, // typical 16224 { "iso": 800, "levels": 15900 }, // gaussian histogram 15900-16224 { "iso": 1600, "levels": 14900 }, // gaussian histogram 14900-15750 - { "iso": 1250, "levels": 11900 } // gaussian histogram 11900-12500 + { "iso": 1250, "levels": 11900 } // gaussian histogram 11900-12500 ], "white_max": 16383, "aperture_scaling": [ @@ -1082,9 +1082,9 @@ Camera constants: "masked_areas": [ 40, 16, 4000, 54 ], "ranges": { "white": [ - { "iso": [ 100, 125, 160 ], "levels": 16300 }, // 16383 - { "iso": [ 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12600 }, // 12632..14500 - { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15000 }, // 15095, 15488 + { "iso": [ 100, 125, 160 ], "levels": 16300 }, // 16383 + { "iso": [ 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12600 }, // 12632..14500 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15000 }, // 15095, 15488 { "iso": [ 6400, 8000, 12800, 25600 ], "levels": 16200 } // 16383 ], "white_max": 16383, @@ -1104,10 +1104,10 @@ Camera constants: }, { // Quality C, White Levels not properly indicated, aperture scaling..missing factors are guessed - "make_model": [ "Canon EOS M5","Canon EOS M6" ], + "make_model": [ "Canon EOS M5","Canon EOS M6" ], "dcraw_matrix": [ 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 ], // DNG_V9.8 D65 "raw_crop": [ 264, 36, 6024, 4020 ], // full size 6288x4056, - //"raw_crop": [ 272, 44, 6008, 4008 ], // matched to official crop 276,48,6275,4047 - official jpeg 6000X4000 + //"raw_crop": [ 272, 44, 6008, 4008 ], // matched to official crop 276,48,6275,4047 - official jpeg 6000X4000 "masked_areas": [ 40, 96, 4000, 260 ], "ranges": { "white": [ @@ -1116,9 +1116,9 @@ Camera constants: { "iso": [ 320 ], "levels": 13100 }, // nominal green 13200, 13528-14466-14380-14368 - blue13262-14186, { "iso": [ 640, 1250 ], "levels": 13200 }, // iso 640 G1,G2 13260-13450 - blue13230-13430 -iso 1250 13430 { "iso": [ 2500, 5000, 10000 ], "levels": 13000 }, // - { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400 ], "levels": 16100 }, // 16383 - // { "iso": [ 1600 ], "levels": 15000 }, // one sample of m6 = 15100 !! - // { "iso": [ 6400 ], "levels": 15500 }, // one sample of m6 = 15600 !! + { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400 ], "levels": 16100 }, // 16383 + // { "iso": [ 1600 ], "levels": 15000 }, // one sample of m6 = 15100 !! + // { "iso": [ 6400 ], "levels": 15500 }, // one sample of m6 = 15600 !! { "iso": [ 8000, 12800, 16000, 25600 ], "levels": 16000 } // R,G1,G2 16383, B 16243 ], "white_max": 16383, @@ -1176,7 +1176,7 @@ Camera constants: "dcraw_matrix": [ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 ], // D65 matrix from adobe dcp //"raw_crop": [ 80, 50, 4400, 3316 ], // full frame 4480x3366 borders 80,50 - much shade in corners, no/wrong auto distortion //"raw_crop": [ 104, 144, 4360, 3128 ], // Mixed best average frame, width is 4352 from 3/2, height 3120 from 4/3 - auto distortion does not work correctly - //"raw_crop": [ 200, 144, 4168, 3128 ], // Optional official 4/3 frame 4160x3120, 4pix borders, Left Border 204-4, Top Border 148-4 + //"raw_crop": [ 200, 144, 4168, 3128 ], // Optional official 4/3 frame 4160x3120, 4pix borders, Left Border 204-4, Top Border 148-4 "raw_crop": [ 104, 252, 4360, 2912 ], // Default official 3/2 frame 4352x2904, 4pix borders, Left Border 108-4, Top border 256-4 "masked_areas": [ 148, 2, 3340, 78 ], "ranges": { "white": 16300 } @@ -1346,8 +1346,8 @@ Camera constants: { // Quality C, only raw crop "make_model": [ "FUJIFILM X-T3", "FUJIFILM X-T30" ], "raw_crop": [ 0, 5, 6252, 4176] - }, - + }, + { // Quality B "make_model": "FUJIFILM X30", "dcraw_matrix": [ 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 ], // DNG_v8.7 D65 @@ -1622,14 +1622,14 @@ Camera constants: "ranges": { "white": 3980 } // 12-bit files. }, - { // Quality C, only colour matrix and PDAF lines info + { // Quality C, only color matrix and PDAF lines info "make_model" : "Nikon Z 7", "dcraw_matrix" : [10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785], // Adobe DNG Converter 11.0 ColorMatrix2 "pdaf_pattern" : [0, 12], "pdaf_offset" : 29 }, - { // Quality C, only colour matrix and PDAF lines info + { // Quality C, only color matrix and PDAF lines info "make_model" : "Nikon Z 6", "dcraw_matrix" : [8210, -2534, -683, -5355, 13338, 2212, -1143, 1929, 6464], // Adobe DNG Converter 11.1 Beta ColorMatrix2 "pdaf_pattern" : [0, 12], @@ -1815,7 +1815,7 @@ Camera constants: { // Quality B, "make_model": [ "Panasonic DMC-FZ2500", "Panasonic DMC-FZ2000", "Panasonic DMC-FZH1" ], - "dcraw_matrix": [ 7386,-2443,-743,-3437,11864,1757,-608,1660,4766 ], // dcp_v9.8 d65 + "dcraw_matrix": [ 7386,-2443,-743,-3437,11864,1757,-608,1660,4766 ], // dcp_v9.8 d65 "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base BL from Exif and calculates total BL = BLbase+BLoffset "white": [ @@ -1906,7 +1906,8 @@ Camera constants: "dcraw_matrix": [ 7122,-2092,-419,-4643,11769,3283,-1363,2413,5944 ], // RT "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base black from Exif and calculates total BL = BLbase+BLoffset - "white": 4060 } // Exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR + "white": 4060 // Exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR + } }, { // Quality A, Replicated from rawimage.cc @@ -1926,7 +1927,8 @@ Camera constants: "dcraw_matrix": [ 7694,-1791,-745,-4917,12818,2332,-1221,2322,7197 ], // Colin Walker "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base black from Exif and calculates total BL = BLbase+BLoffset - "white": 4050 } // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + "white": 4050 // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + } }, { // Quality A, Replicated from rawimage.cc @@ -1934,7 +1936,8 @@ Camera constants: "dcraw_matrix": [ 8074,-1846,-861,-5026,12999,2239,-1320,2375,7422 ], // Colin Walker "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base black from Exif and calculates total BL = BLbase+BLoffset - "white": 4050 } // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + "white": 4050 // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + } }, { // Quality A, Replicated from rawimage.cc @@ -2247,7 +2250,7 @@ Camera constants: } }, - { // Quality B, corrections for raw crop vs dcraw9.21, matched to Samsung's default + { // Quality B, corrections for raw crop vs dcraw9.21, matched to Samsung's default "make_model": "Samsung NX mini", "dcraw_matrix": [ 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 ], // dng 8.6 d65 "raw_crop": [ 128, 36, 5480, 3656 ], // jpeg 5472x3648 - full raw: 5664 x 3710 - Samsung's official crop: 132, 40, 5604, 3688 @@ -2270,8 +2273,8 @@ Camera constants: { "iso": 100, "levels": 16000 }, // 16000 typical 16084, LE 16120 and 16383, LENR 16280 { "iso": [ 200, 400, 800, 1600, 3200, 6400, 12800 ], "levels": 16300 }, // 16383 { "iso": [ 25600, 51200 ], "levels": 16300 } // 16383 - ] - } + ] + } }, { // Quality C, corrections for frame size, black and white levels not declared properly @@ -2310,7 +2313,7 @@ Camera constants: //"dcraw_matrix": [ 5666,139,-892,3780,5428,270,1366,9757,4526 ], // experimental inverted icc sunny8161 //"dcraw_matrix": [ 10288,-2449,-1718,8976,1868,-1608,7011,5039,-249 ], // experimental inverted icc tungsten8130 wp11 //"dcraw_matrix": [ 5864,679,-1491,2963,7635,-919,-640,13738,2790 ], // experimental inverted icc sunny8160 - //"dcraw_matrix": [ 14032,-2231,-1016,-5263,14816,170,-112,183,9113 ], // hardcoded + //"dcraw_matrix": [ 14032,-2231,-1016,-5263,14816,170,-112,183,9113 ], // hardcoded "ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the top "raw_crop": [ 12, 52, -110, -8 ] // for small size all numbers/2 }, @@ -2394,7 +2397,7 @@ Camera constants: "ranges": { "black": 512, "white": 16300 }, // contributed by Horshak from https://www.dpreview.com/forums/post/60873077 "pdaf_pattern" : [ 0,12,36,54,72,90,114,126,144,162,180,204,216,240,252,270,294,306,324,342,366,384,396,414,432,450,474,492,504,522,540,564,576,594,606,630 ], - "pdaf_offset" : 3 + "pdaf_offset" : 3 }, { // Quality A, correction for frame width @@ -2429,8 +2432,8 @@ Camera constants: { // Quality C, color matrix copied from ILCE-9, LongExposures 2-3sec only "make_model": "Sony ILCE-7M3", "dcraw_matrix": [ 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 ], // ILCE-9, DNG_v9.12 D65 - // "raw_crop": [ 8, 8, 6008, 4008 ], // full raw frame 6048x4024 Dcraw auto identify 6024x4024, jpeg 12,12,6000x4000 - // "ranges": { "black": 512, "white": 16300 } + // "raw_crop": [ 8, 8, 6008, 4008 ], // full raw frame 6048x4024 Dcraw auto identify 6024x4024, jpeg 12,12,6000x4000 + // "ranges": { "black": 512, "white": 16300 } "ranges": { "black": 512, "white": [ From 506254ce4631985bd2832d490dd760a2dc925949 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 14 Aug 2019 17:19:26 +0200 Subject: [PATCH 111/222] capture sharpening: first mockup --- rtdata/languages/default | 8 ++ rtengine/color.h | 12 ++ rtengine/imagesource.h | 3 +- rtengine/improccoordinator.cc | 6 +- rtengine/improcfun.h | 2 +- rtengine/ipsharpen.cc | 8 +- rtengine/procparams.cc | 25 ++++ rtengine/procparams.h | 2 + rtengine/rawimagesource.cc | 33 +++++ rtengine/rawimagesource.h | 2 +- rtengine/simpleprocess.cc | 3 + rtengine/stdimagesource.h | 2 +- rtgui/CMakeLists.txt | 1 + rtgui/addsetids.h | 1 + rtgui/paramsedited.cc | 46 +++++++ rtgui/paramsedited.h | 3 + rtgui/pdsharpening.cc | 221 ++++++++++++++++++++++++++++++++++ rtgui/pdsharpening.h | 62 ++++++++++ rtgui/toolpanelcoord.cc | 10 +- rtgui/toolpanelcoord.h | 3 +- 20 files changed, 441 insertions(+), 12 deletions(-) create mode 100644 rtgui/pdsharpening.cc create mode 100644 rtgui/pdsharpening.h diff --git a/rtdata/languages/default b/rtdata/languages/default index e8392db6b..9aa743ab0 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -763,6 +763,11 @@ HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold +HISTORY_MSG_PDSHARPEN_CONTRAST;CAS - Contrast threshold +HISTORY_MSG_PDSHARPEN_ENABLED;Capture Sharpening +HISTORY_MSG_PDSHARPEN_GAMMA;CAS - Gamma +HISTORY_MSG_PDSHARPEN_ITERATIONS;CAS - Iterations +HISTORY_MSG_PDSHARPEN_RADIUS;CAS - Radius HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -773,6 +778,7 @@ 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_SHARPENING_GAMMA;Sharpening - Gamma HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength @@ -1792,6 +1798,7 @@ TP_PCVIGNETTE_ROUNDNESS;Roundness TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. TP_PCVIGNETTE_STRENGTH;Strength TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +TP_PDSHARPENING_LABEL;Capture Sharpening TP_PERSPECTIVE_HORIZONTAL;Horizontal TP_PERSPECTIVE_LABEL;Perspective TP_PERSPECTIVE_VERTICAL;Vertical @@ -2020,6 +2027,7 @@ TP_SHARPENING_BLUR;Blur radius TP_SHARPENING_CONTRAST;Contrast threshold TP_SHARPENING_EDRADIUS;Radius TP_SHARPENING_EDTOLERANCE;Edge tolerance +TP_SHARPENING_GAMMA;Gamma TP_SHARPENING_HALOCONTROL;Halo control TP_SHARPENING_HCAMOUNT;Amount TP_SHARPENING_LABEL;Sharpening diff --git a/rtengine/color.h b/rtengine/color.h index 5bf178636..22a648634 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1804,6 +1804,18 @@ public: return (hr); } + static inline void RGB2YCbCr(float R, float G, float B, float &Y, float &Cb, float &Cr) { + Y = 0.2627f * R + 0.6780f * G + 0.0593f * B; + Cb = -0.2627f * R - 0.6780f * G + (1.f - 0.0593f) * B; + Cr = (1.f - 0.2627f) * R - 0.6780f * G - 0.0593f * B; + + } + + static inline void YCbCr2RGB(float Y, float Cb, float Cr, float &R, float &G, float &B) { + R = std::max(Y + Cr, 0.f); + G = std::max(Y - (0.0593f / 0.6780f) * Cb - (0.2627f / 0.6780f) * Cr, 0.f); + B = std::max(Y + Cb, 0.f); + } }; } diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index bf73b5bb2..6e57bd532 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -46,7 +46,7 @@ struct LensProfParams; struct RAWParams; struct RetinexParams; struct ToneCurveParams; - +struct SharpeningParams; } class ImageMatrices @@ -182,6 +182,7 @@ public: return this; } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; + virtual void captureSharpening(const procparams::SharpeningParams &sharpeningParams) = 0; }; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 6f471eedf..2e2ae9084 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -332,6 +332,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicContrast : params->raw.xtranssensor.dualDemosaicContrast; imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic + if (params->pdsharpening.enabled) { + imgsrc->captureSharpening(params->pdsharpening); + } if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) { bayerAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); } @@ -1546,7 +1549,8 @@ void ImProcCoordinator::process() || params->retinex != nextParams->retinex || params->wavelet != nextParams->wavelet || params->dirpyrequalizer != nextParams->dirpyrequalizer - || params->dehaze != nextParams->dehaze; + || params->dehaze != nextParams->dehaze + || params->pdsharpening != nextParams->pdsharpening; *params = *nextParams; int change = changeSinceLast; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 987a460d7..65f0f5a96 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -248,7 +248,7 @@ public: void Lanczos(const LabImage* src, LabImage* dst, float scale); void Lanczos(const Imagefloat* src, Imagefloat* dst, float scale); - void deconvsharpening(float** luminance, float** buffer, int W, int H, const procparams::SharpeningParams &sharpenParam); + void deconvsharpening(float** luminance, float** buffer, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale); void MLsharpen(LabImage* lab); // Manuel's clarity / sharpening void MLmicrocontrast(float** luminance, int W, int H); //Manuel's microcontrast void MLmicrocontrast(LabImage* lab); //Manuel's microcontrast diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 9d7358fa9..eeda786a5 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -158,7 +158,7 @@ namespace rtengine extern const Settings* settings; -void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, int W, int H, const SharpeningParams &sharpenParam) +void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, int W, int H, const SharpeningParams &sharpenParam, double Scale) { if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) { return; @@ -201,7 +201,7 @@ BENCHFUN } const float damping = sharpenParam.deconvdamping / 5.0; const bool needdamp = sharpenParam.deconvdamping > 0; - const double sigma = sharpenParam.deconvradius / scale; + const double sigma = sharpenParam.deconvradius / Scale; const float amount = sharpenParam.deconvamount / 100.f; #ifdef _OPENMP @@ -274,7 +274,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen JaggedArray b2(W, H); if (sharpenParam.method == "rld") { - deconvsharpening (lab->L, b2, lab->W, lab->H, sharpenParam); + deconvsharpening (lab->L, b2, lab->W, lab->H, sharpenParam, scale); return; } BENCHFUN @@ -905,7 +905,7 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask) if (params->sharpening.method == "rld") { - deconvsharpening (ncie->sh_p, b2, ncie->W, ncie->H, params->sharpening); + deconvsharpening (ncie->sh_p, b2, ncie->W, ncie->H, params->sharpening, scale); return; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 66837f89b..4f2cdce2e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1080,6 +1080,7 @@ SharpeningParams::SharpeningParams() : enabled(false), contrast(20.0), blurradius(0.2), + gamma(1.0), radius(0.5), amount(200), threshold(20, 80, 2000, 1200, false), @@ -1102,6 +1103,7 @@ bool SharpeningParams::operator ==(const SharpeningParams& other) const enabled == other.enabled && contrast == other.contrast && blurradius == other.blurradius + && gamma == other.gamma && radius == other.radius && amount == other.amount && threshold == other.threshold @@ -2787,6 +2789,13 @@ void ProcParams::setDefaults() prsharpening.deconviter = 100; prsharpening.deconvdamping = 0; + pdsharpening = {}; + pdsharpening.contrast = 0.0; + prsharpening.method = "rld"; + pdsharpening.gamma = 1.0; + pdsharpening.deconvradius = 0.75; + pdsharpening.deconviter = 30; + vibrance = {}; wb = {}; @@ -3296,6 +3305,13 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->resize.height, "Resize", "Height", resize.height, keyFile); saveToKeyfile(!pedited || pedited->resize.allowUpscaling, "Resize", "AllowUpscaling", resize.allowUpscaling, keyFile); +// Post demosaic sharpening + saveToKeyfile(!pedited || pedited->pdsharpening.enabled, "PostDemosaicSharpening", "Enabled", pdsharpening.enabled, keyFile); + saveToKeyfile(!pedited || pedited->pdsharpening.contrast, "PostDemosaicSharpening", "Contrast", pdsharpening.contrast, 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.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); + // Post resize sharpening saveToKeyfile(!pedited || pedited->prsharpening.enabled, "PostResizeSharpening", "Enabled", prsharpening.enabled, keyFile); saveToKeyfile(!pedited || pedited->prsharpening.contrast, "PostResizeSharpening", "Contrast", prsharpening.contrast, keyFile); @@ -4376,6 +4392,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } + if (keyFile.has_group("PostDemosaicSharpening")) { + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Enabled", pedited, pdsharpening.enabled, pedited->pdsharpening.enabled); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pedited, pdsharpening.contrast, pedited->pdsharpening.contrast); + + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvGamma", pedited, pdsharpening.gamma, pedited->pdsharpening.gamma); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter); + } + if (keyFile.has_group("PostResizeSharpening")) { assignFromKeyfile(keyFile, "PostResizeSharpening", "Enabled", pedited, prsharpening.enabled, pedited->prsharpening.enabled); assignFromKeyfile(keyFile, "PostResizeSharpening", "Contrast", pedited, prsharpening.contrast, pedited->prsharpening.contrast); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 369af85fa..f9255f815 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -494,6 +494,7 @@ struct SharpeningParams { bool enabled; double contrast; double blurradius; + double gamma; double radius; int amount; Threshold threshold; @@ -1526,6 +1527,7 @@ public: ColorToningParams colorToning; ///< Color Toning parameters SharpeningParams sharpening; ///< Sharpening parameters SharpeningParams prsharpening; ///< Sharpening parameters for post resize sharpening + SharpeningParams pdsharpening; ///< Sharpening parameters for post demosaic sharpening SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters VibranceParams vibrance; ///< Vibrance parameters diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 6cb6fff16..5d8dd8448 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -37,6 +37,9 @@ #include "pdaflinesfilter.h" #include "camconst.h" #include "procparams.h" +#include "color.h" +#define BENCHMARK +#include "StopWatch.h" #ifdef _OPENMP #include #endif @@ -4949,6 +4952,36 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int } } +void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams) { +BENCHFUN + + array2D Y(W,H); + array2D Cb(W,H); + array2D Cr(W,H); + const float gamma = sharpeningParams.gamma; + StopWatch Stop1("rgb2Y"); + #pragma omp parallel for + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W ; ++j) { + Color::RGB2YCbCr(std::max(red[i][j], 0.f), std::max(green[i][j], 0.f), std::max(blue[i][j], 0.f), Y[i][j], Cb[i][j], Cr[i][j]); + Y[i][j] = pow_F(Y[i][j], 1.f / gamma); + } + } + Stop1.stop(); + array2D tmp(W, H); + ProcParams dummy; + ImProcFunctions ipf(&dummy); + ipf.deconvsharpening(Y, tmp, W, H, sharpeningParams, 1.0); + StopWatch Stop2("Y2RGB"); + #pragma omp parallel for + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W ; ++j) { + Y[i][j] = pow_F(Y[i][j], gamma); + Color::YCbCr2RGB(Y[i][j], Cb[i][j], Cr[i][j], red[i][j], green[i][j], blue[i][j]); + } + } + Stop2.stop(); +} void RawImageSource::cleanup () { delete phaseOneIccCurve; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 7c50991c0..7b86111af 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -305,7 +305,7 @@ protected: void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; - + void captureSharpening(const procparams::SharpeningParams &sharpeningParams) override; }; } diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 2d594e0af..a9d32dbac 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -221,6 +221,9 @@ private: double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast; imgsrc->demosaic (params.raw, autoContrast, contrastThreshold); + if (params.pdsharpening.enabled) { + imgsrc->captureSharpening(params.pdsharpening); + } if (pl) { diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 8f16880dc..a8251ade0 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -102,7 +102,7 @@ public: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;} void flushRGB () override; - + void captureSharpening(const procparams::SharpeningParams &sharpeningParams) override {}; }; } #endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index bdd166938..bc52b64b0 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -106,6 +106,7 @@ set(NONCLISOURCEFILES partialpastedlg.cc pathutils.cc pcvignette.cc + pdsharpening.cc perspective.cc placesbrowser.cc popupbutton.cc diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 163bc27ef..6a4ea83d3 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -142,6 +142,7 @@ enum { ADDSET_XTRANS_FALSE_COLOR_SUPPRESSION, ADDSET_SOFTLIGHT_STRENGTH, ADDSET_DEHAZE_STRENGTH, + ADDSET_SHARP_GAMMA, ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!! }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index cb3d4151c..da65cbf8e 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -152,6 +152,7 @@ void ParamsEdited::set(bool v) sharpening.contrast = v; sharpening.radius = v; sharpening.blurradius = v; + sharpening.gamma = v; sharpening.amount = v; sharpening.threshold = v; sharpening.edgesonly = v; @@ -164,6 +165,12 @@ void ParamsEdited::set(bool v) sharpening.deconvradius = v; sharpening.deconviter = v; sharpening.deconvdamping = v; + pdsharpening.enabled = v; + pdsharpening.contrast = v; + pdsharpening.gamma = v; + pdsharpening.deconvamount = v; + pdsharpening.deconvradius = v; + pdsharpening.deconviter = v; prsharpening.enabled = v; prsharpening.contrast = v; prsharpening.radius = v; @@ -729,6 +736,7 @@ void ParamsEdited::initFrom(const std::vector& 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.gamma = sharpening.gamma && p.sharpening.gamma == other.sharpening.gamma; 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; @@ -741,6 +749,11 @@ void ParamsEdited::initFrom(const std::vector& sharpening.deconvradius = sharpening.deconvradius && p.sharpening.deconvradius == other.sharpening.deconvradius; sharpening.deconviter = sharpening.deconviter && p.sharpening.deconviter == other.sharpening.deconviter; sharpening.deconvdamping = sharpening.deconvdamping && p.sharpening.deconvdamping == other.sharpening.deconvdamping; + pdsharpening.enabled = pdsharpening.enabled && p.pdsharpening.enabled == other.pdsharpening.enabled; + pdsharpening.contrast = pdsharpening.contrast && p.pdsharpening.contrast == other.pdsharpening.contrast; + pdsharpening.gamma = pdsharpening.gamma && p.pdsharpening.gamma == other.pdsharpening.gamma; + pdsharpening.deconvradius = pdsharpening.deconvradius && p.pdsharpening.deconvradius == other.pdsharpening.deconvradius; + 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; prsharpening.radius = prsharpening.radius && p.prsharpening.radius == other.prsharpening.radius; @@ -1654,6 +1667,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.sharpening.blurradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.blurradius + mods.sharpening.blurradius : mods.sharpening.blurradius; } + if (sharpening.gamma) { + toEdit.sharpening.gamma = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.gamma + mods.sharpening.gamma : mods.sharpening.gamma; + } + if (sharpening.amount) { toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount; } @@ -1702,6 +1719,30 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.sharpening.deconvdamping = dontforceSet && options.baBehav[ADDSET_SHARP_DAMPING] ? toEdit.sharpening.deconvdamping + mods.sharpening.deconvdamping : mods.sharpening.deconvdamping; } + if (pdsharpening.enabled) { + toEdit.pdsharpening.enabled = mods.pdsharpening.enabled; + } + + if (pdsharpening.contrast) { + toEdit.pdsharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.pdsharpening.contrast + mods.pdsharpening.contrast : mods.pdsharpening.contrast; + } + + if (pdsharpening.deconvamount) { + toEdit.pdsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.pdsharpening.deconvamount + mods.pdsharpening.deconvamount : mods.pdsharpening.deconvamount; + } + + if (pdsharpening.gamma) { + toEdit.pdsharpening.gamma = dontforceSet && options.baBehav[ADDSET_SHARP_GAMMA] ? toEdit.pdsharpening.gamma + mods.pdsharpening.gamma : mods.pdsharpening.gamma; + } + + if (pdsharpening.deconvradius) { + toEdit.pdsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.pdsharpening.deconvradius + mods.pdsharpening.deconvradius : mods.pdsharpening.deconvradius; + } + + if (pdsharpening.deconviter) { + toEdit.pdsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.pdsharpening.deconviter + mods.pdsharpening.deconviter : mods.pdsharpening.deconviter; + } + if (prsharpening.enabled) { toEdit.prsharpening.enabled = mods.prsharpening.enabled; } @@ -3244,3 +3285,8 @@ bool FilmNegativeParamsEdited::isUnchanged() const { return enabled && redRatio && greenExp && blueRatio; } + +bool SharpeningParamsEdited::isUnchanged() const +{ + return enabled && contrast && gamma && deconvradius && deconviter; +} \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 08a41fc7a..5191bce56 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -180,6 +180,7 @@ struct SharpeningParamsEdited { bool enabled; bool contrast; bool blurradius; + bool gamma; bool radius; bool amount; bool threshold; @@ -194,6 +195,7 @@ struct SharpeningParamsEdited { bool deconvradius; bool deconviter; bool deconvdamping; + bool isUnchanged() const; }; struct VibranceParamsEdited { @@ -684,6 +686,7 @@ struct ParamsEdited { ColorToningEdited colorToning; RetinexParamsEdited retinex; SharpeningParamsEdited sharpening; + SharpeningParamsEdited pdsharpening; SharpeningParamsEdited prsharpening; SharpenEdgeParamsEdited sharpenEdge; SharpenMicroParamsEdited sharpenMicro; diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc new file mode 100644 index 000000000..a33da813d --- /dev/null +++ b/rtgui/pdsharpening.cc @@ -0,0 +1,221 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#include "eventmapper.h" +#include "pdsharpening.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PDSHARPENING_LABEL"), false, true) +{ + + auto m = ProcEventMapper::getInstance(); + EvPdShrEnabled = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ENABLED"); + EvPdShrContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_CONTRAST"); + EvPdSharpenGamma = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_GAMMA"); + EvPdShrDRadius = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_RADIUS"); + EvPdShrDIterations = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); + + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->show (); + contrast = Gtk::manage(new Adjuster (M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 15)); + contrast->setAdjusterListener (this); + pack_start(*contrast); + contrast->show(); + + pack_start (*hb); + + rld = new Gtk::VBox (); + gamma = Gtk::manage (new Adjuster (M("TP_SHARPENING_GAMMA"), 0.5, 3.0, 0.05, 1.0)); + dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.75)); + diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + rld->pack_start (*gamma); + rld->pack_start (*dradius); + rld->pack_start (*diter); + gamma->show(); + dradius->show (); + diter->show (); + rld->show (); + pack_start(*rld); + + dradius->setAdjusterListener (this); + gamma->setAdjusterListener (this); + diter->setAdjusterListener (this); + + rld->reference(); +} + +PdSharpening::~PdSharpening () +{ + + delete rld; +} + + +void PdSharpening::read (const ProcParams* pp, const ParamsEdited* pedited) +{ + + disableListener (); + + if (pedited) { + contrast->setEditedState (pedited->pdsharpening.contrast ? Edited : UnEdited); + gamma->setEditedState (pedited->pdsharpening.gamma ? Edited : UnEdited); + dradius->setEditedState (pedited->pdsharpening.deconvradius ? Edited : UnEdited); + diter->setEditedState (pedited->pdsharpening.deconviter ? Edited : UnEdited); + + set_inconsistent (multiImage && !pedited->pdsharpening.enabled); + } + + setEnabled(pp->pdsharpening.enabled); + + contrast->setValue (pp->pdsharpening.contrast); + gamma->setValue (pp->pdsharpening.gamma); + dradius->setValue (pp->pdsharpening.deconvradius); + diter->setValue (pp->pdsharpening.deconviter); + + enableListener (); +} + +void PdSharpening::write (ProcParams* pp, ParamsEdited* pedited) +{ + + pp->pdsharpening.contrast = contrast->getValue (); + pp->pdsharpening.enabled = getEnabled (); + pp->pdsharpening.gamma = gamma->getValue (); + pp->pdsharpening.deconvradius = dradius->getValue (); + pp->pdsharpening.deconviter = (int)diter->getValue (); + + if (pedited) { + pedited->pdsharpening.contrast = contrast->getEditedState (); + pedited->pdsharpening.gamma = gamma->getEditedState (); + pedited->pdsharpening.deconvradius = dradius->getEditedState (); + pedited->pdsharpening.deconviter = diter->getEditedState (); + pedited->pdsharpening.enabled = !get_inconsistent(); + } +} + +void PdSharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +{ + + contrast->setDefault (defParams->pdsharpening.contrast); + gamma->setDefault (defParams->pdsharpening.gamma); + dradius->setDefault (defParams->pdsharpening.deconvradius); + 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); + diter->setDefaultEditedState (pedited->pdsharpening.deconviter ? Edited : UnEdited); + } else { + contrast->setDefaultEditedState (Irrelevant); + gamma->setDefaultEditedState (Irrelevant); + dradius->setDefaultEditedState (Irrelevant); + diter->setDefaultEditedState (Irrelevant); + } +} + +void PdSharpening::adjusterChanged (Adjuster* a, double newval) +{ + if (listener && (multiImage || getEnabled()) ) { + + Glib::ustring costr; + + if (a == gamma || a == dradius) { + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + } else { + costr = Glib::ustring::format ((int)a->getValue()); + } + + if (a == contrast) { + listener->panelChanged (EvPdShrContrast, costr); + } else if (a == gamma) { + listener->panelChanged (EvPdSharpenGamma, costr); + } else if (a == dradius) { + listener->panelChanged (EvPdShrDRadius, costr); + } else if (a == diter) { + listener->panelChanged (EvPdShrDIterations, costr); + } + } +} + +void PdSharpening::enabledChanged () +{ + if (listener) { + if (get_inconsistent()) { + listener->panelChanged (EvPdShrEnabled, M("GENERAL_UNCHANGED")); + } else if (getEnabled()) { + listener->panelChanged (EvPdShrEnabled, M("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvPdShrEnabled, M("GENERAL_DISABLED")); + } + } +} + +void PdSharpening::adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) +{ +} + +void PdSharpening::adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight) +{ +} + +void PdSharpening::adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop) +{ +} + +void PdSharpening::adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) +{ +} + +void PdSharpening::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) +{ +} + +void PdSharpening::setBatchMode (bool batchMode) +{ + + ToolPanel::setBatchMode (batchMode); + +// pack_start (*rld); + + contrast->showEditedCB (); + gamma->showEditedCB (); + dradius->showEditedCB (); + diter->showEditedCB (); +} + +void PdSharpening::setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd) +{ + + contrast->setAddMode(contrastadd); + gamma->setAddMode(gammaadd); + dradius->setAddMode(radiusadd); + diter->setAddMode(iteradd); +} + +void PdSharpening::trimValues (rtengine::procparams::ProcParams* pp) +{ + + contrast->trimValue(pp->pdsharpening.contrast); + gamma->trimValue(pp->pdsharpening.gamma); + dradius->trimValue(pp->pdsharpening.deconvradius); + diter->trimValue(pp->pdsharpening.deconviter); +} diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h new file mode 100644 index 000000000..998322fe4 --- /dev/null +++ b/rtgui/pdsharpening.h @@ -0,0 +1,62 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Ingo Weyrich (heckflosse67@gmx.de) + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#pragma once + +#include +#include "adjuster.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" + +class PdSharpening : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel +{ + +protected: + Adjuster* contrast; + Adjuster* gamma; + Adjuster* dradius; + Adjuster* diter; + Gtk::VBox* rld; + + rtengine::ProcEvent EvPdShrEnabled; + rtengine::ProcEvent EvPdShrContrast; + rtengine::ProcEvent EvPdShrDRadius; + rtengine::ProcEvent EvPdSharpenGamma; + rtengine::ProcEvent EvPdShrDIterations; +public: + + PdSharpening (); + ~PdSharpening () override; + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void setBatchMode (bool batchMode) override; + + void adjusterChanged (Adjuster* a, double newval) override; + void enabledChanged () override; + + void adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) override; + void adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight) override; + void adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop) override; + void adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) override; + void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) override; + + void setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd); + void trimValues (rtengine::procparams::ProcParams* pp) override; +}; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index f7e2991e1..64e44b3fb 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -93,7 +93,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit xtransrawexposure = Gtk::manage (new XTransRAWExposure ()); fattal = Gtk::manage (new FattalToneMapping ()); filmNegative = Gtk::manage (new FilmNegative ()); - + pdSharpening = Gtk::manage (new PdSharpening()); // So Demosaic, Line noise filter, Green Equilibration, Ca-Correction (garder le nom de section identique!) and Black-Level will be moved in a "Bayer sensor" tool, // and a separate Demosaic and Black Level tool will be created in an "X-Trans sensor" tool @@ -156,6 +156,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit addfavoritePanel (rawPanel, darkframe); addfavoritePanel (rawPanel, flatfield); addfavoritePanel (rawPanel, filmNegative); + addfavoritePanel (rawPanel, pdSharpening); int favoriteCount = 0; for(auto it = favorites.begin(); it != favorites.end(); ++it) { @@ -309,6 +310,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::show(); + pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -325,6 +327,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::show(); + pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -341,6 +344,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::hide(); + pdSharpening->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -356,6 +360,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::hide(); filmNegative->FoldableToolPanel::hide(); + pdSharpening->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -368,6 +373,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt { rawPanelSW->set_sensitive(false); filmNegative->FoldableToolPanel::hide(); + pdSharpening->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(true); return false; @@ -484,7 +490,7 @@ void ToolPanelCoordinator::profileChange( lParams[1] = *mergedParams; pe.initFrom (lParams); - filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged() && pe.retinex.isUnchanged() && pe.filmNegative.isUnchanged(); + filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged() && pe.retinex.isUnchanged() && pe.filmNegative.isUnchanged() && pe.pdsharpening.isUnchanged(); } *params = *mergedParams; diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index a1b26b29f..b88fef124 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -77,6 +77,7 @@ #include "colortoning.h" #include "filmsimulation.h" #include "prsharpening.h" +#include "pdsharpening.h" #include "fattaltonemap.h" #include "localcontrast.h" #include "softlight.h" @@ -157,7 +158,7 @@ protected: FattalToneMapping *fattal; MetaDataPanel* metadata; FilmNegative* filmNegative; - + PdSharpening* pdSharpening; std::vector paramcListeners; rtengine::StagedImageProcessor* ipc; From 72e607a140369eec337cb866246381a9fe9c7a36 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 15 Aug 2019 13:53:15 +0200 Subject: [PATCH 112/222] Fix a clang warning --- rtengine/cplx_wavelet_dec.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h index ccecef819..fab6119d9 100644 --- a/rtengine/cplx_wavelet_dec.h +++ b/rtengine/cplx_wavelet_dec.h @@ -45,7 +45,6 @@ private: static const int maxlevels = 10;//should be greater than any conceivable order of decimation int lvltot, subsamp; - int numThreads; int m_w, m_h;//dimensions int wavfilt_len, wavfilt_offset; @@ -97,7 +96,7 @@ public: template wavelet_decomposition::wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop, int numThreads, int Daub4Len) - : coeff0(nullptr), memoryAllocationFailed(false), lvltot(0), subsamp(subsampling), numThreads(numThreads), m_w(width), m_h(height) + : coeff0(nullptr), memoryAllocationFailed(false), lvltot(0), subsamp(subsampling), m_w(width), m_h(height) { //initialize wavelet filters From 674700c2e2005eddd5dac5397dc25fb26d70842c Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 15 Aug 2019 14:17:46 +0200 Subject: [PATCH 113/222] Fix a clang warning --- rtgui/profilestorecombobox.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index 71371afaa..3fd613cb0 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -314,7 +314,7 @@ Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (const Glib::ustring &name) const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; if (pse->label == name) { - return currRow; + return std::move(currRow); } } } From 4308744df57cdcd0f0b37c0cec41205aab5d0057 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 15 Aug 2019 19:31:52 +0200 Subject: [PATCH 114/222] Remove a nop --- rtengine/rawimagesource.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 6cb6fff16..e8eb17c31 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -4931,9 +4931,7 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int ynew = H - 1 - ynew; } else if (rotate == 270) { std::swap(xnew,ynew); - ynew = H - 1 - ynew; xnew = W - 1 - xnew; - ynew = H - 1 - ynew; } xnew = LIM(xnew, 0, W - 1); From 8421f8780a1c404d72ed92b33ba57f5acecee0c6 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 15 Aug 2019 20:40:32 +0200 Subject: [PATCH 115/222] capture sharpening: contrast threshold --- rtdata/languages/default | 2 +- rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 18 +++++++++--- rtengine/improccoordinator.h | 4 +-- rtengine/improcfun.h | 2 +- rtengine/ipsharpen.cc | 38 ++++++++---------------- rtengine/procevents.h | 2 +- rtengine/procparams.cc | 4 +-- rtengine/rawimagesource.cc | 55 ++++++++++++++++++++++++++++++----- rtengine/rawimagesource.h | 2 +- rtengine/refreshmap.cc | 4 ++- rtengine/rtengine.h | 2 +- rtengine/simpleprocess.cc | 2 +- rtengine/stdimagesource.h | 2 +- rtgui/pdsharpening.cc | 19 ++++++++++-- rtgui/pdsharpening.h | 1 - rtgui/toolpanelcoord.cc | 3 +- 17 files changed, 106 insertions(+), 56 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 9aa743ab0..ba96a43cb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -726,6 +726,7 @@ HISTORY_MSG_490;DRC - Amount HISTORY_MSG_491;White Balance HISTORY_MSG_492;RGB Curves HISTORY_MSG_493;L*a*b* Adjustments +HISTORY_MSG_494;Capture Sharpening HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -764,7 +765,6 @@ HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_CONTRAST;CAS - Contrast threshold -HISTORY_MSG_PDSHARPEN_ENABLED;Capture Sharpening HISTORY_MSG_PDSHARPEN_GAMMA;CAS - Gamma HISTORY_MSG_PDSHARPEN_ITERATIONS;CAS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CAS - Radius diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 6e57bd532..006fe59a6 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -182,7 +182,7 @@ public: return this; } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; - virtual void captureSharpening(const procparams::SharpeningParams &sharpeningParams) = 0; + virtual void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) = 0; }; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 2e2ae9084..29d56e79e 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -53,6 +53,7 @@ ImProcCoordinator::ImProcCoordinator() : softProof(false), gamutCheck(false), sharpMask(false), + sharpMaskChanged(false), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), @@ -333,7 +334,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic if (params->pdsharpening.enabled) { - imgsrc->captureSharpening(params->pdsharpening); + imgsrc->captureSharpening(params->pdsharpening, sharpMask); } if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) { bayerAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); @@ -1347,9 +1348,16 @@ void ImProcCoordinator::getSoftProofing(bool &softProof, bool &gamutCheck) gamutCheck = this->gamutCheck; } -void ImProcCoordinator::setSharpMask (bool sharpMask) +ProcEvent ImProcCoordinator::setSharpMask (bool sharpMask) { - this->sharpMask = sharpMask; + if (this->sharpMask != sharpMask) { + sharpMaskChanged = true; + this->sharpMask = sharpMask; + return params->pdsharpening.enabled ? rtengine::EvPdShrEnabled : rtengine::EvShrEnabled; + } else { + sharpMaskChanged = false; + return rtengine::EvShrEnabled; + } } void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool apply_wb) @@ -1550,8 +1558,10 @@ void ImProcCoordinator::process() || params->wavelet != nextParams->wavelet || params->dirpyrequalizer != nextParams->dirpyrequalizer || params->dehaze != nextParams->dehaze - || params->pdsharpening != nextParams->pdsharpening; + || params->pdsharpening != nextParams->pdsharpening + || sharpMaskChanged; + sharpMaskChanged = false; *params = *nextParams; int change = changeSinceLast; changeSinceLast = 0; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index fdf74d297..0315bc180 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -77,7 +77,7 @@ protected: bool softProof; bool gamutCheck; bool sharpMask; - + bool sharpMaskChanged; int scale; bool highDetailPreprocessComputed; bool highDetailRawComputed; @@ -277,7 +277,7 @@ public: void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const override; void setSoftProofing (bool softProof, bool gamutCheck) override; void getSoftProofing (bool &softProof, bool &gamutCheck) override; - void setSharpMask (bool sharpMask) override; + ProcEvent setSharpMask (bool sharpMask) override; bool updateTryLock () override { return updaterThreadStart.trylock(); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 65f0f5a96..6fe8a785d 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -248,7 +248,7 @@ public: void Lanczos(const LabImage* src, LabImage* dst, float scale); void Lanczos(const Imagefloat* src, Imagefloat* dst, float scale); - void deconvsharpening(float** luminance, float** buffer, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale); + void deconvsharpening(float** luminance, float** buffer, float** blend, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale); void MLsharpen(LabImage* lab); // Manuel's clarity / sharpening void MLmicrocontrast(float** luminance, int W, int H); //Manuel's microcontrast void MLmicrocontrast(LabImage* lab); //Manuel's microcontrast diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index eeda786a5..897aaf7b5 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -158,7 +158,7 @@ namespace rtengine extern const Settings* settings; -void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, int W, int H, const SharpeningParams &sharpenParam, double Scale) +void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, float ** blend, int W, int H, const SharpeningParams &sharpenParam, double Scale) { if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) { return; @@ -175,10 +175,6 @@ 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, 1.f); JaggedArray* blurbuffer = nullptr; if (sharpenParam.blurradius >= 0.25f) { @@ -254,11 +250,12 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen int W = lab->W, H = lab->H; + // 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, 1.f); + if(showMask) { - // 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, 1.f); #ifdef _OPENMP #pragma omp parallel for #endif @@ -274,7 +271,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen JaggedArray b2(W, H); if (sharpenParam.method == "rld") { - deconvsharpening (lab->L, b2, lab->W, lab->H, sharpenParam, scale); + deconvsharpening (lab->L, b2, blend, lab->W, lab->H, sharpenParam, scale); return; } BENCHFUN @@ -290,11 +287,6 @@ 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(lab->L, blend, W, H, contrast); - JaggedArray blur(W, H); if (sharpenParam.blurradius >= 0.25f) { @@ -886,11 +878,11 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask) int W = ncie->W, H = ncie->H; + // calculate contrast based blend factors to reduce sharpening in regions with low contrast + JaggedArray blend(W, H); + float contrast = params->sharpening.contrast / 100.f; + buildBlendMask(ncie->sh_p, blend, W, H, contrast); if(showMask) { - // calculate contrast based blend factors to reduce sharpening in regions with low contrast - JaggedArray blend(W, H); - float contrast = params->sharpening.contrast / 100.f; - buildBlendMask(ncie->sh_p, blend, W, H, contrast); #ifdef _OPENMP #pragma omp parallel for #endif @@ -903,9 +895,8 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask) return; } - if (params->sharpening.method == "rld") { - deconvsharpening (ncie->sh_p, b2, ncie->W, ncie->H, params->sharpening, scale); + deconvsharpening (ncie->sh_p, b2, blend, ncie->W, ncie->H, params->sharpening, scale); return; } @@ -921,11 +912,6 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask) } } - // calculate contrast based blend factors to reduce sharpening in regions with low contrast - JaggedArray blend(W, H); - float contrast = params->sharpening.contrast / 100.f; - buildBlendMask(ncie->sh_p, blend, W, H, contrast); - #ifdef _OPENMP #pragma omp parallel #endif diff --git a/rtengine/procevents.h b/rtengine/procevents.h index bb6a30038..670c0c102 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -520,7 +520,7 @@ enum ProcEventCode { EvWBEnabled = 490, EvRGBEnabled = 491, EvLEnabled = 492, -// EvPixelShiftOneGreen = 493, can be reused + EvPdShrEnabled = 493, NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 4f2cdce2e..e1e66d99c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2790,9 +2790,9 @@ void ProcParams::setDefaults() prsharpening.deconvdamping = 0; pdsharpening = {}; - pdsharpening.contrast = 0.0; + pdsharpening.contrast = 10.0; prsharpening.method = "rld"; - pdsharpening.gamma = 1.0; + pdsharpening.gamma = 1.35; pdsharpening.deconvradius = 0.75; pdsharpening.deconviter = 30; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 5d8dd8448..96f161d9f 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -38,6 +38,7 @@ #include "camconst.h" #include "procparams.h" #include "color.h" +#include "rt_algo.h" #define BENCHMARK #include "StopWatch.h" #ifdef _OPENMP @@ -4952,26 +4953,65 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int } } -void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams) { +void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) { BENCHFUN - array2D Y(W,H); - array2D Cb(W,H); - array2D Cr(W,H); + const float xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } + }; + + float contrast = sharpeningParams.contrast / 100.f; + + if (showMask) { + StopWatch Stop1("Show mask"); + array2D& L = blue; // blue will be overridden anyway => we can use its buffer to store L +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H; ++i) { + Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); + } + array2D& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask + buildBlendMask(L, blend, W, H, contrast, 1.f); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f; + } + } + return; + } + + array2D L(W,H); + array2D& Y = red; // red will be overridden anyway => we can use its buffer to store Y + array2D& Cb = green; // green will be overridden anyway => we can use its buffer to store Cb + array2D& Cr = blue; // blue will be overridden anyway => we can use its buffer to store Cr const float gamma = sharpeningParams.gamma; + StopWatch Stop1("rgb2Y"); #pragma omp parallel for for (int i = 0; i < H; ++i) { - for (int j = 0; j < W ; ++j) { + Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); + for (int j = 0; j < W; ++j) { Color::RGB2YCbCr(std::max(red[i][j], 0.f), std::max(green[i][j], 0.f), std::max(blue[i][j], 0.f), Y[i][j], Cb[i][j], Cr[i][j]); Y[i][j] = pow_F(Y[i][j], 1.f / gamma); } } + // calculate contrast based blend factors to reduce sharpening in regions with low contrast + JaggedArray blend(W, H); + buildBlendMask(L, blend, W, H, contrast, 1.f); + Stop1.stop(); - array2D tmp(W, H); + array2D& tmp = L; // L is not used anymore now => we can use its buffer as the needed temporary buffer ProcParams dummy; ImProcFunctions ipf(&dummy); - ipf.deconvsharpening(Y, tmp, W, H, sharpeningParams, 1.0); + ipf.deconvsharpening(Y, tmp, blend, W, H, sharpeningParams, 1.0); StopWatch Stop2("Y2RGB"); #pragma omp parallel for for (int i = 0; i < H; ++i) { @@ -4982,6 +5022,7 @@ BENCHFUN } Stop2.stop(); } + void RawImageSource::cleanup () { delete phaseOneIccCurve; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 7b86111af..a7aee0843 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -305,7 +305,7 @@ protected: void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; - void captureSharpening(const procparams::SharpeningParams &sharpeningParams) override; + void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) override; }; } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index d741b1744..8282f5b4b 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -519,7 +519,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { HDR, // EvTMFattalAmount ALLNORAW, // EvWBEnabled RGBCURVE, // EvRGBEnabled - LUMINANCECURVE // EvLEnabled + LUMINANCECURVE, // EvLEnabled + DEMOSAIC // EvPdShrEnabled + }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index f772975b0..ca4cebe2e 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -535,7 +535,7 @@ public: virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0; virtual void setSoftProofing (bool softProof, bool gamutCheck) = 0; virtual void getSoftProofing (bool &softProof, bool &gamutCheck) = 0; - virtual void setSharpMask (bool sharpMask) = 0; + virtual ProcEvent setSharpMask (bool sharpMask) = 0; virtual ~StagedImageProcessor () {} diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index a9d32dbac..24a3f3263 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -222,7 +222,7 @@ private: imgsrc->demosaic (params.raw, autoContrast, contrastThreshold); if (params.pdsharpening.enabled) { - imgsrc->captureSharpening(params.pdsharpening); + imgsrc->captureSharpening(params.pdsharpening, false); } diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index a8251ade0..5acb8d113 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -102,7 +102,7 @@ public: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;} void flushRGB () override; - void captureSharpening(const procparams::SharpeningParams &sharpeningParams) override {}; + void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) override {}; }; } #endif diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index a33da813d..896d416b5 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -19,6 +19,7 @@ #include #include "eventmapper.h" #include "pdsharpening.h" +#include "options.h" using namespace rtengine; using namespace rtengine::procparams; @@ -27,7 +28,6 @@ PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PD { auto m = ProcEventMapper::getInstance(); - EvPdShrEnabled = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ENABLED"); EvPdShrContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_CONTRAST"); EvPdSharpenGamma = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_GAMMA"); EvPdShrDRadius = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_RADIUS"); @@ -35,7 +35,7 @@ PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PD Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); hb->show (); - contrast = Gtk::manage(new Adjuster (M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 15)); + contrast = Gtk::manage(new Adjuster (M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 10)); contrast->setAdjusterListener (this); pack_start(*contrast); contrast->show(); @@ -43,7 +43,7 @@ PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PD pack_start (*hb); rld = new Gtk::VBox (); - gamma = Gtk::manage (new Adjuster (M("TP_SHARPENING_GAMMA"), 0.5, 3.0, 0.05, 1.0)); + gamma = Gtk::manage (new Adjuster (M("TP_SHARPENING_GAMMA"), 0.5, 3.0, 0.05, 1.35)); dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.75)); diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); rld->pack_start (*gamma); @@ -59,6 +59,19 @@ PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PD gamma->setAdjusterListener (this); diter->setAdjusterListener (this); + if (contrast->delay < options.adjusterMaxDelay) { + contrast->delay = options.adjusterMaxDelay; + } + if (dradius->delay < options.adjusterMaxDelay) { + dradius->delay = options.adjusterMaxDelay; + } + if (gamma->delay < options.adjusterMaxDelay) { + gamma->delay = options.adjusterMaxDelay; + } + if (diter->delay < options.adjusterMaxDelay) { + diter->delay = options.adjusterMaxDelay; + } + rld->reference(); } diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index 998322fe4..fe9359349 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -33,7 +33,6 @@ protected: Adjuster* diter; Gtk::VBox* rld; - rtengine::ProcEvent EvPdShrEnabled; rtengine::ProcEvent EvPdShrContrast; rtengine::ProcEvent EvPdShrDRadius; rtengine::ProcEvent EvPdSharpenGamma; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 64e44b3fb..93f45aefe 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -695,8 +695,7 @@ void ToolPanelCoordinator::sharpMaskSelected(bool sharpMask) return; } ipc->beginUpdateParams (); - ipc->setSharpMask(sharpMask); - ipc->endUpdateParams (rtengine::EvShrEnabled); + ipc->endUpdateParams (ipc->setSharpMask(sharpMask)); } int ToolPanelCoordinator::getSpotWBRectSize() const From e4b955523e7a46882bd1982c962cfe2bc9e72467 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 15 Aug 2019 23:23:28 +0200 Subject: [PATCH 116/222] Capture sharpening: small speedup --- rtengine/color.h | 58 ++++++++++++++++++++++++++++++++++++-- rtengine/rawimagesource.cc | 10 ++----- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/rtengine/color.h b/rtengine/color.h index 22a648634..7b198f284 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1806,9 +1806,37 @@ public: static inline void RGB2YCbCr(float R, float G, float B, float &Y, float &Cb, float &Cr) { Y = 0.2627f * R + 0.6780f * G + 0.0593f * B; - Cb = -0.2627f * R - 0.6780f * G + (1.f - 0.0593f) * B; - Cr = (1.f - 0.2627f) * R - 0.6780f * G - 0.0593f * B; + Cb = (1.f - 0.0593f) * B - (0.2627f * R + 0.6780f * G); + Cr = (1.f - 0.2627f) * R - (0.6780f * G + 0.0593f * B); + } + static inline void RGB2YCbCr(float* R, float* G, float* B, float* Y, float* Cb, float *Cr, float gamma, int W) { + gamma = 1.f / gamma; + int i = 0; +#ifdef __SSE2__ + const vfloat gammav = F2V(gamma); + const vfloat c1v = F2V(0.2627f); + const vfloat c2v = F2V(0.6780f); + const vfloat c3v = F2V(0.0593f); + const vfloat c4v = F2V(1.f - 0.0593f); + const vfloat c5v = F2V(1.f - 0.2627f); + for (; i < W - 3; i += 4) { + const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); + const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); + const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); + STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav)); + STVFU(Cb[i], c4v * Bv - (c1v * Rv + c2v * Gv)); + STVFU(Cr[i], c5v * Rv - (c2v * Gv + c3v * Bv)); + } +#endif + for (; i < W; ++i) { + const float r = std::max(R[i], 0.f); + const float g = std::max(G[i], 0.f); + const float b = std::max(B[i], 0.f); + Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); + Cb[i] = (1.f - 0.0593f) * b - (0.2627f * r + 0.6780f * g); + Cr[i] = (1.f - 0.2627f) * r - (0.6780f * g + 0.0593f * b); + } } static inline void YCbCr2RGB(float Y, float Cb, float Cr, float &R, float &G, float &B) { @@ -1816,6 +1844,32 @@ public: G = std::max(Y - (0.0593f / 0.6780f) * Cb - (0.2627f / 0.6780f) * Cr, 0.f); B = std::max(Y + Cb, 0.f); } + + static inline void YCbCr2RGB(float* Y, float* Cb, float* Cr, float* R, float* G, float* B, float gamma, int W) { + int i = 0; +#ifdef __SSE2__ + const vfloat gammav = F2V(gamma); + const vfloat c1v = F2V(0.0593f / 0.6780f); + const vfloat c2v = F2V(0.2627f / 0.6780f); + + for (; i < W - 3; i += 4) { + const vfloat Yv = pow_F(LVFU(Y[i]), gammav); + const vfloat Crv = LVFU(Cr[i]); + const vfloat Cbv = LVFU(Cb[i]); + STVFU(R[i], vmaxf(Yv + Crv, ZEROV)); + STVFU(G[i], vmaxf(Yv - c1v * Cbv - c2v * Crv, ZEROV)); + STVFU(B[i], vmaxf(Yv + Cbv, ZEROV)); + } +#endif + for (; i < W; ++i) { + const float y = pow_F(Y[i], gamma); + const float cr = Cr[i]; + const float cb = Cb[i]; + R[i] = std::max(y + cr, 0.f); + G[i] = std::max(y - (0.0593f / 0.6780f) * cb - (0.2627f / 0.6780f) * cr, 0.f); + B[i] = std::max(y + cb, 0.f); + } + } }; } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 96f161d9f..25beb6208 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -4998,10 +4998,7 @@ BENCHFUN #pragma omp parallel for for (int i = 0; i < H; ++i) { Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); - for (int j = 0; j < W; ++j) { - Color::RGB2YCbCr(std::max(red[i][j], 0.f), std::max(green[i][j], 0.f), std::max(blue[i][j], 0.f), Y[i][j], Cb[i][j], Cr[i][j]); - Y[i][j] = pow_F(Y[i][j], 1.f / gamma); - } + Color::RGB2YCbCr(red[i], green[i], blue[i], Y[i], Cb[i], Cr[i], gamma, W); } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); @@ -5015,10 +5012,7 @@ BENCHFUN StopWatch Stop2("Y2RGB"); #pragma omp parallel for for (int i = 0; i < H; ++i) { - for (int j = 0; j < W ; ++j) { - Y[i][j] = pow_F(Y[i][j], gamma); - Color::YCbCr2RGB(Y[i][j], Cb[i][j], Cr[i][j], red[i][j], green[i][j], blue[i][j]); - } + Color::YCbCr2RGB(Y[i], Cb[i], Cr[i], red[i], green[i], blue[i], gamma, W); } Stop2.stop(); } From 80c3eb6ac38b2092e68df0450faf5fe3ae72646b Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 16 Aug 2019 17:11:14 +0200 Subject: [PATCH 117/222] fix clang warnings on non SSE builds --- rtengine/amaze_demosaic_RT.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index 9db2caac5..47aa45c14 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -768,7 +768,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c //if both agree on interpolation direction, choose the one with strongest directional discrimination; //otherwise, choose the u/d and l/r difference fluctuation weights - if ((0.5 - varwt) * (0.5 - diffwt) > 0 && fabsf(0.5 - diffwt) < fabsf(0.5 - varwt)) { + if ((0.5f - varwt) * (0.5f - diffwt) > 0.f && fabsf(0.5f - diffwt) < fabsf(0.5f - varwt)) { hvwt[indx >> 1] = varwt; } else { hvwt[indx >> 1] = diffwt; @@ -1236,7 +1236,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c //first ask if one gets more directional discrimination from nearby B/R sites float pmwtalt = xdivf(pmwt[(indx - m1) >> 1] + pmwt[(indx + p1) >> 1] + pmwt[(indx - p1) >> 1] + pmwt[(indx + m1) >> 1], 2); - if (fabsf(0.5 - pmwt[indx1]) < fabsf(0.5 - pmwtalt)) { + if (fabsf(0.5f - pmwt[indx1]) < fabsf(0.5f - pmwtalt)) { pmwt[indx1] = pmwtalt; //a better result was obtained from the neighbours } @@ -1304,7 +1304,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c for (int cc = 12 + (FC(rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 12; cc += 2, indx += 2, indx1++) { - if (fabsf(0.5 - pmwt[indx >> 1]) < fabsf(0.5 - hvwt[indx >> 1]) ) { + if (fabsf(0.5f - pmwt[indx >> 1]) < fabsf(0.5f - hvwt[indx >> 1]) ) { continue; } From 8cb5ed4d0c05687a7bdb8bb675554de87d1c16b1 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 16 Aug 2019 17:12:20 +0200 Subject: [PATCH 118/222] Two changes suggested by @Floessie, #5404 --- rtengine/profilestore.cc | 6 +++--- rtgui/profilestorecombobox.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 7c3e94da3..776dd7caa 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -264,9 +264,9 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath int ProfileStore::findFolderId (const Glib::ustring &path) const { // initialization must have been done when calling this - for (std::vector::const_iterator i = folders.begin(); i != folders.end(); ++i) { - if (*i == path) { - return i - folders.begin(); + for (size_t i = 0; i < folders.size(); ++i) { + if (folders[i] == path) { + return i; } } diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index 3fd613cb0..ae84bd951 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -147,7 +147,7 @@ void ProfileStoreComboBox::updateProfileList () Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) const { - for (const auto iter : childs) { + for (const auto& iter : childs) { const Gtk::TreeModel::Row row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse_ = row[methodColumns.profileStoreEntry]; From 7b3c50bc315e865259945ed246ab08926439d440 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 17 Aug 2019 15:18:24 +0200 Subject: [PATCH 119/222] Capture sharpening: auto contrast threshold --- rtdata/languages/default | 1 + rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 18 ++++++--- rtengine/improccoordinator.h | 6 +++ rtengine/procparams.cc | 5 +++ rtengine/procparams.h | 1 + rtengine/rawimagesource.cc | 11 +++--- rtengine/rawimagesource.h | 2 +- rtengine/rtengine.h | 1 + rtengine/simpleprocess.cc | 2 +- rtengine/stdimagesource.h | 2 +- rtgui/paramsedited.cc | 8 +++- rtgui/paramsedited.h | 1 + rtgui/pdsharpening.cc | 72 +++++++++++++++++++++++++---------- rtgui/pdsharpening.h | 15 ++++---- rtgui/toolpanelcoord.cc | 1 + 16 files changed, 103 insertions(+), 45 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ba96a43cb..d891d8692 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -765,6 +765,7 @@ HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_CONTRAST;CAS - Contrast threshold +HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CAS - Auto threshold HISTORY_MSG_PDSHARPEN_GAMMA;CAS - Gamma HISTORY_MSG_PDSHARPEN_ITERATIONS;CAS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CAS - Radius diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 006fe59a6..46cbc28a6 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -182,7 +182,7 @@ public: return this; } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; - virtual void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) = 0; + virtual void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) = 0; }; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 29d56e79e..7d485fd19 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -121,6 +121,7 @@ ImProcCoordinator::ImProcCoordinator() : flatFieldAutoClipListener(nullptr), bayerAutoContrastListener(nullptr), xtransAutoContrastListener(nullptr), + pdSharpenAutoContrastListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), @@ -333,16 +334,21 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicContrast : params->raw.xtranssensor.dualDemosaicContrast; imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic - if (params->pdsharpening.enabled) { - imgsrc->captureSharpening(params->pdsharpening, sharpMask); - } if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) { - bayerAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); - } - if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) { + bayerAutoContrastListener->autoContrastChanged(contrastThreshold); + } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) { xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); } + if (params->pdsharpening.enabled) { + double pdSharpencontrastThreshold = params->pdsharpening.contrast; + imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold); + if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) { + pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold); + } + } + + // if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag todo |= M_INIT; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 0315bc180..ef1c52bc6 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -161,6 +161,7 @@ protected: FlatFieldAutoClipListener *flatFieldAutoClipListener; AutoContrastListener *bayerAutoContrastListener; AutoContrastListener *xtransAutoContrastListener; + AutoContrastListener *pdSharpenAutoContrastListener; FrameCountListener *frameCountListener; ImageTypeListener *imageTypeListener; @@ -363,6 +364,11 @@ public: xtransAutoContrastListener = acl; } + void setpdSharpenAutoContrastListener (AutoContrastListener* acl) override + { + pdSharpenAutoContrastListener = acl; + } + void setImageTypeListener (ImageTypeListener* itl) override { imageTypeListener = itl; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e1e66d99c..467f1446a 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), + autoContrast(false), blurradius(0.2), gamma(1.0), radius(0.5), @@ -1107,6 +1108,7 @@ bool SharpeningParams::operator ==(const SharpeningParams& other) const && radius == other.radius && amount == other.amount && threshold == other.threshold + && autoContrast == other.autoContrast && edgesonly == other.edgesonly && edges_radius == other.edges_radius && edges_tolerance == other.edges_tolerance @@ -2791,6 +2793,7 @@ void ProcParams::setDefaults() pdsharpening = {}; pdsharpening.contrast = 10.0; + pdsharpening.autoContrast = true; prsharpening.method = "rld"; pdsharpening.gamma = 1.35; pdsharpening.deconvradius = 0.75; @@ -3308,6 +3311,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Post demosaic sharpening saveToKeyfile(!pedited || pedited->pdsharpening.enabled, "PostDemosaicSharpening", "Enabled", pdsharpening.enabled, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.contrast, "PostDemosaicSharpening", "Contrast", pdsharpening.contrast, keyFile); + saveToKeyfile(!pedited || pedited->pdsharpening.autoContrast, "PostDemosaicSharpening", "AutoContrast", pdsharpening.autoContrast, 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.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); @@ -4395,6 +4399,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("PostDemosaicSharpening")) { assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Enabled", pedited, pdsharpening.enabled, pedited->pdsharpening.enabled); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pedited, pdsharpening.contrast, pedited->pdsharpening.contrast); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoContrast", pedited, pdsharpening.autoContrast, pedited->pdsharpening.autoContrast); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvGamma", pedited, pdsharpening.gamma, pedited->pdsharpening.gamma); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index f9255f815..83b6c3e44 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -493,6 +493,7 @@ struct ColorToningParams { struct SharpeningParams { bool enabled; double contrast; + bool autoContrast; double blurradius; double gamma; double radius; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 25beb6208..d84c0436a 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -4953,7 +4953,7 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int } } -void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) { +void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { BENCHFUN const float xyz_rgb[3][3] = { // XYZ from RGB @@ -4962,7 +4962,7 @@ BENCHFUN { 0.019334, 0.119193, 0.950227 } }; - float contrast = sharpeningParams.contrast / 100.f; + float contrast = conrastThreshold / 100.f; if (showMask) { StopWatch Stop1("Show mask"); @@ -4975,8 +4975,8 @@ BENCHFUN Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); } array2D& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask - buildBlendMask(L, blend, W, H, contrast, 1.f); - + buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + conrastThreshold = contrast * 100.f; #ifdef _OPENMP #pragma omp parallel for #endif @@ -5002,7 +5002,8 @@ BENCHFUN } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(L, blend, W, H, contrast, 1.f); + buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + conrastThreshold = contrast * 100.f; Stop1.stop(); array2D& tmp = L; // L is not used anymore now => we can use its buffer as the needed temporary buffer diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index a7aee0843..8cf6b08a9 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -305,7 +305,7 @@ protected: void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; - void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) override; + void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override; }; } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index ca4cebe2e..86e9ade75 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -523,6 +523,7 @@ public: virtual void setFrameCountListener (FrameCountListener* l) = 0; virtual void setBayerAutoContrastListener (AutoContrastListener* l) = 0; virtual void setXtransAutoContrastListener (AutoContrastListener* l) = 0; + virtual void setpdSharpenAutoContrastListener (AutoContrastListener* l) = 0; virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoWBListener (AutoWBListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 24a3f3263..0524734e0 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -222,7 +222,7 @@ private: imgsrc->demosaic (params.raw, autoContrast, contrastThreshold); if (params.pdsharpening.enabled) { - imgsrc->captureSharpening(params.pdsharpening, false); + imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast); } diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 5acb8d113..175f664f8 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -102,7 +102,7 @@ public: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;} void flushRGB () override; - void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask) override {}; + void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override {}; }; } #endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index da65cbf8e..4029d0b9b 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -167,6 +167,7 @@ void ParamsEdited::set(bool v) sharpening.deconvdamping = v; pdsharpening.enabled = v; pdsharpening.contrast = v; + pdsharpening.autoContrast = v; pdsharpening.gamma = v; pdsharpening.deconvamount = v; pdsharpening.deconvradius = v; @@ -751,6 +752,7 @@ void ParamsEdited::initFrom(const std::vector& sharpening.deconvdamping = sharpening.deconvdamping && p.sharpening.deconvdamping == other.sharpening.deconvdamping; pdsharpening.enabled = pdsharpening.enabled && p.pdsharpening.enabled == other.pdsharpening.enabled; pdsharpening.contrast = pdsharpening.contrast && p.pdsharpening.contrast == other.pdsharpening.contrast; + pdsharpening.autoContrast = pdsharpening.autoContrast && p.pdsharpening.autoContrast == other.pdsharpening.autoContrast; pdsharpening.gamma = pdsharpening.gamma && p.pdsharpening.gamma == other.pdsharpening.gamma; pdsharpening.deconvradius = pdsharpening.deconvradius && p.pdsharpening.deconvradius == other.pdsharpening.deconvradius; pdsharpening.deconviter = pdsharpening.deconviter && p.pdsharpening.deconviter == other.pdsharpening.deconviter; @@ -1727,6 +1729,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.pdsharpening.contrast + mods.pdsharpening.contrast : mods.pdsharpening.contrast; } + if (pdsharpening.autoContrast) { + toEdit.pdsharpening.autoContrast = mods.pdsharpening.autoContrast; + } + if (pdsharpening.deconvamount) { toEdit.pdsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.pdsharpening.deconvamount + mods.pdsharpening.deconvamount : mods.pdsharpening.deconvamount; } @@ -3288,5 +3294,5 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool SharpeningParamsEdited::isUnchanged() const { - return enabled && contrast && gamma && deconvradius && deconviter; + return enabled && contrast && autoContrast && gamma && deconvradius && deconviter; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 5191bce56..6d229e689 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -179,6 +179,7 @@ struct SharpenMicroParamsEdited { struct SharpeningParamsEdited { bool enabled; bool contrast; + bool autoContrast; bool blurradius; bool gamma; bool radius; diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 896d416b5..43b32ce7e 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -20,6 +20,7 @@ #include "eventmapper.h" #include "pdsharpening.h" #include "options.h" +#include "../rtengine/procparams.h" using namespace rtengine; using namespace rtengine::procparams; @@ -32,11 +33,15 @@ PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PD EvPdSharpenGamma = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_GAMMA"); EvPdShrDRadius = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_RADIUS"); EvPdShrDIterations = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); + EvPdShrAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); hb->show (); contrast = Gtk::manage(new Adjuster (M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 10)); contrast->setAdjusterListener (this); + contrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP")); + contrast->setAutoValue(true); + pack_start(*contrast); contrast->show(); @@ -77,7 +82,7 @@ PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PD PdSharpening::~PdSharpening () { - + idle_register.destroy(); delete rld; } @@ -89,6 +94,7 @@ void PdSharpening::read (const ProcParams* pp, const ParamsEdited* pedited) if (pedited) { contrast->setEditedState (pedited->pdsharpening.contrast ? Edited : UnEdited); + contrast->setAutoInconsistent (multiImage && !pedited->pdsharpening.autoContrast); gamma->setEditedState (pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setEditedState (pedited->pdsharpening.deconvradius ? Edited : UnEdited); diter->setEditedState (pedited->pdsharpening.deconviter ? Edited : UnEdited); @@ -99,9 +105,11 @@ void PdSharpening::read (const ProcParams* pp, const ParamsEdited* pedited) setEnabled(pp->pdsharpening.enabled); contrast->setValue (pp->pdsharpening.contrast); + contrast->setAutoValue (pp->pdsharpening.autoContrast); gamma->setValue (pp->pdsharpening.gamma); dradius->setValue (pp->pdsharpening.deconvradius); diter->setValue (pp->pdsharpening.deconviter); + lastAutoContrast = pp->pdsharpening.autoContrast; enableListener (); } @@ -110,6 +118,7 @@ void PdSharpening::write (ProcParams* pp, ParamsEdited* pedited) { pp->pdsharpening.contrast = contrast->getValue (); + pp->pdsharpening.autoContrast = contrast->getAutoValue(); pp->pdsharpening.enabled = getEnabled (); pp->pdsharpening.gamma = gamma->getValue (); pp->pdsharpening.deconvradius = dradius->getValue (); @@ -117,6 +126,7 @@ void PdSharpening::write (ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->pdsharpening.contrast = contrast->getEditedState (); + pedited->pdsharpening.autoContrast = !contrast->getAutoInconsistent (); pedited->pdsharpening.gamma = gamma->getEditedState (); pedited->pdsharpening.deconvradius = dradius->getEditedState (); pedited->pdsharpening.deconviter = diter->getEditedState (); @@ -182,26 +192,6 @@ void PdSharpening::enabledChanged () } } -void PdSharpening::adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) -{ -} - -void PdSharpening::adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight) -{ -} - -void PdSharpening::adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop) -{ -} - -void PdSharpening::adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) -{ -} - -void PdSharpening::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) -{ -} - void PdSharpening::setBatchMode (bool batchMode) { @@ -232,3 +222,43 @@ void PdSharpening::trimValues (rtengine::procparams::ProcParams* pp) dradius->trimValue(pp->pdsharpening.deconvradius); diter->trimValue(pp->pdsharpening.deconviter); } + +void PdSharpening::autoContrastChanged (double autoContrast) +{ + idle_register.add( + [this, autoContrast]() -> bool + { + disableListener(); + contrast->setValue(autoContrast); + enableListener(); + return false; + } + ); +} + +void PdSharpening::adjusterAutoToggled(Adjuster* a, bool newval) +{ + if (multiImage) { + if (contrast->getAutoInconsistent()) { + contrast->setAutoInconsistent (false); + contrast->setAutoValue (false); + } else if (lastAutoContrast) { + contrast->setAutoInconsistent (true); + } + + lastAutoContrast = contrast->getAutoValue(); + } + + if (listener) { + + if (a == contrast) { + if (contrast->getAutoInconsistent()) { + listener->panelChanged (EvPdShrAutoContrast, M ("GENERAL_UNCHANGED")); + } else if (contrast->getAutoValue()) { + listener->panelChanged (EvPdShrAutoContrast, M ("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvPdShrAutoContrast, M ("GENERAL_DISABLED")); + } + } + } +} diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index fe9359349..af09a9b6b 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -20,10 +20,9 @@ #include #include "adjuster.h" -#include "thresholdadjuster.h" #include "toolpanel.h" -class PdSharpening : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel +class PdSharpening : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoContrastListener { protected: @@ -32,11 +31,14 @@ protected: Adjuster* dradius; Adjuster* diter; Gtk::VBox* rld; - + bool lastAutoContrast; rtengine::ProcEvent EvPdShrContrast; rtengine::ProcEvent EvPdShrDRadius; rtengine::ProcEvent EvPdSharpenGamma; rtengine::ProcEvent EvPdShrDIterations; + rtengine::ProcEvent EvPdShrAutoContrast; + IdleRegister idle_register; + public: PdSharpening (); @@ -47,14 +49,11 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void setBatchMode (bool batchMode) override; + void adjusterAutoToggled (Adjuster* a, bool newval) override; void adjusterChanged (Adjuster* a, double newval) override; void enabledChanged () override; - void adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop) override; - void adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight) override; - void adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop) override; - void adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) override; - void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) override; + void autoContrastChanged (double autoContrast) override; void setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd); void trimValues (rtengine::procparams::ProcParams* pp) override; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 93f45aefe..f64205219 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -572,6 +572,7 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool ipc->setFlatFieldAutoClipListener (flatfield); ipc->setBayerAutoContrastListener (bayerprocess); ipc->setXtransAutoContrastListener (xtransprocess); + ipc->setpdSharpenAutoContrastListener (pdSharpening); ipc->setAutoWBListener (whitebalance); ipc->setAutoColorTonListener (colortoning); ipc->setAutoChromaListener (dirpyrdenoise); From e2bfbbf9b146454b4cb6013f2e95ebfaa23a2211 Mon Sep 17 00:00:00 2001 From: Hombre Date: Sun, 18 Aug 2019 00:26:15 +0200 Subject: [PATCH 120/222] Bugfix: Edit button was not switched off when opening a new image Reported in issue #2239 : https://github.com/Beep6581/RawTherapee/issues/2239#issuecomment-521955110 --- rtgui/editorpanel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 1f8e83c3e..053586bca 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1090,8 +1090,8 @@ void EditorPanel::close () if (iareapanel) { iareapanel->imageArea->setPreviewHandler (nullptr); iareapanel->imageArea->setImProcCoordinator (nullptr); - iareapanel->imageArea->unsubscribe(); } + tpc->editModeSwitchedOff(); rtengine::StagedImageProcessor::destroy (ipc); ipc = nullptr; From f5a18f6248d0736ca1b4571a7b3966aa2deb0935 Mon Sep 17 00:00:00 2001 From: Hombre Date: Sun, 18 Aug 2019 01:54:31 +0200 Subject: [PATCH 121/222] Hovered edit object wasn't dragged if inside a red crop's rectangle Fix issue #5415 --- rtgui/cropwindow.cc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 5839a5edb..41c626015 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -404,6 +404,26 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) action_y = 0; needRedraw = true; } + } else if (iarea->getToolMode () == TMHand + && editSubscriber + && cropgl + && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) + && editSubscriber->getEditingType() == ET_OBJECTS + && iarea->getObject() >= 0 + ) + { + needRedraw = editSubscriber->button1Pressed(bstate); + if (editSubscriber->isDragging()) { + state = SEditDrag1; + } else if (editSubscriber->isPicking()) { + state = SEditPick1; + pickedObject = iarea->getObject(); + pickModifierKey = bstate; + } + press_x = x; + press_y = y; + action_x = 0; + action_y = 0; } else if (onArea (CropTopLeft, x, y)) { state = SResizeTL; press_x = x; @@ -477,7 +497,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) cropgl->cropInit (cropHandler.cropParams->x, cropHandler.cropParams->y, cropHandler.cropParams->w, cropHandler.cropParams->h); } else if (iarea->getToolMode () == TMHand) { if (editSubscriber) { - if ((cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType() == ET_PIPETTE && (bstate & GDK_CONTROL_MASK))) || editSubscriber->getEditingType() == ET_OBJECTS) { + if ((cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && editSubscriber->getEditingType() == ET_PIPETTE && (bstate & GDK_CONTROL_MASK))) { needRedraw = editSubscriber->button1Pressed(bstate); if (editSubscriber->isDragging()) { state = SEditDrag1; @@ -492,7 +512,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) action_y = 0; } } - if (state != SEditDrag1) { + if (state != SEditDrag1 && state != SEditPick1) { state = SCropImgMove; press_x = x; press_y = y; From ee38731328e3b4868650b5eb3a88779a6935998b Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 18 Aug 2019 10:44:59 +0200 Subject: [PATCH 122/222] fixes #5416 --- rtgui/filebrowser.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 88220a688..f60e47518 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -1502,8 +1502,8 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) const // true -> std::transform(FileName.begin(), FileName.end(), FileName.begin(), ::toupper); int iFilenameMatch = 0; - for (const auto& filter : filter.vFilterStrings) { - if (FileName.find(filter) != std::string::npos) { + for (const auto& filterString : filter.vFilterStrings) { + if (FileName.find(filterString) != std::string::npos) { ++iFilenameMatch; break; } From ce3ca966f6c8a5e11cd7a4cbeecf40a505a46d22 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 18 Aug 2019 11:16:53 +0200 Subject: [PATCH 123/222] Capture sharpening: some cleanups --- rtengine/rawimagesource.cc | 9 +- rtgui/batchtoolpanelcoord.cc | 1 + rtgui/pdsharpening.cc | 207 ++++++++++++++++------------------- rtgui/pdsharpening.h | 21 ++-- 4 files changed, 113 insertions(+), 125 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index d84c0436a..ed0fac707 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -4992,13 +4992,14 @@ BENCHFUN array2D& Y = red; // red will be overridden anyway => we can use its buffer to store Y array2D& Cb = green; // green will be overridden anyway => we can use its buffer to store Cb array2D& Cr = blue; // blue will be overridden anyway => we can use its buffer to store Cr - const float gamma = sharpeningParams.gamma; StopWatch Stop1("rgb2Y"); +#ifdef _OPENMP #pragma omp parallel for +#endif for (int i = 0; i < H; ++i) { Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); - Color::RGB2YCbCr(red[i], green[i], blue[i], Y[i], Cb[i], Cr[i], gamma, W); + Color::RGB2YCbCr(red[i], green[i], blue[i], Y[i], Cb[i], Cr[i], sharpeningParams.gamma, W); } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); @@ -5011,9 +5012,11 @@ BENCHFUN ImProcFunctions ipf(&dummy); ipf.deconvsharpening(Y, tmp, blend, W, H, sharpeningParams, 1.0); StopWatch Stop2("Y2RGB"); +#ifdef _OPENMP #pragma omp parallel for +#endif for (int i = 0; i < H; ++i) { - Color::YCbCr2RGB(Y[i], Cb[i], Cr[i], red[i], green[i], blue[i], gamma, W); + Color::YCbCr2RGB(Y[i], Cb[i], Cr[i], red[i], green[i], blue[i], sharpeningParams.gamma, W); } Stop2.stop(); } diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 1a0eaeb28..62867996e 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -152,6 +152,7 @@ void BatchToolPanelCoordinator::initSession () cacorrection->setAdjusterBehavior (false); sharpening->setAdjusterBehavior (false, false, false, false, false, false, false); prsharpening->setAdjusterBehavior (false, false, false, false, false, false, false); + pdSharpening->setAdjusterBehavior (false, false, false, false); sharpenEdge->setAdjusterBehavior (false, false); sharpenMicro->setAdjusterBehavior (false, false, false); epd->setAdjusterBehavior (false, false, false, false, false); diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 43b32ce7e..1151684e7 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -1,7 +1,7 @@ /* * This file is part of RawTherapee. * - * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2019 Ingo Weyrich (heckflosse67@gmx.de) * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ +*/ + #include #include "eventmapper.h" #include "pdsharpening.h" @@ -25,7 +26,7 @@ using namespace rtengine; using namespace rtengine::procparams; -PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PDSHARPENING_LABEL"), false, true) +PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDSHARPENING_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); @@ -35,177 +36,164 @@ PdSharpening::PdSharpening () : FoldableToolPanel(this, "pdsharpening", M("TP_PD EvPdShrDIterations = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); EvPdShrAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); - Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); - hb->show (); - contrast = Gtk::manage(new Adjuster (M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 10)); - contrast->setAdjusterListener (this); + Gtk::HBox* hb = Gtk::manage(new Gtk::HBox()); + hb->show(); + contrast = Gtk::manage(new Adjuster(M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 10)); + contrast->setAdjusterListener(this); contrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP")); contrast->setAutoValue(true); pack_start(*contrast); contrast->show(); - pack_start (*hb); + pack_start(*hb); - rld = new Gtk::VBox (); - gamma = Gtk::manage (new Adjuster (M("TP_SHARPENING_GAMMA"), 0.5, 3.0, 0.05, 1.35)); - dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.75)); - diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); - rld->pack_start (*gamma); - rld->pack_start (*dradius); - rld->pack_start (*diter); + Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); + gamma = Gtk::manage(new Adjuster(M("TP_SHARPENING_GAMMA"), 0.5, 3.0, 0.05, 1.35)); + dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.75)); + diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + rld->pack_start(*gamma); + rld->pack_start(*dradius); + rld->pack_start(*diter); gamma->show(); - dradius->show (); - diter->show (); - rld->show (); + dradius->show(); + diter->show(); + rld->show(); pack_start(*rld); - dradius->setAdjusterListener (this); - gamma->setAdjusterListener (this); - diter->setAdjusterListener (this); + dradius->setAdjusterListener(this); + gamma->setAdjusterListener(this); + diter->setAdjusterListener(this); - if (contrast->delay < options.adjusterMaxDelay) { - contrast->delay = options.adjusterMaxDelay; - } - if (dradius->delay < options.adjusterMaxDelay) { - dradius->delay = options.adjusterMaxDelay; - } - if (gamma->delay < options.adjusterMaxDelay) { - gamma->delay = options.adjusterMaxDelay; - } - if (diter->delay < options.adjusterMaxDelay) { - diter->delay = options.adjusterMaxDelay; - } - - rld->reference(); + contrast->delay = std::max(contrast->delay, options.adjusterMaxDelay); + dradius->delay = std::max(dradius->delay, options.adjusterMaxDelay); + gamma->delay = std::max(gamma->delay, options.adjusterMaxDelay); + diter->delay = std::max(diter->delay, options.adjusterMaxDelay); } -PdSharpening::~PdSharpening () +PdSharpening::~PdSharpening() { idle_register.destroy(); - delete rld; } -void PdSharpening::read (const ProcParams* pp, const ParamsEdited* pedited) +void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) { - disableListener (); + disableListener(); if (pedited) { - contrast->setEditedState (pedited->pdsharpening.contrast ? Edited : UnEdited); - contrast->setAutoInconsistent (multiImage && !pedited->pdsharpening.autoContrast); - gamma->setEditedState (pedited->pdsharpening.gamma ? Edited : UnEdited); - dradius->setEditedState (pedited->pdsharpening.deconvradius ? Edited : UnEdited); - diter->setEditedState (pedited->pdsharpening.deconviter ? Edited : UnEdited); + contrast->setEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); + contrast->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoContrast); + gamma->setEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); + dradius->setEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); + diter->setEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); - set_inconsistent (multiImage && !pedited->pdsharpening.enabled); + set_inconsistent(multiImage && !pedited->pdsharpening.enabled); } setEnabled(pp->pdsharpening.enabled); - contrast->setValue (pp->pdsharpening.contrast); - contrast->setAutoValue (pp->pdsharpening.autoContrast); - gamma->setValue (pp->pdsharpening.gamma); - dradius->setValue (pp->pdsharpening.deconvradius); - diter->setValue (pp->pdsharpening.deconviter); + contrast->setValue(pp->pdsharpening.contrast); + contrast->setAutoValue(pp->pdsharpening.autoContrast); + gamma->setValue(pp->pdsharpening.gamma); + dradius->setValue(pp->pdsharpening.deconvradius); + diter->setValue(pp->pdsharpening.deconviter); lastAutoContrast = pp->pdsharpening.autoContrast; - enableListener (); + enableListener(); } -void PdSharpening::write (ProcParams* pp, ParamsEdited* pedited) +void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) { - pp->pdsharpening.contrast = contrast->getValue (); + pp->pdsharpening.contrast = contrast->getValue(); pp->pdsharpening.autoContrast = contrast->getAutoValue(); - pp->pdsharpening.enabled = getEnabled (); - pp->pdsharpening.gamma = gamma->getValue (); - pp->pdsharpening.deconvradius = dradius->getValue (); - pp->pdsharpening.deconviter = (int)diter->getValue (); + pp->pdsharpening.enabled = getEnabled(); + pp->pdsharpening.gamma = gamma->getValue(); + pp->pdsharpening.deconvradius = dradius->getValue(); + pp->pdsharpening.deconviter =(int)diter->getValue(); if (pedited) { - pedited->pdsharpening.contrast = contrast->getEditedState (); - pedited->pdsharpening.autoContrast = !contrast->getAutoInconsistent (); - pedited->pdsharpening.gamma = gamma->getEditedState (); - pedited->pdsharpening.deconvradius = dradius->getEditedState (); - pedited->pdsharpening.deconviter = diter->getEditedState (); - pedited->pdsharpening.enabled = !get_inconsistent(); + pedited->pdsharpening.contrast = contrast->getEditedState(); + pedited->pdsharpening.autoContrast = !contrast->getAutoInconsistent(); + pedited->pdsharpening.gamma = gamma->getEditedState(); + pedited->pdsharpening.deconvradius = dradius->getEditedState(); + pedited->pdsharpening.deconviter = diter->getEditedState(); + pedited->pdsharpening.enabled = !get_inconsistent(); } } -void PdSharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +void PdSharpening::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { - contrast->setDefault (defParams->pdsharpening.contrast); - gamma->setDefault (defParams->pdsharpening.gamma); - dradius->setDefault (defParams->pdsharpening.deconvradius); - diter->setDefault (defParams->pdsharpening.deconviter); + contrast->setDefault(defParams->pdsharpening.contrast); + gamma->setDefault(defParams->pdsharpening.gamma); + dradius->setDefault(defParams->pdsharpening.deconvradius); + 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); - diter->setDefaultEditedState (pedited->pdsharpening.deconviter ? Edited : UnEdited); + contrast->setDefaultEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); + gamma->setDefaultEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); + dradius->setDefaultEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); + diter->setDefaultEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); } else { - contrast->setDefaultEditedState (Irrelevant); - gamma->setDefaultEditedState (Irrelevant); - dradius->setDefaultEditedState (Irrelevant); - diter->setDefaultEditedState (Irrelevant); + contrast->setDefaultEditedState(Irrelevant); + gamma->setDefaultEditedState(Irrelevant); + dradius->setDefaultEditedState(Irrelevant); + diter->setDefaultEditedState(Irrelevant); } } -void PdSharpening::adjusterChanged (Adjuster* a, double newval) +void PdSharpening::adjusterChanged(Adjuster* a, double newval) { - if (listener && (multiImage || getEnabled()) ) { + if (listener && (multiImage || getEnabled())) { Glib::ustring costr; if (a == gamma || a == dradius) { - costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else { - costr = Glib::ustring::format ((int)a->getValue()); + costr = Glib::ustring::format((int)a->getValue()); } if (a == contrast) { - listener->panelChanged (EvPdShrContrast, costr); + listener->panelChanged(EvPdShrContrast, costr); } else if (a == gamma) { - listener->panelChanged (EvPdSharpenGamma, costr); + listener->panelChanged(EvPdSharpenGamma, costr); } else if (a == dradius) { - listener->panelChanged (EvPdShrDRadius, costr); + listener->panelChanged(EvPdShrDRadius, costr); } else if (a == diter) { - listener->panelChanged (EvPdShrDIterations, costr); + listener->panelChanged(EvPdShrDIterations, costr); } } } -void PdSharpening::enabledChanged () +void PdSharpening::enabledChanged() { if (listener) { if (get_inconsistent()) { - listener->panelChanged (EvPdShrEnabled, M("GENERAL_UNCHANGED")); + listener->panelChanged(EvPdShrEnabled, M("GENERAL_UNCHANGED")); } else if (getEnabled()) { - listener->panelChanged (EvPdShrEnabled, M("GENERAL_ENABLED")); + listener->panelChanged(EvPdShrEnabled, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvPdShrEnabled, M("GENERAL_DISABLED")); + listener->panelChanged(EvPdShrEnabled, M("GENERAL_DISABLED")); } } } -void PdSharpening::setBatchMode (bool batchMode) +void PdSharpening::setBatchMode(bool batchMode) { - ToolPanel::setBatchMode (batchMode); + ToolPanel::setBatchMode(batchMode); -// pack_start (*rld); - - contrast->showEditedCB (); - gamma->showEditedCB (); - dradius->showEditedCB (); - diter->showEditedCB (); + contrast->showEditedCB(); + gamma->showEditedCB(); + dradius->showEditedCB(); + diter->showEditedCB(); } -void PdSharpening::setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd) +void PdSharpening::setAdjusterBehavior(bool contrastadd, bool gammaadd, bool radiusadd, bool iteradd) { contrast->setAddMode(contrastadd); @@ -214,7 +202,7 @@ void PdSharpening::setAdjusterBehavior (bool contrastadd, bool gammaadd, bool ra diter->setAddMode(iteradd); } -void PdSharpening::trimValues (rtengine::procparams::ProcParams* pp) +void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) { contrast->trimValue(pp->pdsharpening.contrast); @@ -223,7 +211,7 @@ void PdSharpening::trimValues (rtengine::procparams::ProcParams* pp) diter->trimValue(pp->pdsharpening.deconviter); } -void PdSharpening::autoContrastChanged (double autoContrast) +void PdSharpening::autoContrastChanged(double autoContrast) { idle_register.add( [this, autoContrast]() -> bool @@ -240,25 +228,22 @@ void PdSharpening::adjusterAutoToggled(Adjuster* a, bool newval) { if (multiImage) { if (contrast->getAutoInconsistent()) { - contrast->setAutoInconsistent (false); - contrast->setAutoValue (false); + contrast->setAutoInconsistent(false); + contrast->setAutoValue(false); } else if (lastAutoContrast) { - contrast->setAutoInconsistent (true); + contrast->setAutoInconsistent(true); } lastAutoContrast = contrast->getAutoValue(); } if (listener) { - - if (a == contrast) { - if (contrast->getAutoInconsistent()) { - listener->panelChanged (EvPdShrAutoContrast, M ("GENERAL_UNCHANGED")); - } else if (contrast->getAutoValue()) { - listener->panelChanged (EvPdShrAutoContrast, M ("GENERAL_ENABLED")); - } else { - listener->panelChanged (EvPdShrAutoContrast, M ("GENERAL_DISABLED")); - } + if (contrast->getAutoInconsistent()) { + listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_UNCHANGED")); + } else if (contrast->getAutoValue()) { + listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_DISABLED")); } } } diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index af09a9b6b..b2f7b6e57 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -15,14 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ +*/ #pragma once -#include #include "adjuster.h" #include "toolpanel.h" -class PdSharpening : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoContrastListener +class PdSharpening final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoContrastListener { protected: @@ -30,7 +29,7 @@ protected: Adjuster* gamma; Adjuster* dradius; Adjuster* diter; - Gtk::VBox* rld; + bool lastAutoContrast; rtengine::ProcEvent EvPdShrContrast; rtengine::ProcEvent EvPdShrDRadius; @@ -44,17 +43,17 @@ public: PdSharpening (); ~PdSharpening () override; - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; - void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; - void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; - void setBatchMode (bool batchMode) override; + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void setBatchMode (bool batchMode) override; void adjusterAutoToggled (Adjuster* a, bool newval) override; void adjusterChanged (Adjuster* a, double newval) override; - void enabledChanged () override; + void enabledChanged () override; void autoContrastChanged (double autoContrast) override; - void setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd); - void trimValues (rtengine::procparams::ProcParams* pp) override; + void setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool iteradds); + void trimValues (rtengine::procparams::ProcParams* pp) override; }; From 8bb88073fa1fd59ec9723a521a7a890838520f75 Mon Sep 17 00:00:00 2001 From: Hombre Date: Sun, 18 Aug 2019 17:12:37 +0200 Subject: [PATCH 124/222] Fixing object precedence in getCursor as well + resize of the "catching spot" of the Gradient widget (30 -> 12) --- rtgui/cropwindow.cc | 2 ++ rtgui/gradient.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 41c626015..a170ec04d 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -1276,6 +1276,8 @@ void CropWindow::updateCursor (int x, int y) newType = CSArrow; } else if (onArea (CropToolBar, x, y)) { newType = CSMove; + } else if (iarea->getObject() > -1 && editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) { + newType = editSubscriber->getCursor(iarea->getObject()); } else if (onArea (CropResize, x, y)) { newType = CSResizeDiagonal; } else if (tm == TMColorPicker && hoveredPicker) { diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index 3f13dfe4d..4f389e112 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -93,7 +93,7 @@ Gradient::Gradient () : FoldableToolPanel(this, "gradient", M("TP_GRADIENT_LABEL centerCircle = new Circle(); centerCircle->datum = Geometry::IMAGE; centerCircle->radiusInImageSpace = false; - centerCircle->radius = 30; + centerCircle->radius = 12; centerCircle->filled = true; EditSubscriber::mouseOverGeometry.push_back( hLine ); From 6b12f299e698be8e26efd30f8594afb56bf00d6a Mon Sep 17 00:00:00 2001 From: Hombre Date: Sun, 18 Aug 2019 18:20:32 +0200 Subject: [PATCH 125/222] On preview widgets for main crop window is now clipped to avoid drawing on the whole window. Fix issue #5418 --- rtgui/cropwindow.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 5839a5edb..72d2500ba 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -1845,11 +1845,9 @@ void CropWindow::expose (Cairo::RefPtr cr) EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS && bufferCreated()) { - if (this != iarea->mainCropWindow) { - cr->set_line_width (0.); - cr->rectangle (x + imgAreaX, y + imgAreaY, imgAreaW, imgAreaH); - cr->clip(); - } + cr->set_line_width (0.); + cr->rectangle (x + imgAreaX, y + imgAreaY, imgAreaW, imgAreaH); + cr->clip(); // drawing Subscriber's visible geometry const std::vector visibleGeom = editSubscriber->getVisibleGeometry(); From 3a538b9b836761d5188d0d0e6fa131354db0fec1 Mon Sep 17 00:00:00 2001 From: Hombre Date: Mon, 19 Aug 2019 20:17:09 +0200 Subject: [PATCH 126/222] RT was crashing when exiting with On Preview Widget displayed see issue #5419 --- rtgui/editorpanel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 053586bca..e0cc8fd92 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1090,8 +1090,8 @@ void EditorPanel::close () if (iareapanel) { iareapanel->imageArea->setPreviewHandler (nullptr); iareapanel->imageArea->setImProcCoordinator (nullptr); + tpc->editModeSwitchedOff(); } - tpc->editModeSwitchedOff(); rtengine::StagedImageProcessor::destroy (ipc); ipc = nullptr; From dab39dae76888c71b05e3cfdd382a71f8848f33a Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 19 Aug 2019 21:17:25 +0200 Subject: [PATCH 127/222] Capture Sharpening: avoid hue shift --- rtengine/color.cc | 16 ++++++++-------- rtengine/color.h | 36 ++++++++++++++++++++++++------------ rtengine/rawimagesource.cc | 25 ++++++++++++++++++------- rtengine/rt_algo.cc | 8 ++++---- rtengine/rt_algo.h | 2 +- rtgui/pdsharpening.cc | 2 +- 6 files changed, 56 insertions(+), 33 deletions(-) diff --git a/rtengine/color.cc b/rtengine/color.cc index 7c12c0ca5..26c2cf7c9 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -1835,21 +1835,21 @@ void Color::RGB2L(float *R, float *G, float *B, float *L, const float wp[3][3], { #ifdef __SSE2__ - vfloat minvalfv = F2V(0.f); - vfloat maxvalfv = F2V(MAXVALF); + const vfloat maxvalfv = F2V(MAXVALF); + const vfloat rmv = F2V(wp[1][0]); + const vfloat gmv = F2V(wp[1][1]); + const vfloat bmv = F2V(wp[1][2]); #endif int i = 0; #ifdef __SSE2__ - for(;i < width - 3; i+=4) { + for(; i < width - 3; i+=4) { const vfloat rv = LVFU(R[i]); const vfloat gv = LVFU(G[i]); const vfloat bv = LVFU(B[i]); - const vfloat yv = F2V(wp[1][0]) * rv + F2V(wp[1][1]) * gv + F2V(wp[1][2]) * bv; + const vfloat yv = rmv * rv + gmv * gv + bmv * bv; - vmask maxMask = vmaskf_gt(yv, maxvalfv); - vmask minMask = vmaskf_lt(yv, minvalfv); - if (_mm_movemask_ps((vfloat)vorm(maxMask, minMask))) { + if (_mm_movemask_ps((vfloat)vorm(vmaskf_gt(yv, maxvalfv), vmaskf_lt(yv, ZEROV)))) { // take slower code path for all 4 pixels if one of the values is > MAXVALF. Still faster than non SSE2 version for(int k = 0; k < 4; ++k) { float y = yv[k]; @@ -1860,7 +1860,7 @@ void Color::RGB2L(float *R, float *G, float *B, float *L, const float wp[3][3], } } #endif - for(;i < width; ++i) { + for(; i < width; ++i) { const float rv = R[i]; const float gv = G[i]; const float bv = B[i]; diff --git a/rtengine/color.h b/rtengine/color.h index 7b198f284..7cc7368b3 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1804,12 +1804,6 @@ public: return (hr); } - static inline void RGB2YCbCr(float R, float G, float B, float &Y, float &Cb, float &Cr) { - Y = 0.2627f * R + 0.6780f * G + 0.0593f * B; - Cb = (1.f - 0.0593f) * B - (0.2627f * R + 0.6780f * G); - Cr = (1.f - 0.2627f) * R - (0.6780f * G + 0.0593f * B); - } - static inline void RGB2YCbCr(float* R, float* G, float* B, float* Y, float* Cb, float *Cr, float gamma, int W) { gamma = 1.f / gamma; int i = 0; @@ -1839,12 +1833,6 @@ public: } } - static inline void YCbCr2RGB(float Y, float Cb, float Cr, float &R, float &G, float &B) { - R = std::max(Y + Cr, 0.f); - G = std::max(Y - (0.0593f / 0.6780f) * Cb - (0.2627f / 0.6780f) * Cr, 0.f); - B = std::max(Y + Cb, 0.f); - } - static inline void YCbCr2RGB(float* Y, float* Cb, float* Cr, float* R, float* G, float* B, float gamma, int W) { int i = 0; #ifdef __SSE2__ @@ -1870,6 +1858,30 @@ public: B[i] = std::max(y + cb, 0.f); } } + + static inline void RGB2Y(float* R, float* G, float* B, float* Y, float gamma, int W) { + gamma = 1.f / gamma; + int i = 0; +#ifdef __SSE2__ + const vfloat gammav = F2V(gamma); + const vfloat c1v = F2V(0.2627f); + const vfloat c2v = F2V(0.6780f); + const vfloat c3v = F2V(0.0593f); + for (; i < W - 3; i += 4) { + const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); + const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); + const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); + STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav)); + } +#endif + for (; i < W; ++i) { + const float r = std::max(R[i], 0.f); + const float g = std::max(G[i], 0.f); + const float b = std::max(B[i], 0.f); + Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); + } + } + }; } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 050b62692..d947d4195 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -4987,17 +4987,22 @@ BENCHFUN } array2D L(W,H); - array2D& Y = red; // red will be overridden anyway => we can use its buffer to store Y - array2D& Cb = green; // green will be overridden anyway => we can use its buffer to store Cb - array2D& Cr = blue; // blue will be overridden anyway => we can use its buffer to store Cr + array2D YOld(W,H); + array2D YNew(W,H); +// array2D& Y = red; // red will be overridden anyway => we can use its buffer to store Y +// array2D& Cb = green; // green will be overridden anyway => we can use its buffer to store Cb +// array2D& Cr = blue; // blue will be overridden anyway => we can use its buffer to store Cr StopWatch Stop1("rgb2Y"); #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < H; ++i) { Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); - Color::RGB2YCbCr(red[i], green[i], blue[i], Y[i], Cb[i], Cr[i], sharpeningParams.gamma, W); + Color::RGB2Y(red[i], green[i], blue[i], YOld[i], sharpeningParams.gamma, W); + for (int j = 0; j < W; ++j) { + YNew[i][j] = YOld[i][j]; + } } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); @@ -5008,13 +5013,19 @@ BENCHFUN array2D& tmp = L; // L is not used anymore now => we can use its buffer as the needed temporary buffer ProcParams dummy; ImProcFunctions ipf(&dummy); - ipf.deconvsharpening(Y, tmp, blend, W, H, sharpeningParams, 1.0); + ipf.deconvsharpening(YNew, tmp, blend, W, H, sharpeningParams, 1.0); StopWatch Stop2("Y2RGB"); + const float gamma = sharpeningParams.gamma; #ifdef _OPENMP #pragma omp parallel for #endif for (int i = 0; i < H; ++i) { - Color::YCbCr2RGB(Y[i], Cb[i], Cr[i], red[i], green[i], blue[i], sharpeningParams.gamma, W); + for (int j = 0; j < W; ++j) { + const float factor = pow_F(YNew[i][j] / (YOld[i][j] == 0.f ? 0.00001f : YOld[i][j]), gamma); + red[i][j] *= factor; + green[i][j] *= factor; + blue[i][j] *= factor; + } } Stop2.stop(); } diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc index 1011ae7b7..97c44dfc1 100644 --- a/rtengine/rt_algo.cc +++ b/rtengine/rt_algo.cc @@ -52,7 +52,7 @@ vfloat calcBlendFactor(vfloat valv, vfloat thresholdv) { } #endif -float tileAverage(float **data, size_t tileY, size_t tileX, size_t tilesize) { +float tileAverage(const float * const *data, size_t tileY, size_t tileX, size_t tilesize) { float avg = 0.f; #ifdef __SSE2__ @@ -75,7 +75,7 @@ float tileAverage(float **data, size_t tileY, size_t tileX, size_t tilesize) { return avg / rtengine::SQR(tilesize); } -float tileVariance(float **data, size_t tileY, size_t tileX, size_t tilesize, float avg) { +float tileVariance(const float * const *data, size_t tileY, size_t tileX, size_t tilesize, float avg) { float var = 0.f; #ifdef __SSE2__ @@ -99,7 +99,7 @@ float tileVariance(float **data, size_t tileY, size_t tileX, size_t tilesize, fl return var / (rtengine::SQR(tilesize) * avg); } -float calcContrastThreshold(float** luminance, int tileY, int tileX, int tilesize) { +float calcContrastThreshold(const float* const * luminance, int tileY, int tileX, int tilesize) { constexpr float scale = 0.0625f / 327.68f; std::vector> blend(tilesize - 4, std::vector(tilesize - 4)); @@ -299,7 +299,7 @@ void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& maxOut = rtengine::LIM(maxOut, minVal, maxVal); } -void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast) { +void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast) { if (autoContrast) { constexpr float minLuminance = 2000.f; diff --git a/rtengine/rt_algo.h b/rtengine/rt_algo.h index a8e2e3e23..a13f3cb8e 100644 --- a/rtengine/rt_algo.h +++ b/rtengine/rt_algo.h @@ -24,5 +24,5 @@ namespace rtengine { void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true); -void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false); +void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false); } diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 1151684e7..7a428806f 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -49,7 +49,7 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS pack_start(*hb); Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); - gamma = Gtk::manage(new Adjuster(M("TP_SHARPENING_GAMMA"), 0.5, 3.0, 0.05, 1.35)); + gamma = Gtk::manage(new Adjuster(M("TP_SHARPENING_GAMMA"), 0.5, 6.0, 0.05, 1.35)); dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.75)); diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); rld->pack_start(*gamma); From b6d333ee72dcae2b57a7048a367933be8e89d9bf Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 20 Aug 2019 00:32:37 +0200 Subject: [PATCH 128/222] "Allow upscaling" in Resize tool wasn't displayed with Scale method (no issue) --- rtgui/resize.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 3789d4693..0525d64af 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -91,14 +91,13 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals sbox->pack_start (*hbox); sizeBox->pack_start (*sbox, Gtk::PACK_SHRINK, 0); - - allowUpscaling = Gtk::manage(new Gtk::CheckButton(M("TP_RESIZE_ALLOW_UPSCALING"))); - sizeBox->pack_start(*allowUpscaling); - allowUpscaling->signal_toggled().connect(sigc::mem_fun(*this, &Resize::allowUpscalingChanged)); - sizeBox->show_all (); sizeBox->reference (); + allowUpscaling = Gtk::manage(new Gtk::CheckButton(M("TP_RESIZE_ALLOW_UPSCALING"))); + pack_start(*allowUpscaling); + allowUpscaling->signal_toggled().connect(sigc::mem_fun(*this, &Resize::allowUpscalingChanged)); + w->set_digits (0); w->set_increments (1, 100); w->set_value (800); @@ -572,11 +571,13 @@ void Resize::updateGUI () case (0): // Scale mode pack_start (*scale, Gtk::PACK_SHRINK, 4); + reorder_child(*allowUpscaling, 4); break; case (1): // Width mode pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + reorder_child(*allowUpscaling, 4); w->set_sensitive (true); h->set_sensitive (false); break; @@ -584,6 +585,7 @@ void Resize::updateGUI () case (2): // Height mode pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + reorder_child(*allowUpscaling, 4); w->set_sensitive (false); h->set_sensitive (true); break; @@ -591,6 +593,7 @@ void Resize::updateGUI () case (3): // Bounding box mode pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + reorder_child(*allowUpscaling, 4); w->set_sensitive (true); h->set_sensitive (true); break; From 0c1caf6c3658f8230eb16d0e1ba4ccac892463eb Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 20 Aug 2019 18:41:06 +0200 Subject: [PATCH 129/222] capture sharpening: further improvements and speedups --- rtengine/color.h | 25 ++++ rtengine/gauss.cc | 269 ++++++++++++++++++++++++++++++++++++- rtengine/improcfun.h | 2 +- rtengine/ipsharpen.cc | 2 +- rtengine/rawimagesource.cc | 27 ++-- 5 files changed, 307 insertions(+), 18 deletions(-) diff --git a/rtengine/color.h b/rtengine/color.h index 7cc7368b3..789bf27c6 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1882,6 +1882,31 @@ public: } } + static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, float gamma, int W) { + gamma = 1.f / gamma; + int i = 0; +#ifdef __SSE2__ + const vfloat gammav = F2V(gamma); + const vfloat c1v = F2V(0.2627f); + const vfloat c2v = F2V(0.6780f); + const vfloat c3v = F2V(0.0593f); + for (; i < W - 3; i += 4) { + const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); + const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); + const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); + vfloat yv = pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav); + STVFU(Y1[i], yv); + STVFU(Y2[i], yv); + } +#endif + for (; i < W; ++i) { + const float r = std::max(R[i], 0.f); + const float g = std::max(G[i], 0.f); + const float b = std::max(B[i], 0.f); + Y1[i] = Y2[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); + } + } + }; } diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index b7de67851..171ed84e8 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -17,14 +17,48 @@ * along with RawTherapee. If not, see . */ #include "gauss.h" +#include "rt_math.h" #include #include #include "opthelper.h" #include "boxblur.h" - namespace { +void compute7x7kernel(float sigma, float kernel[7][7]) { + const double temp = -2.f * rtengine::SQR(sigma); + float sum = 0.f; + for (int i = -3; i <= 3; ++i) { + for (int j = -3; j <= 3; ++j) { + kernel[i + 3][j + 3] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); + sum += kernel[i + 3][j + 3]; + } + } + + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + kernel[i][j] /= sum; + } + } +} + +void compute5x5kernel(float sigma, float kernel[5][5]) { + const double temp = -2.f * rtengine::SQR(sigma); + float sum = 0.f; + for (int i = -2; i <= 2; ++i) { + for (int j = -2; j <= 2; ++j) { + kernel[i + 2][j + 2] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); + sum += kernel[i + 2][j + 2]; + } + } + + for (int i = 0; i < 5; ++i) { + for (int j = 0; j < 5; ++j) { + kernel[i][j] /= sum; + } + } +} + template void calculateYvVFactors( const T sigma, T &b1, T &b2, T &b3, T &B, T M[3][3]) { // coefficient calculation @@ -207,6 +241,219 @@ template void gauss3x3div (T** RESTRICT src, T** RESTRICT dst, T** REST } } +template void gauss7x7div (T** RESTRICT src, T** RESTRICT dst, T** RESTRICT divBuffer, const int W, const int H, float sigma) +{ + + float kernel[7][7]; + compute7x7kernel(sigma, kernel); + +#ifdef __SSE2__ + vfloat kernelv[7][7] ALIGNED16; + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + kernelv[i][j] = F2V(kernel[i][j]); + } + } + const vfloat onev = F2V(1.f); +#endif + +#ifdef _OPENMP + #pragma omp for schedule(dynamic, 16) nowait +#endif + + for (int i = 3; i < H - 3; ++i) { + dst[i][0] = dst[i][1] = dst[i][2] = 1.f; + int j = 3; +#ifdef __SSE2__ + for (; j < W - 6; j += 4) { + vfloat valv = ZEROV; + for (int k = -3; k <= 3; ++k) { + for (int l = -3; l <= 3; ++l) { + valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 3][l + 3]); + } + } + STVFU(dst[i][j], vmaxf(LVFU(divBuffer[i][j]) / (vself(vmaskf_gt(valv, ZEROV), valv, onev)), ZEROV)); + } +#endif + for (; j < W - 3; ++j) { + float val = 0; + for (int k = -3; k <= 3; ++k) { + for (int l = -3; l <= 3; ++l) { + val += src[i + k][j + l] * kernel[k + 3][l + 3]; + } + } + dst[i][j] = rtengine::max(divBuffer[i][j] / (val > 0.f ? val : 1.f), 0.f); + } + dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f; + } + + // first and last rows +#ifdef _OPENMP + #pragma omp single +#endif + { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + for (int i = H - 3 ; i < H; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + } +} + +template void gauss5x5div (T** RESTRICT src, T** RESTRICT dst, T** RESTRICT divBuffer, const int W, const int H, float sigma) +{ + + float kernel[5][5]; + compute5x5kernel(sigma, kernel); + +#ifdef __SSE2__ + vfloat kernelv[5][5] ALIGNED16; + for (int i = 0; i < 5; ++i) { + for (int j = 0; j < 5; ++j) { + kernelv[i][j] = F2V(kernel[i][j]); + } + } + const vfloat onev = F2V(1.f); +#endif + +#ifdef _OPENMP + #pragma omp for schedule(dynamic, 16) nowait +#endif + + for (int i = 2; i < H - 2; ++i) { + dst[i][0] = dst[i][1] = 1.f; + int j = 2; +#ifdef __SSE2__ + for (; j < W - 5; j += 4) { + vfloat valv = ZEROV; + for (int k = -2; k <= 2; ++k) { + for (int l = -2; l <= 2; ++l) { + valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 2][l + 2]); + } + } + STVFU(dst[i][j], vmaxf(LVFU(divBuffer[i][j]) / (vself(vmaskf_gt(valv, ZEROV), valv, onev)), ZEROV)); + } +#endif + for (; j < W - 2; ++j) { + float val = 0; + for (int k = -2; k <= 2; ++k) { + for (int l = -2; l <= 2; ++l) { + val += src[i + k][j + l] * kernel[k + 2][l + 2]; + } + } + dst[i][j] = rtengine::max(divBuffer[i][j] / (val > 0.f ? val : 1.f), 0.f); + } + dst[i][W - 2] = dst[i][W - 1] = 1.f; + } + + // first and last rows +#ifdef _OPENMP + #pragma omp single +#endif + { + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + for (int i = H - 2 ; i < H; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + } +} + +template void gauss7x7mult (T** RESTRICT src, T** RESTRICT dst, const int W, const int H, float sigma) +{ + + float kernel[7][7]; + compute7x7kernel(sigma, kernel); +#ifdef __SSE2__ + vfloat kernelv[7][7] ALIGNED16; + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + kernelv[i][j] = F2V(kernel[i][j]); + } + } +#endif + +#ifdef _OPENMP + #pragma omp for schedule(dynamic, 16) +#endif + + for (int i = 3; i < H - 3; ++i) { + int j = 3; +#ifdef __SSE2__ + for (; j < W - 6; j += 4) { + vfloat valv = ZEROV; + for (int k = -3; k <= 3; ++k) { + for (int l = -3; l <= 3; ++l) { + valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 3][l + 3]); + } + } + STVFU(dst[i][j], LVFU(dst[i][j]) * valv); + } +#endif + for (; j < W - 3; ++j) { + float val = 0; + for (int k = -3; k <= 3; ++k) { + for (int l = -3; l <= 3; ++l) { + val += src[i + k][j + l] * kernel[k + 3][l + 3]; + } + } + dst[i][j] *= val; + } + } +} + +template void gauss5x5mult (T** RESTRICT src, T** RESTRICT dst, const int W, const int H, float sigma) +{ + + float kernel[5][5]; + compute5x5kernel(sigma, kernel); +#ifdef __SSE2__ + vfloat kernelv[5][5] ALIGNED16; + for (int i = 0; i < 5; ++i) { + for (int j = 0; j < 5; ++j) { + kernelv[i][j] = F2V(kernel[i][j]); + } + } +#endif + +#ifdef _OPENMP + #pragma omp for schedule(dynamic, 16) +#endif + + for (int i = 2; i < H - 2; ++i) { + int j = 2; +#ifdef __SSE2__ + for (; j < W - 5; j += 4) { + vfloat valv = ZEROV; + for (int k = -2; k <= 2; ++k) { + for (int l = -2; l <= 2; ++l) { + valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 2][l + 2]); + } + } + STVFU(dst[i][j], LVFU(dst[i][j]) * valv); + } +#endif + for (; j < W - 2; ++j) { + float val = 0; + for (int k = -2; k <= 2; ++k) { + for (int l = -2; l <= 2; ++l) { + val += src[i + k][j + l] * kernel[k + 2][l + 2]; + } + } + dst[i][j] *= val; + } + } +} // use separated filter if the support window is small and src == dst template void gaussHorizontal3 (T** src, T** dst, int W, int H, const float c0, const float c1) @@ -1241,14 +1488,26 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int if (sigma < GAUSS_DOUBLE) { switch (gausstype) { case GAUSS_MULT : { - gaussHorizontalSse (src, src, W, H, sigma); - gaussVerticalSsemult (src, dst, W, H, sigma); + if (sigma < 0.84 && src != dst) { + gauss5x5mult(src, dst, W, H, sigma); + } else if (sigma < 1.15f && src != dst) { + gauss7x7mult(src, dst, W, H, sigma); + } else { + gaussHorizontalSse (src, src, W, H, sigma); + gaussVerticalSsemult (src, dst, W, H, sigma); + } break; } case GAUSS_DIV : { - gaussHorizontalSse (src, dst, W, H, sigma); - gaussVerticalSsediv (dst, dst, buffer2, W, H, sigma); + if (sigma < 0.84f && src != dst) { + gauss5x5div (src, dst, buffer2, W, H, sigma); + } else if (sigma < 1.15f && src != dst) { + gauss7x7div (src, dst, buffer2, W, H, sigma); + } else { + gaussHorizontalSse (src, dst, W, H, sigma); + gaussVerticalSsediv (dst, dst, buffer2, W, H, sigma); + } break; } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 6fe8a785d..5cd65cad8 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -248,7 +248,7 @@ public: void Lanczos(const LabImage* src, LabImage* dst, float scale); void Lanczos(const Imagefloat* src, Imagefloat* dst, float scale); - void deconvsharpening(float** luminance, float** buffer, float** blend, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale); + void deconvsharpening(float** luminance, float** buffer, const float* const * blend, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale); void MLsharpen(LabImage* lab); // Manuel's clarity / sharpening void MLmicrocontrast(float** luminance, int W, int H); //Manuel's microcontrast void MLmicrocontrast(LabImage* lab); //Manuel's microcontrast diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 897aaf7b5..1d3d6375e 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -158,7 +158,7 @@ namespace rtengine extern const Settings* settings; -void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, float ** blend, int W, int H, const SharpeningParams &sharpenParam, double Scale) +void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, const float * const * blend, int W, int H, const SharpeningParams &sharpenParam, double Scale) { if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) { return; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index d947d4195..0602c770b 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -4989,20 +4989,14 @@ BENCHFUN array2D L(W,H); array2D YOld(W,H); array2D YNew(W,H); -// array2D& Y = red; // red will be overridden anyway => we can use its buffer to store Y -// array2D& Cb = green; // green will be overridden anyway => we can use its buffer to store Cb -// array2D& Cr = blue; // blue will be overridden anyway => we can use its buffer to store Cr - StopWatch Stop1("rgb2Y"); + StopWatch Stop1("rgb2YL"); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < H; ++i) { Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); - Color::RGB2Y(red[i], green[i], blue[i], YOld[i], sharpeningParams.gamma, W); - for (int j = 0; j < W; ++j) { - YNew[i][j] = YOld[i][j]; - } + Color::RGB2Y(red[i], green[i], blue[i], YOld[i], YNew[i], sharpeningParams.gamma, W); } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); @@ -5017,11 +5011,22 @@ BENCHFUN StopWatch Stop2("Y2RGB"); const float gamma = sharpeningParams.gamma; #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < H; ++i) { - for (int j = 0; j < W; ++j) { - const float factor = pow_F(YNew[i][j] / (YOld[i][j] == 0.f ? 0.00001f : YOld[i][j]), gamma); + int j = 0; +#ifdef __SSE2__ + const vfloat gammav = F2V(gamma); + for (; j < W - 3; j += 4) { + const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); + STVFU(red[i][j], LVFU(red[i][j]) * factor); + STVFU(green[i][j], LVFU(green[i][j]) * factor); + STVFU(blue[i][j], LVFU(blue[i][j]) * factor); + } + +#endif + for (; j < W; ++j) { + const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma); red[i][j] *= factor; green[i][j] *= factor; blue[i][j] *= factor; From 147d6b36f6b4b49570496825b120108a5b5d7c53 Mon Sep 17 00:00:00 2001 From: Pavel Shlyak Date: Wed, 21 Aug 2019 04:22:04 +0300 Subject: [PATCH 130/222] dcraw.cc: replace memcpy with memmove Memcpy does not support overlapping. It can cause problems in specific situations. --- rtengine/dcraw.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index a4450a69a..9606c1c71 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++) { From 7c616453940fea53ea3872bb78236280ccc577ce Mon Sep 17 00:00:00 2001 From: Pavel Shlyak Date: Wed, 21 Aug 2019 04:30:59 +0300 Subject: [PATCH 131/222] improcfun.cc: cleanup The pointers allocated with new can never be null. Exception will be thrown in case of memory allocation error. --- rtengine/improcfun.cc | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 23dc4b1ba..c3272c4d1 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -4247,11 +4247,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; @@ -4264,11 +4262,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; @@ -4281,11 +4277,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; From ec818167166b4ed9f6b073c6a0e54a8d2555bdc8 Mon Sep 17 00:00:00 2001 From: Hombre57 Date: Wed, 21 Aug 2019 12:31:45 +0200 Subject: [PATCH 132/222] Code cleanup in rtgui/thresholdselector.cc See issue #5423 --- rtgui/thresholdselector.cc | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index 9b5250862..d9b0921ce 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -629,13 +629,8 @@ void ThresholdSelector::findBoundaries(double &min, double &max) switch (movedCursor) { case (TS_BOTTOMLEFT): if (separatedSliders) { - if (movedCursor == TS_BOTTOMLEFT) { - min = minValBottom; - max = maxValBottom; - } else if (movedCursor == TS_TOPLEFT) { - min = minValTop; - max = maxValTop; - } + min = minValBottom; + max = maxValBottom; } else if (initalEq1) { min = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_TOPLEFT] : minValTop + (positions[TS_BOTTOMLEFT] - positions[TS_TOPLEFT]); max = positions[TS_BOTTOMRIGHT]; @@ -648,13 +643,8 @@ void ThresholdSelector::findBoundaries(double &min, double &max) case (TS_TOPLEFT): if (separatedSliders) { - if (movedCursor == TS_BOTTOMLEFT) { - min = minValBottom; - max = maxValBottom; - } else if (movedCursor == TS_TOPLEFT) { - min = minValTop; - max = maxValTop; - } + min = minValTop; + max = maxValTop; } else if (initalEq1) { min = minValTop; max = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_BOTTOMLEFT] : positions[TS_BOTTOMRIGHT] - (positions[TS_BOTTOMLEFT] - positions[TS_TOPLEFT]); From a0f95fe9e6f53ce9f9e653b6283b291518f560ae Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 21 Aug 2019 17:29:59 +0200 Subject: [PATCH 133/222] Speedup for gauss5x5 and gauss7x7 --- rtengine/gauss.cc | 337 +++++++++++++++++++++++++++++----------------- 1 file changed, 213 insertions(+), 124 deletions(-) diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index 171ed84e8..5665394cc 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -30,8 +30,12 @@ void compute7x7kernel(float sigma, float kernel[7][7]) { float sum = 0.f; for (int i = -3; i <= 3; ++i) { for (int j = -3; j <= 3; ++j) { - kernel[i + 3][j + 3] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); - sum += kernel[i + 3][j + 3]; + if((rtengine::SQR(i) + rtengine::SQR(j)) <= rtengine::SQR(3.0 * 1.15)) { + kernel[i + 3][j + 3] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); + sum += kernel[i + 3][j + 3]; + } else { + kernel[i + 3][j + 3] = 0.f; + } } } @@ -47,8 +51,12 @@ void compute5x5kernel(float sigma, float kernel[5][5]) { float sum = 0.f; for (int i = -2; i <= 2; ++i) { for (int j = -2; j <= 2; ++j) { - kernel[i + 2][j + 2] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); - sum += kernel[i + 2][j + 2]; + if((rtengine::SQR(i) + rtengine::SQR(j)) <= rtengine::SQR(3.0 * 0.84)) { + kernel[i + 2][j + 2] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); + sum += kernel[i + 2][j + 2]; + } else { + kernel[i + 2][j + 2] = 0.f; + } } } @@ -247,15 +255,14 @@ template void gauss7x7div (T** RESTRICT src, T** RESTRICT dst, T** REST float kernel[7][7]; compute7x7kernel(sigma, kernel); -#ifdef __SSE2__ - vfloat kernelv[7][7] ALIGNED16; - for (int i = 0; i < 7; ++i) { - for (int j = 0; j < 7; ++j) { - kernelv[i][j] = F2V(kernel[i][j]); - } - } - const vfloat onev = F2V(1.f); -#endif + const float c31 = kernel[0][2]; + const float c30 = kernel[0][3]; + const float c22 = kernel[1][1]; + const float c21 = kernel[1][2]; + const float c20 = kernel[1][3]; + const float c11 = kernel[2][2]; + const float c10 = kernel[2][3]; + const float c00 = kernel[3][3]; #ifdef _OPENMP #pragma omp for schedule(dynamic, 16) nowait @@ -263,26 +270,54 @@ template void gauss7x7div (T** RESTRICT src, T** RESTRICT dst, T** REST for (int i = 3; i < H - 3; ++i) { dst[i][0] = dst[i][1] = dst[i][2] = 1.f; - int j = 3; -#ifdef __SSE2__ - for (; j < W - 6; j += 4) { - vfloat valv = ZEROV; - for (int k = -3; k <= 3; ++k) { - for (int l = -3; l <= 3; ++l) { - valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 3][l + 3]); - } - } - STVFU(dst[i][j], vmaxf(LVFU(divBuffer[i][j]) / (vself(vmaskf_gt(valv, ZEROV), valv, onev)), ZEROV)); - } -#endif - for (; j < W - 3; ++j) { - float val = 0; - for (int k = -3; k <= 3; ++k) { - for (int l = -3; l <= 3; ++l) { - val += src[i + k][j + l] * kernel[k + 3][l + 3]; - } - } - dst[i][j] = rtengine::max(divBuffer[i][j] / (val > 0.f ? val : 1.f), 0.f); + // I tried hand written SSE code but gcc vectorizes better + for (int j = 3; j < W - 3; ++j) { + float val = src[i - 3][j - 1] * c31; + val += src[i - 3][j - 0] * c30; + val += src[i - 3][j + 1] * c31; + + val += src[i - 2][j - 2] * c22; + val += src[i - 2][j - 1] * c21; + val += src[i - 2][j - 0] * c20; + val += src[i - 2][j + 1] * c21; + val += src[i - 2][j + 2] * c22; + + val += src[i - 1][j - 3] * c31; + val += src[i - 1][j - 2] * c21; + val += src[i - 1][j - 1] * c11; + val += src[i - 1][j - 0] * c10; + val += src[i - 1][j + 1] * c11; + val += src[i - 1][j + 2] * c21; + val += src[i - 1][j + 3] * c31; + + val += src[i][j - 3] * c30; + val += src[i][j - 2] * c20; + val += src[i][j - 1] * c10; + val += src[i][j - 0] * c00; + val += src[i][j + 1] * c10; + val += src[i][j + 2] * c20; + val += src[i][j + 3] * c30; + + val += src[i + 1][j - 3] * c31; + val += src[i + 1][j - 2] * c21; + val += src[i + 1][j - 1] * c11; + val += src[i + 1][j - 0] * c10; + val += src[i + 1][j + 1] * c11; + val += src[i + 1][j + 2] * c21; + val += src[i + 1][j + 3] * c31; + + val += src[i + 2][j - 2] * c22; + val += src[i + 2][j - 1] * c21; + val += src[i + 2][j - 0] * c20; + val += src[i + 2][j + 1] * c21; + val += src[i + 2][j + 2] * c22; + + val += src[i + 3][j - 1] * c31; + val += src[i + 3][j - 0] * c30; + val += src[i + 3][j + 1] * c31; + + val = val > 0.f ? val : 1.f; + dst[i][j] = std::max(divBuffer[i][j] / val, 0.f); } dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f; } @@ -311,15 +346,11 @@ template void gauss5x5div (T** RESTRICT src, T** RESTRICT dst, T** REST float kernel[5][5]; compute5x5kernel(sigma, kernel); -#ifdef __SSE2__ - vfloat kernelv[5][5] ALIGNED16; - for (int i = 0; i < 5; ++i) { - for (int j = 0; j < 5; ++j) { - kernelv[i][j] = F2V(kernel[i][j]); - } - } - const vfloat onev = F2V(1.f); -#endif + const float c21 = kernel[0][1]; + const float c20 = kernel[0][2]; + const float c11 = kernel[1][1]; + const float c10 = kernel[1][2]; + const float c00 = kernel[2][2]; #ifdef _OPENMP #pragma omp for schedule(dynamic, 16) nowait @@ -327,26 +358,36 @@ template void gauss5x5div (T** RESTRICT src, T** RESTRICT dst, T** REST for (int i = 2; i < H - 2; ++i) { dst[i][0] = dst[i][1] = 1.f; - int j = 2; -#ifdef __SSE2__ - for (; j < W - 5; j += 4) { - vfloat valv = ZEROV; - for (int k = -2; k <= 2; ++k) { - for (int l = -2; l <= 2; ++l) { - valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 2][l + 2]); - } - } - STVFU(dst[i][j], vmaxf(LVFU(divBuffer[i][j]) / (vself(vmaskf_gt(valv, ZEROV), valv, onev)), ZEROV)); - } -#endif - for (; j < W - 2; ++j) { - float val = 0; - for (int k = -2; k <= 2; ++k) { - for (int l = -2; l <= 2; ++l) { - val += src[i + k][j + l] * kernel[k + 2][l + 2]; - } - } - dst[i][j] = rtengine::max(divBuffer[i][j] / (val > 0.f ? val : 1.f), 0.f); + // I tried hand written SSE code but gcc vectorizes better + for (int j = 2; j < W - 2; ++j) { + float val = src[i - 2][j - 1] * c21; + val += src[i - 2][j - 0] * c20; + val += src[i - 2][j + 1] * c21; + + val += src[i - 1][j - 2] * c21; + val += src[i - 1][j - 1] * c11; + val += src[i - 1][j - 0] * c10; + val += src[i - 1][j + 1] * c11; + val += src[i - 1][j + 2] * c21; + + val += src[i - 0][j - 2] * c20; + val += src[i - 0][j - 1] * c10; + val += src[i - 0][j - 0] * c00; + val += src[i - 0][j + 1] * c10; + val += src[i - 0][j + 2] * c20; + + val += src[i + 1][j - 2] * c21; + val += src[i + 1][j - 1] * c11; + val += src[i + 1][j - 0] * c10; + val += src[i + 1][j + 1] * c11; + val += src[i + 1][j + 2] * c21; + + val += src[i + 2][j - 1] * c21; + val += src[i + 2][j - 0] * c20; + val += src[i + 2][j + 1] * c21; + + val = val > 0.f ? val : 1.f; + dst[i][j] = std::max(divBuffer[i][j] / val, 0.f); } dst[i][W - 2] = dst[i][W - 1] = 1.f; } @@ -374,39 +415,66 @@ template void gauss7x7mult (T** RESTRICT src, T** RESTRICT dst, const i float kernel[7][7]; compute7x7kernel(sigma, kernel); -#ifdef __SSE2__ - vfloat kernelv[7][7] ALIGNED16; - for (int i = 0; i < 7; ++i) { - for (int j = 0; j < 7; ++j) { - kernelv[i][j] = F2V(kernel[i][j]); - } - } -#endif + const float c31 = kernel[0][2]; + const float c30 = kernel[0][3]; + const float c22 = kernel[1][1]; + const float c21 = kernel[1][2]; + const float c20 = kernel[1][3]; + const float c11 = kernel[2][2]; + const float c10 = kernel[2][3]; + const float c00 = kernel[3][3]; #ifdef _OPENMP #pragma omp for schedule(dynamic, 16) #endif for (int i = 3; i < H - 3; ++i) { - int j = 3; -#ifdef __SSE2__ - for (; j < W - 6; j += 4) { - vfloat valv = ZEROV; - for (int k = -3; k <= 3; ++k) { - for (int l = -3; l <= 3; ++l) { - valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 3][l + 3]); - } - } - STVFU(dst[i][j], LVFU(dst[i][j]) * valv); - } -#endif - for (; j < W - 3; ++j) { - float val = 0; - for (int k = -3; k <= 3; ++k) { - for (int l = -3; l <= 3; ++l) { - val += src[i + k][j + l] * kernel[k + 3][l + 3]; - } - } + // I tried hand written SSE code but gcc vectorizes better + for (int j = 3; j < W - 3; ++j) { + float val = src[i - 3][j - 1] * c31; + val += src[i - 3][j - 0] * c30; + val += src[i - 3][j + 1] * c31; + + val += src[i - 2][j - 2] * c22; + val += src[i - 2][j - 1] * c21; + val += src[i - 2][j - 0] * c20; + val += src[i - 2][j + 1] * c21; + val += src[i - 2][j + 2] * c22; + + val += src[i - 1][j - 3] * c31; + val += src[i - 1][j - 2] * c21; + val += src[i - 1][j - 1] * c11; + val += src[i - 1][j - 0] * c10; + val += src[i - 1][j + 1] * c11; + val += src[i - 1][j + 2] * c21; + val += src[i - 1][j + 3] * c31; + + val += src[i][j - 3] * c30; + val += src[i][j - 2] * c20; + val += src[i][j - 1] * c10; + val += src[i][j - 0] * c00; + val += src[i][j + 1] * c10; + val += src[i][j + 2] * c20; + val += src[i][j + 3] * c30; + + val += src[i + 1][j - 3] * c31; + val += src[i + 1][j - 2] * c21; + val += src[i + 1][j - 1] * c11; + val += src[i + 1][j - 0] * c10; + val += src[i + 1][j + 1] * c11; + val += src[i + 1][j + 2] * c21; + val += src[i + 1][j + 3] * c31; + + val += src[i + 2][j - 2] * c22; + val += src[i + 2][j - 1] * c21; + val += src[i + 2][j - 0] * c20; + val += src[i + 2][j + 1] * c21; + val += src[i + 2][j + 2] * c22; + + val += src[i + 3][j - 1] * c31; + val += src[i + 3][j - 0] * c30; + val += src[i + 3][j + 1] * c31; + dst[i][j] *= val; } } @@ -417,39 +485,46 @@ template void gauss5x5mult (T** RESTRICT src, T** RESTRICT dst, const i float kernel[5][5]; compute5x5kernel(sigma, kernel); -#ifdef __SSE2__ - vfloat kernelv[5][5] ALIGNED16; - for (int i = 0; i < 5; ++i) { - for (int j = 0; j < 5; ++j) { - kernelv[i][j] = F2V(kernel[i][j]); - } - } -#endif + + const float c21 = kernel[0][1]; + const float c20 = kernel[0][2]; + const float c11 = kernel[1][1]; + const float c10 = kernel[1][2]; + const float c00 = kernel[2][2]; #ifdef _OPENMP #pragma omp for schedule(dynamic, 16) #endif for (int i = 2; i < H - 2; ++i) { - int j = 2; -#ifdef __SSE2__ - for (; j < W - 5; j += 4) { - vfloat valv = ZEROV; - for (int k = -2; k <= 2; ++k) { - for (int l = -2; l <= 2; ++l) { - valv += LVFU(src[i + k][j + l]) * LVF(kernelv[k + 2][l + 2]); - } - } - STVFU(dst[i][j], LVFU(dst[i][j]) * valv); - } -#endif - for (; j < W - 2; ++j) { - float val = 0; - for (int k = -2; k <= 2; ++k) { - for (int l = -2; l <= 2; ++l) { - val += src[i + k][j + l] * kernel[k + 2][l + 2]; - } - } + // I tried hand written SSE code but gcc vectorizes better + for (int j = 2; j < W - 2; ++j) { + float val = src[i - 2][j - 1] * c21; + val += src[i - 2][j - 0] * c20; + val += src[i - 2][j + 1] * c21; + + val += src[i - 1][j - 2] * c21; + val += src[i - 1][j - 1] * c11; + val += src[i - 1][j - 0] * c10; + val += src[i - 1][j + 1] * c11; + val += src[i - 1][j + 2] * c21; + + val += src[i - 0][j - 2] * c20; + val += src[i - 0][j - 1] * c10; + val += src[i - 0][j - 0] * c00; + val += src[i - 0][j + 1] * c10; + val += src[i - 0][j + 2] * c20; + + val += src[i + 1][j - 2] * c21; + val += src[i + 1][j - 1] * c11; + val += src[i + 1][j - 0] * c10; + val += src[i + 1][j + 1] * c11; + val += src[i + 1][j + 2] * c21; + + val += src[i + 2][j - 1] * c21; + val += src[i + 2][j - 0] * c20; + val += src[i + 2][j + 1] * c21; + dst[i][j] *= val; } } @@ -1390,6 +1465,8 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int { static constexpr auto GAUSS_SKIP = 0.25; static constexpr auto GAUSS_3X3_LIMIT = 0.6; + static constexpr auto GAUSS_5X5_LIMIT = 0.84; + static constexpr auto GAUSS_7X7_LIMIT = 1.15; static constexpr auto GAUSS_DOUBLE = 25.0; if(buffer) { @@ -1488,9 +1565,9 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int if (sigma < GAUSS_DOUBLE) { switch (gausstype) { case GAUSS_MULT : { - if (sigma < 0.84 && src != dst) { + if (sigma <= GAUSS_5X5_LIMIT && src != dst) { gauss5x5mult(src, dst, W, H, sigma); - } else if (sigma < 1.15f && src != dst) { + } else if (sigma <= GAUSS_7X7_LIMIT && src != dst) { gauss7x7mult(src, dst, W, H, sigma); } else { gaussHorizontalSse (src, src, W, H, sigma); @@ -1500,9 +1577,9 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int } case GAUSS_DIV : { - if (sigma < 0.84f && src != dst) { + if (sigma <= GAUSS_5X5_LIMIT && src != dst) { gauss5x5div (src, dst, buffer2, W, H, sigma); - } else if (sigma < 1.15f && src != dst) { + } else if (sigma <= GAUSS_7X7_LIMIT && src != dst) { gauss7x7div (src, dst, buffer2, W, H, sigma); } else { gaussHorizontalSse (src, dst, W, H, sigma); @@ -1527,14 +1604,26 @@ template void gaussianBlurImpl(T** src, T** dst, const int W, const int if (sigma < GAUSS_DOUBLE) { switch (gausstype) { case GAUSS_MULT : { - gaussHorizontal (src, src, W, H, sigma); - gaussVerticalmult (src, dst, W, H, sigma); + if (sigma <= GAUSS_5X5_LIMIT && src != dst) { + gauss5x5mult(src, dst, W, H, sigma); + } else if (sigma <= GAUSS_7X7_LIMIT && src != dst) { + gauss7x7mult(src, dst, W, H, sigma); + } else { + gaussHorizontal (src, src, W, H, sigma); + gaussVerticalmult (src, dst, W, H, sigma); + } break; } case GAUSS_DIV : { - gaussHorizontal (src, dst, W, H, sigma); - gaussVerticaldiv (dst, dst, buffer2, W, H, sigma); + if (sigma <= GAUSS_5X5_LIMIT && src != dst) { + gauss5x5div (src, dst, buffer2, W, H, sigma); + } else if (sigma <= GAUSS_7X7_LIMIT && src != dst) { + gauss7x7div (src, dst, buffer2, W, H, sigma); + } else { + gaussHorizontal (src, dst, W, H, sigma); + gaussVerticaldiv (dst, dst, buffer2, W, H, sigma); + } break; } From e93ce860678c4073e09ca35e01d4d802358d4751 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 21 Aug 2019 19:03:51 +0200 Subject: [PATCH 134/222] DNG with 'Embed Fast Load Data' not rendered the same as plain DNG or NEF, fixes #4695 --- rtengine/dcraw.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index a4450a69a..e15a2bb0f 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6549,6 +6549,31 @@ guess_cfa_pc: cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ RT_blacklevel_from_constant = ThreeValBool::F; +//----------------------------------------------------------------------------- +// taken from LibRaw. +/* + Copyright 2008-2019 LibRaw LLC (info@libraw.org) + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). +*/ + if (tiff_ifd[ifd].samples > 1 && tiff_ifd[ifd].samples == len) // LinearDNG, per-channel black + { + for (i = 0; i < 4 && i < len; i++) + { + double b = getreal(type); + cblack[i] = b+0.5; + } + + black = 0; + } else +//----------------------------------------------------------------------------- if(cblack[4] * cblack[5] == 0) { int dblack[] = { 0,0,0,0 }; black = getreal(type); From d4ffcde1a3416ff96a6ac845577d77001e7b4b81 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 21 Aug 2019 21:22:22 +0200 Subject: [PATCH 135/222] Capture sharpening: reduce upper limit of radius adjuster to 1.0 --- rtgui/pdsharpening.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 7a428806f..5c14c052f 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -50,7 +50,7 @@ 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.35)); - dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.75)); + dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_EDRADIUS"), 0.4, 1.0, 0.01, 0.75)); diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); rld->pack_start(*gamma); rld->pack_start(*dradius); From 061bf713c80782dd7e1dc551b757c687218cd2a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Thu, 22 Aug 2019 15:25:43 +0200 Subject: [PATCH 136/222] Optimize `milestones` handling in `LCurve` c'tor (fixes #5422) --- rtgui/labcurve.cc | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index 4b25c1e4f..eeb0cd18e 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -29,9 +29,6 @@ using namespace rtengine::procparams; LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), false, true) { - - std::vector milestones; - brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100., 100., 1., 0.)); contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100., 100., 1., 0.)); chromaticity = Gtk::manage (new Adjuster (M("TP_LABCURVE_CHROMATICITY"), -100., 100., 1., 0.)); @@ -98,12 +95,12 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE4") ); //from green to magenta - milestones.clear(); - milestones.push_back( GradientMilestone(0., 0., 1., 0.) ); - milestones.push_back( GradientMilestone(1., 1., 0., 1.) ); + std::vector milestones = { + GradientMilestone(0., 0., 1., 0.), + GradientMilestone(1., 1., 0., 1.) + }; ashape->setBottomBarBgGradient(milestones); ashape->setLeftBarBgGradient(milestones); - milestones.clear(); bshape = static_cast(curveEditorG->addCurve(CT_Diagonal, "b*")); bshape->setRangeLabels( @@ -113,12 +110,12 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), bshape->setEditID(EUID_Lab_bCurve, BT_SINGLEPLANE_FLOAT); //from blue to yellow - milestones.clear(); - milestones.push_back( GradientMilestone(0., 0., 0., 1.) ); - milestones.push_back( GradientMilestone(1., 1., 1., 0.) ); + milestones = { + GradientMilestone(0., 0., 0., 1.), + GradientMilestone(1., 1., 1., 0.) + }; bshape->setBottomBarBgGradient(milestones); bshape->setLeftBarBgGradient(milestones); - milestones.clear(); curveEditorG->newLine(); // ------------------------------------------------ second line @@ -171,21 +168,23 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), clshape->setLeftBarColorProvider(this, 7); clshape->setRangeDefaultMilestones(0.25, 0.5, 0.75); - milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); - milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + milestones = { + GradientMilestone(0., 0., 0., 0.), + GradientMilestone(1., 1., 1., 1.) + }; clshape->setBottomBarBgGradient(milestones); // Setting the gradient milestones // from black to white - milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); - milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + milestones.emplace_back(0., 0., 0., 0.); + milestones.emplace_back(1., 1., 1., 1.); lshape->setBottomBarBgGradient(milestones); lshape->setLeftBarBgGradient(milestones); - milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); - milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + milestones.emplace_back(0., 0., 0., 0.); + milestones.emplace_back(1., 1., 1., 1.); lcshape->setRangeDefaultMilestones(0.05, 0.2, 0.58); lcshape->setBottomBarBgGradient(milestones); @@ -201,7 +200,7 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL"), float R, G, B; float x = float(i) * (1.0f / 6.0); Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); - milestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + milestones.emplace_back(x, R, G, B); } chshape->setBottomBarBgGradient(milestones); From cb7b31f3a4c760e305174d7b7ad5d9e609a41878 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 24 Aug 2019 12:14:54 +0200 Subject: [PATCH 137/222] Allow Capture Sharpening for monochrome raw files --- rtgui/toolpanelcoord.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index f64205219..0bf976c2b 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -344,7 +344,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::hide(); - pdSharpening->FoldableToolPanel::hide(); + pdSharpening->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; From bca760c8baa7ca9298f85f4ddc8980c3aa8ee1c7 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 24 Aug 2019 20:52:36 +0200 Subject: [PATCH 138/222] Capture sharpening: removed unused code, also small speedup for 5x5 and 7x7 gauss --- rtengine/color.h | 78 --------------------- rtengine/gauss.cc | 168 ++++++++-------------------------------------- 2 files changed, 28 insertions(+), 218 deletions(-) diff --git a/rtengine/color.h b/rtengine/color.h index 789bf27c6..d36a7db8e 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1804,84 +1804,6 @@ public: return (hr); } - static inline void RGB2YCbCr(float* R, float* G, float* B, float* Y, float* Cb, float *Cr, float gamma, int W) { - gamma = 1.f / gamma; - int i = 0; -#ifdef __SSE2__ - const vfloat gammav = F2V(gamma); - const vfloat c1v = F2V(0.2627f); - const vfloat c2v = F2V(0.6780f); - const vfloat c3v = F2V(0.0593f); - const vfloat c4v = F2V(1.f - 0.0593f); - const vfloat c5v = F2V(1.f - 0.2627f); - for (; i < W - 3; i += 4) { - const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); - const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); - const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); - STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav)); - STVFU(Cb[i], c4v * Bv - (c1v * Rv + c2v * Gv)); - STVFU(Cr[i], c5v * Rv - (c2v * Gv + c3v * Bv)); - } -#endif - for (; i < W; ++i) { - const float r = std::max(R[i], 0.f); - const float g = std::max(G[i], 0.f); - const float b = std::max(B[i], 0.f); - Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); - Cb[i] = (1.f - 0.0593f) * b - (0.2627f * r + 0.6780f * g); - Cr[i] = (1.f - 0.2627f) * r - (0.6780f * g + 0.0593f * b); - } - } - - static inline void YCbCr2RGB(float* Y, float* Cb, float* Cr, float* R, float* G, float* B, float gamma, int W) { - int i = 0; -#ifdef __SSE2__ - const vfloat gammav = F2V(gamma); - const vfloat c1v = F2V(0.0593f / 0.6780f); - const vfloat c2v = F2V(0.2627f / 0.6780f); - - for (; i < W - 3; i += 4) { - const vfloat Yv = pow_F(LVFU(Y[i]), gammav); - const vfloat Crv = LVFU(Cr[i]); - const vfloat Cbv = LVFU(Cb[i]); - STVFU(R[i], vmaxf(Yv + Crv, ZEROV)); - STVFU(G[i], vmaxf(Yv - c1v * Cbv - c2v * Crv, ZEROV)); - STVFU(B[i], vmaxf(Yv + Cbv, ZEROV)); - } -#endif - for (; i < W; ++i) { - const float y = pow_F(Y[i], gamma); - const float cr = Cr[i]; - const float cb = Cb[i]; - R[i] = std::max(y + cr, 0.f); - G[i] = std::max(y - (0.0593f / 0.6780f) * cb - (0.2627f / 0.6780f) * cr, 0.f); - B[i] = std::max(y + cb, 0.f); - } - } - - static inline void RGB2Y(float* R, float* G, float* B, float* Y, float gamma, int W) { - gamma = 1.f / gamma; - int i = 0; -#ifdef __SSE2__ - const vfloat gammav = F2V(gamma); - const vfloat c1v = F2V(0.2627f); - const vfloat c2v = F2V(0.6780f); - const vfloat c3v = F2V(0.0593f); - for (; i < W - 3; i += 4) { - const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); - const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); - const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); - STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav)); - } -#endif - for (; i < W; ++i) { - const float r = std::max(R[i], 0.f); - const float g = std::max(G[i], 0.f); - const float b = std::max(B[i], 0.f); - Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); - } - } - static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, float gamma, int W) { gamma = 1.f / gamma; int i = 0; diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index 5665394cc..dfb7cb225 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -272,52 +272,16 @@ template void gauss7x7div (T** RESTRICT src, T** RESTRICT dst, T** REST dst[i][0] = dst[i][1] = dst[i][2] = 1.f; // I tried hand written SSE code but gcc vectorizes better for (int j = 3; j < W - 3; ++j) { - float val = src[i - 3][j - 1] * c31; - val += src[i - 3][j - 0] * c30; - val += src[i - 3][j + 1] * c31; + const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + + c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; - val += src[i - 2][j - 2] * c22; - val += src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; - val += src[i - 2][j + 2] * c22; - - val += src[i - 1][j - 3] * c31; - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - val += src[i - 1][j + 3] * c31; - - val += src[i][j - 3] * c30; - val += src[i][j - 2] * c20; - val += src[i][j - 1] * c10; - val += src[i][j - 0] * c00; - val += src[i][j + 1] * c10; - val += src[i][j + 2] * c20; - val += src[i][j + 3] * c30; - - val += src[i + 1][j - 3] * c31; - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - val += src[i + 1][j + 3] * c31; - - val += src[i + 2][j - 2] * c22; - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; - val += src[i + 2][j + 2] * c22; - - val += src[i + 3][j - 1] * c31; - val += src[i + 3][j - 0] * c30; - val += src[i + 3][j + 1] * c31; - - val = val > 0.f ? val : 1.f; - dst[i][j] = std::max(divBuffer[i][j] / val, 0.f); + dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f; } @@ -360,34 +324,13 @@ template void gauss5x5div (T** RESTRICT src, T** RESTRICT dst, T** REST dst[i][0] = dst[i][1] = 1.f; // I tried hand written SSE code but gcc vectorizes better for (int j = 2; j < W - 2; ++j) { - float val = src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; + const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - - val += src[i - 0][j - 2] * c20; - val += src[i - 0][j - 1] * c10; - val += src[i - 0][j - 0] * c00; - val += src[i - 0][j + 1] * c10; - val += src[i - 0][j + 2] * c20; - - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; - - val = val > 0.f ? val : 1.f; - dst[i][j] = std::max(divBuffer[i][j] / val, 0.f); + dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } dst[i][W - 2] = dst[i][W - 1] = 1.f; } @@ -431,49 +374,14 @@ template void gauss7x7mult (T** RESTRICT src, T** RESTRICT dst, const i for (int i = 3; i < H - 3; ++i) { // I tried hand written SSE code but gcc vectorizes better for (int j = 3; j < W - 3; ++j) { - float val = src[i - 3][j - 1] * c31; - val += src[i - 3][j - 0] * c30; - val += src[i - 3][j + 1] * c31; - - val += src[i - 2][j - 2] * c22; - val += src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; - val += src[i - 2][j + 2] * c22; - - val += src[i - 1][j - 3] * c31; - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - val += src[i - 1][j + 3] * c31; - - val += src[i][j - 3] * c30; - val += src[i][j - 2] * c20; - val += src[i][j - 1] * c10; - val += src[i][j - 0] * c00; - val += src[i][j + 1] * c10; - val += src[i][j + 2] * c20; - val += src[i][j + 3] * c30; - - val += src[i + 1][j - 3] * c31; - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - val += src[i + 1][j + 3] * c31; - - val += src[i + 2][j - 2] * c22; - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; - val += src[i + 2][j + 2] * c22; - - val += src[i + 3][j - 1] * c31; - val += src[i + 3][j - 0] * c30; - val += src[i + 3][j + 1] * c31; + const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + + c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; dst[i][j] *= val; } @@ -499,31 +407,11 @@ template void gauss5x5mult (T** RESTRICT src, T** RESTRICT dst, const i for (int i = 2; i < H - 2; ++i) { // I tried hand written SSE code but gcc vectorizes better for (int j = 2; j < W - 2; ++j) { - float val = src[i - 2][j - 1] * c21; - val += src[i - 2][j - 0] * c20; - val += src[i - 2][j + 1] * c21; - - val += src[i - 1][j - 2] * c21; - val += src[i - 1][j - 1] * c11; - val += src[i - 1][j - 0] * c10; - val += src[i - 1][j + 1] * c11; - val += src[i - 1][j + 2] * c21; - - val += src[i - 0][j - 2] * c20; - val += src[i - 0][j - 1] * c10; - val += src[i - 0][j - 0] * c00; - val += src[i - 0][j + 1] * c10; - val += src[i - 0][j + 2] * c20; - - val += src[i + 1][j - 2] * c21; - val += src[i + 1][j - 1] * c11; - val += src[i + 1][j - 0] * c10; - val += src[i + 1][j + 1] * c11; - val += src[i + 1][j + 2] * c21; - - val += src[i + 2][j - 1] * c21; - val += src[i + 2][j - 0] * c20; - val += src[i + 2][j + 1] * c21; + const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; dst[i][j] *= val; } From 9a624ca01e36208a8727f200554ed088f9f618e2 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 27 Aug 2019 13:25:34 +0200 Subject: [PATCH 139/222] Speedup for transform --- rtengine/improcfun.h | 110 ------------------------------------- rtengine/iptransform.cc | 119 +++++++++++++++++++++++++++++----------- 2 files changed, 86 insertions(+), 143 deletions(-) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 987a460d7..338df2416 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -77,116 +77,6 @@ class ImProcFunctions bool needsLensfun(); // static cmsUInt8Number* Mempro = NULL; - inline void interpolateTransformCubic(Imagefloat* src, int xs, int ys, double Dx, double Dy, float *r, float *g, float *b, double mul) - { - const double A = -0.85; - - double w[4]; - - { - double t1, t2; - t1 = -A * (Dx - 1.0) * Dx; - t2 = (3.0 - 2.0 * Dx) * Dx * Dx; - w[3] = t1 * Dx; - w[2] = t1 * (Dx - 1.0) + t2; - w[1] = -t1 * Dx + 1.0 - t2; - w[0] = -t1 * (Dx - 1.0); - } - - double rd, gd, bd; - double yr[4] = {0.0}, yg[4] = {0.0}, yb[4] = {0.0}; - - for (int k = ys, kx = 0; k < ys + 4; k++, kx++) { - rd = gd = bd = 0.0; - - for (int i = xs, ix = 0; i < xs + 4; i++, ix++) { - rd += src->r(k, i) * w[ix]; - gd += src->g(k, i) * w[ix]; - bd += src->b(k, i) * w[ix]; - } - - yr[kx] = rd; - yg[kx] = gd; - yb[kx] = bd; - } - - - { - double t1, t2; - - t1 = -A * (Dy - 1.0) * Dy; - t2 = (3.0 - 2.0 * Dy) * Dy * Dy; - w[3] = t1 * Dy; - w[2] = t1 * (Dy - 1.0) + t2; - w[1] = -t1 * Dy + 1.0 - t2; - w[0] = -t1 * (Dy - 1.0); - } - - rd = gd = bd = 0.0; - - for (int i = 0; i < 4; i++) { - rd += yr[i] * w[i]; - gd += yg[i] * w[i]; - bd += yb[i] * w[i]; - } - - *r = rd * mul; - *g = gd * mul; - *b = bd * mul; - - // if (xs==100 && ys==100) - // printf ("r=%g, g=%g\n", *r, *g); - } - - inline void interpolateTransformChannelsCubic(float** src, int xs, int ys, double Dx, double Dy, float *r, double mul) - { - const double A = -0.85; - - double w[4]; - - { - double t1, t2; - t1 = -A * (Dx - 1.0) * Dx; - t2 = (3.0 - 2.0 * Dx) * Dx * Dx; - w[3] = t1 * Dx; - w[2] = t1 * (Dx - 1.0) + t2; - w[1] = -t1 * Dx + 1.0 - t2; - w[0] = -t1 * (Dx - 1.0); - } - - double rd; - double yr[4] = {0.0}; - - for (int k = ys, kx = 0; k < ys + 4; k++, kx++) { - rd = 0.0; - - for (int i = xs, ix = 0; i < xs + 4; i++, ix++) { - rd += src[k][i] * w[ix]; - } - - yr[kx] = rd; - } - - - { - double t1, t2; - t1 = -A * (Dy - 1.0) * Dy; - t2 = (3.0 - 2.0 * Dy) * Dy * Dy; - w[3] = t1 * Dy; - w[2] = t1 * (Dy - 1.0) + t2; - w[1] = -t1 * Dy + 1.0 - t2; - w[0] = -t1 * (Dy - 1.0); - } - - rd = 0.0; - - for (int i = 0; i < 4; i++) { - rd += yr[i] * w[i]; - } - - *r = rd * mul; - } - public: enum class Median { diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 5b1e7c458..1d7ac9d56 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -26,7 +26,8 @@ #include "rt_math.h" #include "sleef.c" #include "rtlensfun.h" - +#define BENCHMARK +#include "StopWatch.h" using namespace std; @@ -87,6 +88,66 @@ float normn (float a, float b, int n) } } +inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul) +{ + constexpr float A = -0.85f; + + // Vertical + const float t1Vert = A * (Dy - Dy * Dy); + const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy; + const float w3Vert = t1Vert * Dy; + const float w2Vert = t1Vert * Dy - t1Vert + t2Vert; + const float w1Vert = 1.f - (t1Vert * Dy) - t2Vert; + const float w0Vert = t1Vert - (t1Vert * Dy); + + float rv[4], gv[4], bv[4]; + for (int i = 0; i < 4; ++i) { + rv[i] = w0Vert * src->r(ys, xs + i) + w1Vert * src->r(ys + 1, xs + i) + w2Vert * src->r(ys + 2, xs + i) + w3Vert * src->r(ys + 3, xs + i); + gv[i] = w0Vert * src->g(ys, xs + i) + w1Vert * src->g(ys + 1, xs + i) + w2Vert * src->g(ys + 2, xs + i) + w3Vert * src->g(ys + 3, xs + i); + bv[i] = w0Vert * src->b(ys, xs + i) + w1Vert * src->b(ys + 1, xs + i) + w2Vert * src->b(ys + 2, xs + i) + w3Vert * src->b(ys + 3, xs + i); + } + + // Horizontal + const float t1Hor = A * (Dx - Dx * Dx); + const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx; + const float w3Hor = t1Hor * Dx; + const float w2Hor = t1Hor * Dx - t1Hor + t2Hor; + const float w1Hor = 1.f - (t1Hor * Dx) - t2Hor; + const float w0Hor = t1Hor - (t1Hor * Dx); + + r = mul * (rv[0] * w0Hor + rv[1] * w1Hor + rv[2] * w2Hor + rv[3] * w3Hor); + g = mul * (gv[0] * w0Hor + gv[1] * w1Hor + gv[2] * w2Hor + gv[3] * w3Hor); + b = mul * (bv[0] * w0Hor + bv[1] * w1Hor + bv[2] * w2Hor + bv[3] * w3Hor); +} + +inline void interpolateTransformChannelsCubic(const float* const * src, int xs, int ys, float Dx, float Dy, float &dest, float mul) +{ + constexpr float A = -0.85f; + + // Vertical + const float t1Vert = A * (Dy - Dy * Dy); + const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy; + const float w3Vert = t1Vert * Dy; + const float w2Vert = t1Vert * Dy - t1Vert + t2Vert; + const float w1Vert = 1.f - (t1Vert * Dy) - t2Vert; + const float w0Vert = t1Vert - (t1Vert * Dy); + + float cv[4]; + for (int i = 0; i < 4; ++i) { + cv[i] = w0Vert * src[ys][xs + i] + w1Vert * src[ys + 1][xs + i] + w2Vert * src[ys + 2][xs + i] + w3Vert * src[ys + 3][xs + i]; + } + + // Horizontal + const float t1Hor = A * (Dx - Dx * Dx); + const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx; + const float w3Hor = t1Hor * Dx; + const float w2Hor = t1Hor * Dx - t1Hor + t2Hor; + const float w1Hor = 1.f - (t1Hor * Dx) - t2Hor; + const float w0Hor = t1Hor - (t1Hor * Dx); + + dest = mul * (cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor); +} + } @@ -740,17 +801,18 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat* void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap) { + BENCHFUN // set up stuff, depending on the mode we are - bool enableLCPDist = pLCPMap && params->lensProf.useDist; - bool enableCA = highQuality && needsCA(); - bool enableGradient = needsGradient(); - bool enablePCVignetting = needsPCVignetting(); - bool enableVignetting = needsVignetting(); - bool enablePerspective = needsPerspective(); - bool enableDistortion = needsDistortion(); + const bool enableLCPDist = pLCPMap && params->lensProf.useDist; + const bool enableCA = highQuality && needsCA(); + const bool enableGradient = needsGradient(); + const bool enablePCVignetting = needsPCVignetting(); + const bool enableVignetting = needsVignetting(); + const bool enablePerspective = needsPerspective(); + const bool enableDistortion = needsDistortion(); - double w2 = (double) oW / 2.0 - 0.5; - double h2 = (double) oH / 2.0 - 0.5; + const double w2 = (double) oW / 2.0 - 0.5; + const double h2 = (double) oH / 2.0 - 0.5; double vig_w2, vig_h2, maxRadius, v, b, mul; calcVignettingParams (oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); @@ -784,11 +846,11 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I chDist[2] = enableCA ? params->cacorrection.blue : 0.0; // auxiliary variables for distortion correction - double distAmount = params->distortion.amount; + const double distAmount = params->distortion.amount; // auxiliary variables for rotation - double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0); - double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0); + const double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0); + const double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0); // auxiliary variables for vertical perspective correction double vpdeg = params->perspective.vertical / 100.0 * 45.0; @@ -814,9 +876,10 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I #pragma GCC diagnostic pop #endif // main cycle - bool darkening = (params->vignetting.amount <= 0.0); + const bool darkening = (params->vignetting.amount <= 0.0); + #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for schedule(dynamic, 16) if(multiThread) #endif for (int y = 0; y < transformed->getHeight(); y++) { @@ -833,13 +896,6 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I x_d += ascale * (cx - w2); // centering x coord & scale y_d += ascale * (cy - h2); // centering y coord & scale - double vig_x_d = 0., vig_y_d = 0.; - - if (enableVignetting) { - vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale - vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale - } - if (enablePerspective) { // horizontal perspective transformation y_d *= maxRadius / (maxRadius + x_d * hptanpt); @@ -862,14 +918,6 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I s = 1.0 - distAmount + distAmount * r ; } - double r2 = 0.; - - if (enableVignetting) { - double vig_Dx = vig_x_d * cost - vig_y_d * sint; - double vig_Dy = vig_x_d * sint + vig_y_d * cost; - r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy); - } - for (int c = 0; c < (enableCA ? 3 : 1); c++) { double Dx = Dxc * (s + chDist[c]); double Dy = Dyc * (s + chDist[c]); @@ -893,6 +941,11 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I double vignmul = 1.0; if (enableVignetting) { + const double vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale + const double vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale + const double vig_Dx = vig_x_d * cost - vig_y_d * sint; + const double vig_Dy = vig_x_d * sint + vig_y_d * cost; + const double r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy); if (darkening) { vignmul /= std::max (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001); } else { @@ -911,13 +964,13 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) { // all interpolation pixels inside image if (enableCA) { - interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, & (chTrans[c][y][x]), vignmul); + interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul); } else if (!highQuality) { transformed->r (y, x) = vignmul * (original->r (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r (yc, xc + 1) * Dx * (1.0 - Dy) + original->r (yc + 1, xc) * (1.0 - Dx) * Dy + original->r (yc + 1, xc + 1) * Dx * Dy); transformed->g (y, x) = vignmul * (original->g (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g (yc, xc + 1) * Dx * (1.0 - Dy) + original->g (yc + 1, xc) * (1.0 - Dx) * Dy + original->g (yc + 1, xc + 1) * Dx * Dy); transformed->b (y, x) = vignmul * (original->b (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b (yc, xc + 1) * Dx * (1.0 - Dy) + original->b (yc + 1, xc) * (1.0 - Dx) * Dy + original->b (yc + 1, xc + 1) * Dx * Dy); } else { - interpolateTransformCubic (original, xc - 1, yc - 1, Dx, Dy, & (transformed->r (y, x)), & (transformed->g (y, x)), & (transformed->b (y, x)), vignmul); + interpolateTransformCubic (original, xc - 1, yc - 1, Dx, Dy, transformed->r (y, x), transformed->g (y, x), transformed->b (y, x), vignmul); } } else { // edge pixels @@ -988,7 +1041,7 @@ void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *trans // multiplier for vignetting correction if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) { // all interpolation pixels inside image - interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, & (chTrans[c][y][x]), 1.0); + interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0); } else { // edge pixels int y1 = LIM (yc, 0, original->getHeight() - 1); From 5a5952dddbbeb5ba901950e43592aea338d22e60 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 27 Aug 2019 13:36:52 +0200 Subject: [PATCH 140/222] added two comments --- rtengine/iptransform.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 1d7ac9d56..9484599d6 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -90,6 +90,7 @@ float normn (float a, float b, int n) inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul) { + // I tried hand written SSE code but gcc vectorizes better constexpr float A = -0.85f; // Vertical @@ -122,6 +123,7 @@ inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, inline void interpolateTransformChannelsCubic(const float* const * src, int xs, int ys, float Dx, float Dy, float &dest, float mul) { + // I tried hand written SSE code but gcc vectorizes better constexpr float A = -0.85f; // Vertical From 4312e682657590ef8c30f4056baa49613bdd16ed Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 27 Aug 2019 19:59:10 +0200 Subject: [PATCH 141/222] SSE code for interpolateTransformCubic and interpolateTransformChannelsCubic, also some cleanups --- rtengine/iptransform.cc | 165 ++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 67 deletions(-) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 9484599d6..608fa0337 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -88,9 +88,34 @@ float normn (float a, float b, int n) } } +#ifdef __SSE2__ +inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul) +{ + constexpr float A = -0.85f; + + // Vertical + const float t1Vert = A * (Dy - Dy * Dy); + const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy; + const vfloat w3Vert = F2V(t1Vert * Dy); + const vfloat w2Vert = F2V(t1Vert * Dy - t1Vert + t2Vert); + const vfloat w1Vert = F2V(1.f - (t1Vert * Dy) - t2Vert); + const vfloat w0Vert = F2V(t1Vert - (t1Vert * Dy)); + + const vfloat rv = (w0Vert * LVFU(src->r(ys, xs)) + w1Vert * LVFU(src->r(ys + 1, xs))) + (w2Vert * LVFU(src->r(ys + 2, xs)) + w3Vert * LVFU(src->r(ys + 3, xs))); + const vfloat gv = (w0Vert * LVFU(src->g(ys, xs)) + w1Vert * LVFU(src->g(ys + 1, xs))) + (w2Vert * LVFU(src->g(ys + 2, xs)) + w3Vert * LVFU(src->g(ys + 3, xs))); + const vfloat bv = (w0Vert * LVFU(src->b(ys, xs)) + w1Vert * LVFU(src->b(ys + 1, xs))) + (w2Vert * LVFU(src->b(ys + 2, xs)) + w3Vert * LVFU(src->b(ys + 3, xs))); + + // Horizontal + const float t1Hor = A * (Dx - Dx * Dx); + const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx; + const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx)) * F2V(mul); + r = vhadd(weight * rv); + g = vhadd(weight * gv); + b = vhadd(weight * bv); +} +#else inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul) { - // I tried hand written SSE code but gcc vectorizes better constexpr float A = -0.85f; // Vertical @@ -120,10 +145,31 @@ inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, g = mul * (gv[0] * w0Hor + gv[1] * w1Hor + gv[2] * w2Hor + gv[3] * w3Hor); b = mul * (bv[0] * w0Hor + bv[1] * w1Hor + bv[2] * w2Hor + bv[3] * w3Hor); } - +#endif +#ifdef __SSE2__ +inline void interpolateTransformChannelsCubic(const float* const * src, int xs, int ys, float Dx, float Dy, float &dest, float mul) +{ + constexpr float A = -0.85f; + + // Vertical + const float t1Vert = A * (Dy - Dy * Dy); + const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy; + const vfloat w3Vert = F2V(t1Vert * Dy); + const vfloat w2Vert = F2V(t1Vert * Dy - t1Vert + t2Vert); + const vfloat w1Vert = F2V(1.f - (t1Vert * Dy) - t2Vert); + const vfloat w0Vert = F2V(t1Vert - (t1Vert * Dy)); + + const vfloat cv = (w0Vert * LVFU(src[ys][xs]) + w1Vert * LVFU(src[ys + 1][xs])) + (w2Vert * LVFU(src[ys + 2][xs]) + w3Vert * LVFU(src[ys + 3][xs])); + + // Horizontal + const float t1Hor = A * (Dx - Dx * Dx); + const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx; + const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx)); + dest = mul * vhadd(weight * cv); +} +#else inline void interpolateTransformChannelsCubic(const float* const * src, int xs, int ys, float Dx, float Dy, float &dest, float mul) { - // I tried hand written SSE code but gcc vectorizes better constexpr float A = -0.85f; // Vertical @@ -149,7 +195,7 @@ inline void interpolateTransformChannelsCubic(const float* const * src, int xs, dest = mul * (cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor); } - +#endif } @@ -817,69 +863,54 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I const double h2 = (double) oH / 2.0 - 0.5; double vig_w2, vig_h2, maxRadius, v, b, mul; - calcVignettingParams (oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); + calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); struct grad_params gp; if (enableGradient) { - calcGradientParams (oW, oH, params->gradient, gp); + calcGradientParams(oW, oH, params->gradient, gp); } struct pcv_params pcv; if (enablePCVignetting) { - calcPCVignetteParams (fW, fH, oW, oH, params->pcvignette, params->crop, pcv); + calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv); } - float** chOrig[3]; - chOrig[0] = original->r.ptrs; - chOrig[1] = original->g.ptrs; - chOrig[2] = original->b.ptrs; - - float** chTrans[3]; - chTrans[0] = transformed->r.ptrs; - chTrans[1] = transformed->g.ptrs; - chTrans[2] = transformed->b.ptrs; + float** chOrig[3] = {original->r.ptrs, original->g.ptrs, original->b.ptrs}; + float** chTrans[3] = {transformed->r.ptrs, transformed->g.ptrs, transformed->b.ptrs}; // auxiliary variables for c/a correction - double chDist[3]; - chDist[0] = enableCA ? params->cacorrection.red : 0.0; - chDist[1] = 0.0; - chDist[2] = enableCA ? params->cacorrection.blue : 0.0; + const double chDist[3] = {enableCA ? params->cacorrection.red : 0.0, 0.0, enableCA ? params->cacorrection.blue : 0.0}; // auxiliary variables for distortion correction const double distAmount = params->distortion.amount; // auxiliary variables for rotation - const double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0); - const double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0); + const double cost = cos(params->rotate.degree * rtengine::RT_PI / 180.0); + const double sint = sin(params->rotate.degree * rtengine::RT_PI / 180.0); // auxiliary variables for vertical perspective correction - double vpdeg = params->perspective.vertical / 100.0 * 45.0; - double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI; - double vpteta = fabs (vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt ((-SQR (oW * tan (vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) * - oW * tan (vpalpha) * sqrt (SQR (4 * maxRadius) + SQR (oW * tan (vpalpha)))) / (SQR (maxRadius) * 8))); - double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta); + const double vpdeg = params->perspective.vertical / 100.0 * 45.0; + const double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI; + const double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oW * tan(vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) * + oW * tan(vpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oW * tan(vpalpha)))) / (SQR(maxRadius) * 8))); + const double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos(vpteta), vptanpt = tan(vpteta); // auxiliary variables for horizontal perspective correction - double hpdeg = params->perspective.horizontal / 100.0 * 45.0; - double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI; - double hpteta = fabs (hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt ((-SQR (oH * tan (hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) * - oH * tan (hpalpha) * sqrt (SQR (4 * maxRadius) + SQR (oH * tan (hpalpha)))) / (SQR (maxRadius) * 8))); - double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); + const double hpdeg = params->perspective.horizontal / 100.0 * 45.0; + const double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI; + const double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oH * tan(hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) * + oH * tan(hpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oH * tan(hpalpha)))) / (SQR(maxRadius) * 8))); + const double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos(hpteta), hptanpt = tan(hpteta); - double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0; + const double ascale = params->commonTrans.autofill ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0; -#if defined( __GNUC__ ) && __GNUC__ >= 7// silence warning -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#endif -#if defined( __GNUC__ ) && __GNUC__ >= 7 -#pragma GCC diagnostic pop -#endif - // main cycle const bool darkening = (params->vignetting.amount <= 0.0); + const double centerFactorx = cx - w2; + const double centerFactory = cy - h2; + // main cycle #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) if(multiThread) #endif @@ -895,8 +926,8 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I y_d *= ascale; } - x_d += ascale * (cx - w2); // centering x coord & scale - y_d += ascale * (cy - h2); // centering y coord & scale + x_d += ascale * centerFactorx; // centering x coord & scale + y_d += ascale * centerFactory; // centering y coord & scale if (enablePerspective) { // horizontal perspective transformation @@ -909,15 +940,15 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I } // rotate - double Dxc = x_d * cost - y_d * sint; - double Dyc = x_d * sint + y_d * cost; + const double Dxc = x_d * cost - y_d * sint; + const double Dyc = x_d * sint + y_d * cost; // distortion correction double s = 1; if (enableDistortion) { - double r = sqrt (Dxc * Dxc + Dyc * Dyc) / maxRadius; // sqrt is slow - s = 1.0 - distAmount + distAmount * r ; + double r = sqrt(Dxc * Dxc + Dyc * Dyc) / maxRadius; + s = 1.0 - distAmount + distAmount * r; } for (int c = 0; c < (enableCA ? 3 : 1); c++) { @@ -947,46 +978,46 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I const double vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale const double vig_Dx = vig_x_d * cost - vig_y_d * sint; const double vig_Dy = vig_x_d * sint + vig_y_d * cost; - const double r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy); + const double r2 = sqrt(vig_Dx * vig_Dx + vig_Dy * vig_Dy); if (darkening) { - vignmul /= std::max (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001); + vignmul /= std::max(v + mul * tanh(b * (maxRadius - s * r2) / maxRadius), 0.001); } else { - vignmul *= (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius)); + vignmul *= (v + mul * tanh(b * (maxRadius - s * r2) / maxRadius)); } } if (enableGradient) { - vignmul *= calcGradientFactor (gp, cx + x, cy + y); + vignmul *= calcGradientFactor(gp, cx + x, cy + y); } if (enablePCVignetting) { - vignmul *= calcPCVignetteFactor (pcv, cx + x, cy + y); + vignmul *= calcPCVignetteFactor(pcv, cx + x, cy + y); } if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) { // all interpolation pixels inside image if (enableCA) { - interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul); + interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul); } else if (!highQuality) { - transformed->r (y, x) = vignmul * (original->r (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r (yc, xc + 1) * Dx * (1.0 - Dy) + original->r (yc + 1, xc) * (1.0 - Dx) * Dy + original->r (yc + 1, xc + 1) * Dx * Dy); - transformed->g (y, x) = vignmul * (original->g (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g (yc, xc + 1) * Dx * (1.0 - Dy) + original->g (yc + 1, xc) * (1.0 - Dx) * Dy + original->g (yc + 1, xc + 1) * Dx * Dy); - transformed->b (y, x) = vignmul * (original->b (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b (yc, xc + 1) * Dx * (1.0 - Dy) + original->b (yc + 1, xc) * (1.0 - Dx) * Dy + original->b (yc + 1, xc + 1) * Dx * Dy); + transformed->r(y, x) = vignmul * (original->r(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r(yc, xc + 1) * Dx * (1.0 - Dy) + original->r(yc + 1, xc) * (1.0 - Dx) * Dy + original->r(yc + 1, xc + 1) * Dx * Dy); + transformed->g(y, x) = vignmul * (original->g(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g(yc, xc + 1) * Dx * (1.0 - Dy) + original->g(yc + 1, xc) * (1.0 - Dx) * Dy + original->g(yc + 1, xc + 1) * Dx * Dy); + transformed->b(y, x) = vignmul * (original->b(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b(yc, xc + 1) * Dx * (1.0 - Dy) + original->b(yc + 1, xc) * (1.0 - Dx) * Dy + original->b(yc + 1, xc + 1) * Dx * Dy); } else { - interpolateTransformCubic (original, xc - 1, yc - 1, Dx, Dy, transformed->r (y, x), transformed->g (y, x), transformed->b (y, x), vignmul); + interpolateTransformCubic(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul); } } else { // edge pixels - int y1 = LIM (yc, 0, original->getHeight() - 1); - int y2 = LIM (yc + 1, 0, original->getHeight() - 1); - int x1 = LIM (xc, 0, original->getWidth() - 1); - int x2 = LIM (xc + 1, 0, original->getWidth() - 1); + int y1 = LIM(yc, 0, original->getHeight() - 1); + int y2 = LIM(yc + 1, 0, original->getHeight() - 1); + int x1 = LIM(xc, 0, original->getWidth() - 1); + int x2 = LIM(xc + 1, 0, original->getWidth() - 1); if (enableCA) { chTrans[c][y][x] = vignmul * (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy); } else { - transformed->r (y, x) = vignmul * (original->r (y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->r (y1, x2) * Dx * (1.0 - Dy) + original->r (y2, x1) * (1.0 - Dx) * Dy + original->r (y2, x2) * Dx * Dy); - transformed->g (y, x) = vignmul * (original->g (y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->g (y1, x2) * Dx * (1.0 - Dy) + original->g (y2, x1) * (1.0 - Dx) * Dy + original->g (y2, x2) * Dx * Dy); - transformed->b (y, x) = vignmul * (original->b (y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b (y1, x2) * Dx * (1.0 - Dy) + original->b (y2, x1) * (1.0 - Dx) * Dy + original->b (y2, x2) * Dx * Dy); + transformed->r(y, x) = vignmul * (original->r(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->r(y1, x2) * Dx * (1.0 - Dy) + original->r(y2, x1) * (1.0 - Dx) * Dy + original->r(y2, x2) * Dx * Dy); + transformed->g(y, x) = vignmul * (original->g(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->g(y1, x2) * Dx * (1.0 - Dy) + original->g(y2, x1) * (1.0 - Dx) * Dy + original->g(y2, x2) * Dx * Dy); + transformed->b(y, x) = vignmul * (original->b(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b(y1, x2) * Dx * (1.0 - Dy) + original->b(y2, x1) * (1.0 - Dx) * Dy + original->b(y2, x2) * Dx * Dy); } } } else { @@ -994,9 +1025,9 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I // not valid (source pixel x,y not inside source image, etc.) chTrans[c][y][x] = 0; } else { - transformed->r (y, x) = 0; - transformed->g (y, x) = 0; - transformed->b (y, x) = 0; + transformed->r(y, x) = 0; + transformed->g(y, x) = 0; + transformed->b(y, x) = 0; } } } From ba8c3d15bf5e553e3f28c5b323ca1a2793b082f0 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 28 Aug 2019 18:03:31 +0200 Subject: [PATCH 142/222] capture sharpening: do not trigger demosaic when changing adjusters --- rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 27 +++++---- rtengine/rawimagesource.cc | 109 ++++++++++++++++++++++++++++++---- rtengine/rawimagesource.h | 8 ++- rtengine/simpleprocess.cc | 2 +- rtgui/pdsharpening.cc | 10 ++-- 6 files changed, 128 insertions(+), 30 deletions(-) diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 46cbc28a6..1a5469744 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -83,7 +83,7 @@ public: virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {}; virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) {}; virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams& currentParams, std::array& newExps) { return false; }; - virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) {}; + virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) {}; virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; virtual void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) {}; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 7d485fd19..7496cb2aa 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -332,26 +332,31 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } 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; - imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic + imgsrc->demosaic(rp, autoContrast, contrastThreshold, params->pdsharpening.enabled); if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) { bayerAutoContrastListener->autoContrastChanged(contrastThreshold); } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) { xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); } - - if (params->pdsharpening.enabled) { - double pdSharpencontrastThreshold = params->pdsharpening.contrast; - imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold); - if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) { - pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold); - } - } - - // if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag todo |= M_INIT; + } + + if ((todo & M_INIT) && params->pdsharpening.enabled) { + double pdSharpencontrastThreshold = params->pdsharpening.contrast; + imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold); + if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) { + pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold); + } + } + + + if ((todo & M_RAW) + || (!highDetailRawComputed && highDetailNeeded) + || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) + || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { if (highDetailNeeded) { highDetailRawComputed = true; } else { diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 0602c770b..82863267f 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -45,6 +45,7 @@ #include #endif #include "opthelper.h" +#include "../rtgui/multilangmgr.h" #define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) #undef CLIPD #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) @@ -457,6 +458,9 @@ RawImageSource::RawImageSource () , green(0, 0) , red(0, 0) , blue(0, 0) + , greenCache(nullptr) + , redCache(nullptr) + , blueCache(nullptr) , rawDirty(true) , histMatchingParams(new procparams::ColorManagementParams) { @@ -474,6 +478,9 @@ RawImageSource::~RawImageSource () { delete idata; + delete redCache; + delete greenCache; + delete blueCache; for(size_t i = 0; i < numFrames; ++i) { delete riFrames[i]; @@ -1524,7 +1531,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold) +void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache) { MyTime t1, t2; t1.set(); @@ -1595,7 +1602,49 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c rgbSourceModified = false; - + if (cache) { + if (!redCache) { + redCache = new array2D(W, H); + greenCache = new array2D(W, H); + blueCache = new array2D(W, H); + } +#ifdef _OPENMP + #pragma omp parallel sections +#endif + { +#ifdef _OPENMP + #pragma omp section +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + (*redCache)[i][j] = red[i][j]; + } + } +#ifdef _OPENMP + #pragma omp section +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + (*greenCache)[i][j] = green[i][j]; + } + } +#ifdef _OPENMP + #pragma omp section +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + (*blueCache)[i][j] = blue[i][j]; + } + } + } + } else { + delete redCache; + redCache = nullptr; + delete greenCache; + greenCache = nullptr; + delete blueCache; + blueCache = nullptr; + } if( settings->verbose ) { if (getSensorType() == ST_BAYER) { printf("Demosaicing Bayer data: %s - %d usec\n", raw.bayersensor.method.c_str(), t2.etime(t1)); @@ -4954,6 +5003,12 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { BENCHFUN + + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(0.0); + } + const float xyz_rgb[3][3] = { // XYZ from RGB { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, @@ -4962,6 +5017,10 @@ BENCHFUN float contrast = conrastThreshold / 100.f; + array2D& redVals = redCache ? *redCache : red; + array2D& greenVals = greenCache ? *greenCache : green; + array2D& blueVals = blueCache ? *blueCache : blue; + if (showMask) { StopWatch Stop1("Show mask"); array2D& L = blue; // blue will be overridden anyway => we can use its buffer to store L @@ -4970,10 +5029,18 @@ BENCHFUN #endif for (int i = 0; i < H; ++i) { - Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); + Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); + } + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(0.1); } array2D& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(0.2); + } conrastThreshold = contrast * 100.f; #ifdef _OPENMP #pragma omp parallel for @@ -4983,6 +5050,10 @@ BENCHFUN red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f; } } + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(1.0); + } return; } @@ -4995,12 +5066,20 @@ BENCHFUN #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < H; ++i) { - Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); - Color::RGB2Y(red[i], green[i], blue[i], YOld[i], YNew[i], sharpeningParams.gamma, W); + Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); + Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], sharpeningParams.gamma, W); + } + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(0.1); } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(0.2); + } conrastThreshold = contrast * 100.f; Stop1.stop(); @@ -5008,6 +5087,10 @@ BENCHFUN ProcParams dummy; ImProcFunctions ipf(&dummy); ipf.deconvsharpening(YNew, tmp, blend, W, H, sharpeningParams, 1.0); + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(0.9); + } StopWatch Stop2("Y2RGB"); const float gamma = sharpeningParams.gamma; #ifdef _OPENMP @@ -5019,20 +5102,24 @@ BENCHFUN const vfloat gammav = F2V(gamma); for (; j < W - 3; j += 4) { const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); - STVFU(red[i][j], LVFU(red[i][j]) * factor); - STVFU(green[i][j], LVFU(green[i][j]) * factor); - STVFU(blue[i][j], LVFU(blue[i][j]) * factor); + STVFU(red[i][j], LVFU(redVals[i][j]) * factor); + STVFU(green[i][j], LVFU(greenVals[i][j]) * factor); + STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor); } #endif for (; j < W; ++j) { const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma); - red[i][j] *= factor; - green[i][j] *= factor; - blue[i][j] *= factor; + red[i][j] = redVals[i][j] * factor; + green[i][j] = greenVals[i][j] * factor; + blue[i][j] = blueVals[i][j] * factor; } } Stop2.stop(); + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(1.0); + } } void RawImageSource::cleanup () diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 8cf6b08a9..bbc15c448 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -88,6 +88,12 @@ protected: array2D red; // the interpolated blue plane: array2D blue; + // the interpolated green plane: + array2D* greenCache; + // the interpolated red plane: + array2D* redCache; + // the interpolated blue plane: + array2D* blueCache; bool rawDirty; float psRedBrightness[4]; float psGreenBrightness[4]; @@ -117,7 +123,7 @@ public: void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override; void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) override; bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) override; - void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) override; + void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) override; void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override; void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override; void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) override; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 0524734e0..1751a7cea 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -220,7 +220,7 @@ private: 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; - imgsrc->demosaic (params.raw, autoContrast, contrastThreshold); + imgsrc->demosaic (params.raw, autoContrast, contrastThreshold, params.pdsharpening.enabled && pl); if (params.pdsharpening.enabled) { imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast); } diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 5c14c052f..8e7c0e8b8 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -30,11 +30,11 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS { auto m = ProcEventMapper::getInstance(); - EvPdShrContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_CONTRAST"); - EvPdSharpenGamma = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_GAMMA"); - EvPdShrDRadius = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_RADIUS"); - EvPdShrDIterations = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); - EvPdShrAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); + EvPdShrContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_CONTRAST"); + EvPdSharpenGamma = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_GAMMA"); + EvPdShrDRadius = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_RADIUS"); + EvPdShrDIterations = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); + EvPdShrAutoContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); Gtk::HBox* hb = Gtk::manage(new Gtk::HBox()); hb->show(); From d3ec7f52773864d21c39c6ca5b930e576360dc6e Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 28 Aug 2019 19:26:09 +0200 Subject: [PATCH 143/222] capture sharpening: Do not trigger demosaic when toggling mask preview, #5412 --- rtengine/improccoordinator.cc | 2 +- rtengine/procevents.h | 1 + rtengine/rawimagesource.cc | 7 ------- rtengine/refreshmap.cc | 5 +++-- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 7496cb2aa..4b255d663 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1364,7 +1364,7 @@ ProcEvent ImProcCoordinator::setSharpMask (bool sharpMask) if (this->sharpMask != sharpMask) { sharpMaskChanged = true; this->sharpMask = sharpMask; - return params->pdsharpening.enabled ? rtengine::EvPdShrEnabled : rtengine::EvShrEnabled; + return params->pdsharpening.enabled ? rtengine::EvPdShrMaskToggled : rtengine::EvShrEnabled; } else { sharpMaskChanged = false; return rtengine::EvShrEnabled; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 670c0c102..d8491e533 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -521,6 +521,7 @@ enum ProcEventCode { EvRGBEnabled = 491, EvLEnabled = 492, EvPdShrEnabled = 493, + EvPdShrMaskToggled = 494, NUMOFEVENTS diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 82863267f..487bb1959 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -5032,13 +5032,11 @@ BENCHFUN Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); } if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.1); } array2D& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.2); } conrastThreshold = contrast * 100.f; @@ -5051,7 +5049,6 @@ BENCHFUN } } if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(1.0); } return; @@ -5070,14 +5067,12 @@ BENCHFUN Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], sharpeningParams.gamma, W); } if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.1); } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.2); } conrastThreshold = contrast * 100.f; @@ -5088,7 +5083,6 @@ BENCHFUN ImProcFunctions ipf(&dummy); ipf.deconvsharpening(YNew, tmp, blend, W, H, sharpeningParams, 1.0); if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.9); } StopWatch Stop2("Y2RGB"); @@ -5117,7 +5111,6 @@ BENCHFUN } Stop2.stop(); if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(1.0); } } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 8282f5b4b..56db1f71b 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -519,8 +519,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { HDR, // EvTMFattalAmount ALLNORAW, // EvWBEnabled RGBCURVE, // EvRGBEnabled - LUMINANCECURVE, // EvLEnabled - DEMOSAIC // EvPdShrEnabled + LUMINANCECURVE, // EvLEnabled + DEMOSAIC, // EvPdShrEnabled + ALLNORAW // EvPdShrMaskToggled }; From cca484f6c9251d4200c8c81e28e36e29fed3f469 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 28 Aug 2019 19:59:55 +0200 Subject: [PATCH 144/222] capture sharpening: reduce memory usage in preview mode, #5412 --- rtengine/rawimagesource.cc | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 487bb1959..2b45bfe38 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -5054,9 +5054,23 @@ BENCHFUN return; } - array2D L(W,H); - array2D YOld(W,H); - array2D YNew(W,H); + array2D* Lbuffer = nullptr; + if (!redCache) { + Lbuffer = new array2D(W, H); + } + + array2D* YOldbuffer = nullptr; + if (!greenCache) { + YOldbuffer = new array2D(W, H); + } + + array2D* YNewbuffer = nullptr; + if (!blueCache) { + YNewbuffer = new array2D(W, H); + } + array2D& L = Lbuffer ? *Lbuffer : red; + array2D& YOld = YOldbuffer ? * YOldbuffer : green; + array2D& YNew = YNewbuffer ? * YNewbuffer : blue; StopWatch Stop1("rgb2YL"); #ifdef _OPENMP @@ -5110,6 +5124,9 @@ BENCHFUN } } Stop2.stop(); + delete Lbuffer; + delete YOldbuffer; + delete YNewbuffer; if (plistener) { plistener->setProgress(1.0); } From b72d4e27eb935e2894933016587a1bd386b5539c Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 29 Aug 2019 13:02:54 +0200 Subject: [PATCH 145/222] capture sharpening: early exit if Autocontrast is changed from true to false, #5412 --- rtengine/rawimagesource.cc | 7 ++++++- rtengine/rawimagesource.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 2b45bfe38..3cab9b6b1 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -461,6 +461,7 @@ RawImageSource::RawImageSource () , greenCache(nullptr) , redCache(nullptr) , blueCache(nullptr) + , captureSharpeningAutoContrast(false) , rawDirty(true) , histMatchingParams(new procparams::ColorManagementParams) { @@ -5003,7 +5004,11 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { BENCHFUN - + if (!sharpeningParams.autoContrast && captureSharpeningAutoContrast) { + captureSharpeningAutoContrast = false; + return; + } + captureSharpeningAutoContrast = sharpeningParams.autoContrast; if (plistener) { plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.0); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index bbc15c448..cebedd32f 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -94,6 +94,7 @@ protected: array2D* redCache; // the interpolated blue plane: array2D* blueCache; + bool captureSharpeningAutoContrast; bool rawDirty; float psRedBrightness[4]; float psGreenBrightness[4]; From 205db936f9a3f5556e442e2a57820ca3ecea0e3f Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 29 Aug 2019 13:58:46 +0200 Subject: [PATCH 146/222] Revert "capture sharpening: early exit if Autocontrast is changed from true to false, #5412" This reverts commit b72d4e27eb935e2894933016587a1bd386b5539c. --- rtengine/rawimagesource.cc | 7 +------ rtengine/rawimagesource.h | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 3cab9b6b1..2b45bfe38 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -461,7 +461,6 @@ RawImageSource::RawImageSource () , greenCache(nullptr) , redCache(nullptr) , blueCache(nullptr) - , captureSharpeningAutoContrast(false) , rawDirty(true) , histMatchingParams(new procparams::ColorManagementParams) { @@ -5004,11 +5003,7 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { BENCHFUN - if (!sharpeningParams.autoContrast && captureSharpeningAutoContrast) { - captureSharpeningAutoContrast = false; - return; - } - captureSharpeningAutoContrast = sharpeningParams.autoContrast; + if (plistener) { plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.0); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index cebedd32f..bbc15c448 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -94,7 +94,6 @@ protected: array2D* redCache; // the interpolated blue plane: array2D* blueCache; - bool captureSharpeningAutoContrast; bool rawDirty; float psRedBrightness[4]; float psGreenBrightness[4]; From 1ff505432c4496b71bf03db35f5fde19cc1eecaa Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 29 Aug 2019 21:04:56 +0200 Subject: [PATCH 147/222] Do not treat changes of tonecurve.fromHistMatching as related to panning --- rtengine/improccoordinator.cc | 2 +- rtengine/procparams.cc | 23 +++++++++++++++++++++++ rtengine/procparams.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 6f471eedf..766c7ba84 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1514,7 +1514,7 @@ void ImProcCoordinator::process() while (changeSinceLast) { const bool panningRelatedChange = - params->toneCurve != nextParams->toneCurve + params->toneCurve.isPanningRelatedChange(nextParams->toneCurve) || params->labCurve != nextParams->labCurve || params->localContrast != nextParams->localContrast || params->rgbCurves != nextParams->rgbCurves diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 66837f89b..9fbc260ce 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -330,6 +330,29 @@ ToneCurveParams::ToneCurveParams() : { } +bool ToneCurveParams::isPanningRelatedChange(const ToneCurveParams& other) const +{ + return ! + (autoexp == other.autoexp + && clip == other.clip + && hrenabled == other.hrenabled + && method == other.method + && expcomp == other.expcomp + && curve == other.curve + && curve2 == other.curve2 + && curveMode == other.curveMode + && curveMode2 == other.curveMode2 + && brightness == other.brightness + && black == other.black + && contrast == other.contrast + && saturation == other.saturation + && shcompr == other.shcompr + && hlcompr == other.hlcompr + && hlcomprthresh == other.hlcomprthresh + && histmatching == other.histmatching + && clampOOG == other.clampOOG); +} + bool ToneCurveParams::operator ==(const ToneCurveParams& other) const { return diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 369af85fa..2d042f571 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -284,6 +284,7 @@ struct ToneCurveParams { ToneCurveParams(); + bool isPanningRelatedChange(const ToneCurveParams& other) const; bool operator ==(const ToneCurveParams& other) const; bool operator !=(const ToneCurveParams& other) const; From df8367558ba81c34a8fb67852685f2ec4e97349b Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 29 Aug 2019 22:07:15 +0200 Subject: [PATCH 148/222] Do not treat white balance changes as related to panning if before and after uses camera whitebalance --- rtengine/improccoordinator.cc | 2 +- rtengine/procparams.cc | 15 +++++++++++++++ rtengine/procparams.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 766c7ba84..daadcb16c 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1520,7 +1520,7 @@ void ImProcCoordinator::process() || params->rgbCurves != nextParams->rgbCurves || params->colorToning != nextParams->colorToning || params->vibrance != nextParams->vibrance - || params->wb != nextParams->wb + || params->wb.isPanningRelatedChange(nextParams->wb) || params->colorappearance != nextParams->colorappearance || params->epd != nextParams->epd || params->fattal != nextParams->fattal diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9fbc260ce..f14d72871 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1233,6 +1233,21 @@ WBParams::WBParams() : { } +bool WBParams::isPanningRelatedChange(const WBParams& other) const +{ + return ! + (enabled == other.enabled + && ((method == "Camera" && other.method == "Camera") + || + (method == other.method + && temperature == other.temperature + && green == other.green + && equal == other.equal + && tempBias == other.tempBias) + ) + ); +} + bool WBParams::operator ==(const WBParams& other) const { return diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2d042f571..6ae807d7e 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -598,6 +598,7 @@ struct WBParams { WBParams(); + bool isPanningRelatedChange(const WBParams& other) const; bool operator ==(const WBParams& other) const; bool operator !=(const WBParams& other) const; From 48bcf9e71a1348a15f91bd92285638edd97bd93e Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 29 Aug 2019 22:46:09 +0200 Subject: [PATCH 149/222] Fix broken export when filmnegative was used on xtrans files --- rtengine/simpleprocess.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1751a7cea..b14b4435d 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -210,7 +210,7 @@ private: imgsrc->preprocess ( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); // After preprocess, run film negative processing if enabled - if (imgsrc->getSensorType() == ST_BAYER && params.filmNegative.enabled) { + if ((imgsrc->getSensorType() == ST_BAYER || (imgsrc->getSensorType() == ST_FUJI_XTRANS)) && params.filmNegative.enabled) { imgsrc->filmNegativeProcess (params.filmNegative); } From a5cba6261a59e37e9c9e9ae6ddf15c09469ccdb1 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 29 Aug 2019 22:50:45 +0200 Subject: [PATCH 150/222] Fix broken export when filmnegative was used on xtrans files --- rtengine/simpleprocess.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 2d594e0af..8d24514d6 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -210,7 +210,7 @@ private: imgsrc->preprocess ( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); // After preprocess, run film negative processing if enabled - if (imgsrc->getSensorType() == ST_BAYER && params.filmNegative.enabled) { + if ((imgsrc->getSensorType() == ST_BAYER || (imgsrc->getSensorType() == ST_FUJI_XTRANS)) && params.filmNegative.enabled) { imgsrc->filmNegativeProcess (params.filmNegative); } From f882309f594444abcce2df5eee6f8c8969822e06 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 30 Aug 2019 14:45:45 +0200 Subject: [PATCH 151/222] capture sharpening: own compilation unit, smooth progressbar, #5412 --- rtengine/CMakeLists.txt | 1 + rtengine/capturesharpening.cc | 218 ++++++++++++++++++++++++++++++++++ rtengine/imagesource.h | 4 +- rtengine/procparams.cc | 32 ++++- rtengine/procparams.h | 16 ++- rtengine/rawimagesource.cc | 138 +-------------------- rtengine/rawimagesource.h | 2 +- rtengine/stdimagesource.h | 2 +- rtgui/paramsedited.cc | 7 +- rtgui/paramsedited.h | 11 +- 10 files changed, 277 insertions(+), 154 deletions(-) create mode 100644 rtengine/capturesharpening.cc diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index c5c8afa82..f52cfa256 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -32,6 +32,7 @@ set(CAMCONSTSFILE "camconst.json") set(RTENGINESOURCEFILES badpixels.cc CA_correct_RT.cc + capturesharpening.cc EdgePreservingDecomposition.cc FTblockDN.cc PF_correct_RT.cc diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc new file mode 100644 index 000000000..71cefaca6 --- /dev/null +++ b/rtengine/capturesharpening.cc @@ -0,0 +1,218 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Ingo Weyrich (heckflosse67@gmx.de) + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . +*/ +#include +#include + +#include "jaggedarray.h" +#include "rtengine.h" +#include "rawimagesource.h" +#include "rt_math.h" +#include "improcfun.h" +#include "procparams.h" +#include "color.h" +#include "gauss.h" +#include "rt_algo.h" +#define BENCHMARK +#include "StopWatch.h" +#ifdef _OPENMP +#include +#endif +#include "opthelper.h" +#include "../rtgui/multilangmgr.h" + +namespace { +void CaptureDeconvSharpening (float** luminance, float** tmp, const float * const * blend, int W, int H, double sigma, int iterations, rtengine::ProgressListener* plistener, double start, double step) +{ + + rtengine::JaggedArray tmpI(W, H); + +#ifdef _OPENMP + #pragma omp parallel +#endif + { +#ifdef _OPENMP + #pragma omp for +#endif + for (int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + tmpI[i][j] = max(luminance[i][j], 0.f); + } + } + + for (int k = 0; k < iterations; k++) { + // apply gaussian blur and divide luminance by result of gaussian blur + gaussianBlur(tmpI, tmp, W, H, sigma, nullptr, GAUSS_DIV, luminance); + gaussianBlur(tmp, tmpI, W, H, sigma, nullptr, GAUSS_MULT); + if (plistener) { +#ifdef _OPENMP + #pragma omp single +#endif + start += step; + plistener->setProgress(start); + } + } // end for + +#ifdef _OPENMP + #pragma omp for +#endif + + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + luminance[i][j] = rtengine::intp(blend[i][j], max(tmpI[i][j], 0.0f), luminance[i][j]); + } + } + } // end parallel +} + +} + +namespace rtengine +{ + +void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { +BENCHFUN + + + if (plistener) { + plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); + plistener->setProgress(0.0); + } + + const float xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } + }; + + float contrast = conrastThreshold / 100.f; + + array2D& redVals = redCache ? *redCache : red; + array2D& greenVals = greenCache ? *greenCache : green; + array2D& blueVals = blueCache ? *blueCache : blue; + + if (showMask) { + StopWatch Stop1("Show mask"); + array2D& L = blue; // blue will be overridden anyway => we can use its buffer to store L +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H; ++i) { + Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); + } + if (plistener) { + plistener->setProgress(0.1); + } + array2D& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask + buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + if (plistener) { + plistener->setProgress(0.2); + } + conrastThreshold = contrast * 100.f; +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f; + } + } + if (plistener) { + plistener->setProgress(1.0); + } + return; + } + + array2D* Lbuffer = nullptr; + if (!redCache) { + Lbuffer = new array2D(W, H); + } + + array2D* YOldbuffer = nullptr; + if (!greenCache) { + YOldbuffer = new array2D(W, H); + } + + array2D* YNewbuffer = nullptr; + if (!blueCache) { + YNewbuffer = new array2D(W, H); + } + array2D& L = Lbuffer ? *Lbuffer : red; + array2D& YOld = YOldbuffer ? * YOldbuffer : green; + array2D& YNew = YNewbuffer ? * YNewbuffer : blue; + + StopWatch Stop1("rgb2YL"); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int i = 0; i < H; ++i) { + Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); + Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], sharpeningParams.gamma, W); + } + if (plistener) { + plistener->setProgress(0.1); + } + // calculate contrast based blend factors to reduce sharpening in regions with low contrast + JaggedArray blend(W, H); + buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + if (plistener) { + plistener->setProgress(0.2); + } + conrastThreshold = contrast * 100.f; + + Stop1.stop(); + array2D& tmp = L; // L is not used anymore now => we can use its buffer as the needed temporary buffer + CaptureDeconvSharpening(YNew, tmp, blend, W, H, sharpeningParams.deconvradius, sharpeningParams.deconviter, plistener, 0.2, (0.9 - 0.2) / sharpeningParams.deconviter); + if (plistener) { + plistener->setProgress(0.9); + } + StopWatch Stop2("Y2RGB"); + const float gamma = sharpeningParams.gamma; +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int i = 0; i < H; ++i) { + int j = 0; +#ifdef __SSE2__ + const vfloat gammav = F2V(gamma); + for (; j < W - 3; j += 4) { + const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); + STVFU(red[i][j], LVFU(redVals[i][j]) * factor); + STVFU(green[i][j], LVFU(greenVals[i][j]) * factor); + STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor); + } + +#endif + for (; j < W; ++j) { + const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma); + red[i][j] = redVals[i][j] * factor; + green[i][j] = greenVals[i][j] * factor; + blue[i][j] = blueVals[i][j] * factor; + } + } + Stop2.stop(); + delete Lbuffer; + delete YOldbuffer; + delete YNewbuffer; + if (plistener) { + plistener->setProgress(1.0); + } +} + +} /* namespace */ diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 1a5469744..64bb53a49 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -46,7 +46,7 @@ struct LensProfParams; struct RAWParams; struct RetinexParams; struct ToneCurveParams; -struct SharpeningParams; +struct CaptureSharpeningParams; } class ImageMatrices @@ -182,7 +182,7 @@ public: return this; } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; - virtual void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) = 0; + virtual void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) = 0; }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 60b95a2e8..d88892a3b 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1149,6 +1149,32 @@ bool SharpeningParams::operator !=(const SharpeningParams& other) const return !(*this == other); } +CaptureSharpeningParams::CaptureSharpeningParams() : + enabled(false), + autoContrast(true), + contrast(10.0), + gamma(1.35), + deconvradius(0.75), + deconviter(30) +{ +} + +bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) const +{ + return + enabled == other.enabled + && contrast == other.contrast + && gamma == other.gamma + && autoContrast == other.autoContrast + && deconvradius == other.deconvradius + && deconviter == other.deconviter; +} + +bool CaptureSharpeningParams::operator !=(const CaptureSharpeningParams& other) const +{ + return !(*this == other); +} + SharpenEdgeParams::SharpenEdgeParams() : enabled(false), passes(2), @@ -2830,12 +2856,6 @@ void ProcParams::setDefaults() prsharpening.deconvdamping = 0; pdsharpening = {}; - pdsharpening.contrast = 10.0; - pdsharpening.autoContrast = true; - prsharpening.method = "rld"; - pdsharpening.gamma = 1.35; - pdsharpening.deconvradius = 0.75; - pdsharpening.deconviter = 30; vibrance = {}; diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 4be6de254..cbcec0e18 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -542,6 +542,20 @@ struct SharpenMicroParams { bool operator !=(const SharpenMicroParams& other) const; }; +struct CaptureSharpeningParams { + bool enabled; + bool autoContrast; + double contrast; + double gamma; + double deconvradius; + int deconviter; + + CaptureSharpeningParams(); + + bool operator ==(const CaptureSharpeningParams& other) const; + bool operator !=(const CaptureSharpeningParams& other) const; +}; + /** * Parameters of the vibrance */ @@ -1530,7 +1544,7 @@ public: ColorToningParams colorToning; ///< Color Toning parameters SharpeningParams sharpening; ///< Sharpening parameters SharpeningParams prsharpening; ///< Sharpening parameters for post resize sharpening - SharpeningParams pdsharpening; ///< Sharpening parameters for post demosaic sharpening + CaptureSharpeningParams pdsharpening; ///< Sharpening parameters for post demosaic sharpening SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters VibranceParams vibrance; ///< Vibrance parameters diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 2b45bfe38..931a46ede 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -38,14 +38,12 @@ #include "camconst.h" #include "procparams.h" #include "color.h" -#include "rt_algo.h" -#define BENCHMARK -#include "StopWatch.h" +//#define BENCHMARK +//#include "StopWatch.h" #ifdef _OPENMP #include #endif #include "opthelper.h" -#include "../rtgui/multilangmgr.h" #define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) #undef CLIPD #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) @@ -5000,138 +4998,6 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int } } -void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { -BENCHFUN - - - if (plistener) { - plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); - plistener->setProgress(0.0); - } - - const float xyz_rgb[3][3] = { // XYZ from RGB - { 0.412453, 0.357580, 0.180423 }, - { 0.212671, 0.715160, 0.072169 }, - { 0.019334, 0.119193, 0.950227 } - }; - - float contrast = conrastThreshold / 100.f; - - array2D& redVals = redCache ? *redCache : red; - array2D& greenVals = greenCache ? *greenCache : green; - array2D& blueVals = blueCache ? *blueCache : blue; - - if (showMask) { - StopWatch Stop1("Show mask"); - array2D& L = blue; // blue will be overridden anyway => we can use its buffer to store L -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = 0; i < H; ++i) { - Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); - } - if (plistener) { - plistener->setProgress(0.1); - } - array2D& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask - buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); - if (plistener) { - plistener->setProgress(0.2); - } - conrastThreshold = contrast * 100.f; -#ifdef _OPENMP - #pragma omp parallel for -#endif - for (int i = 0; i < H; ++i) { - for (int j = 0; j < W; ++j) { - red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f; - } - } - if (plistener) { - plistener->setProgress(1.0); - } - return; - } - - array2D* Lbuffer = nullptr; - if (!redCache) { - Lbuffer = new array2D(W, H); - } - - array2D* YOldbuffer = nullptr; - if (!greenCache) { - YOldbuffer = new array2D(W, H); - } - - array2D* YNewbuffer = nullptr; - if (!blueCache) { - YNewbuffer = new array2D(W, H); - } - array2D& L = Lbuffer ? *Lbuffer : red; - array2D& YOld = YOldbuffer ? * YOldbuffer : green; - array2D& YNew = YNewbuffer ? * YNewbuffer : blue; - - StopWatch Stop1("rgb2YL"); -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, 16) -#endif - for (int i = 0; i < H; ++i) { - Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); - Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], sharpeningParams.gamma, W); - } - if (plistener) { - plistener->setProgress(0.1); - } - // calculate contrast based blend factors to reduce sharpening in regions with low contrast - JaggedArray blend(W, H); - buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); - if (plistener) { - plistener->setProgress(0.2); - } - conrastThreshold = contrast * 100.f; - - Stop1.stop(); - array2D& tmp = L; // L is not used anymore now => we can use its buffer as the needed temporary buffer - ProcParams dummy; - ImProcFunctions ipf(&dummy); - ipf.deconvsharpening(YNew, tmp, blend, W, H, sharpeningParams, 1.0); - if (plistener) { - plistener->setProgress(0.9); - } - StopWatch Stop2("Y2RGB"); - const float gamma = sharpeningParams.gamma; -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, 16) -#endif - for (int i = 0; i < H; ++i) { - int j = 0; -#ifdef __SSE2__ - const vfloat gammav = F2V(gamma); - for (; j < W - 3; j += 4) { - const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); - STVFU(red[i][j], LVFU(redVals[i][j]) * factor); - STVFU(green[i][j], LVFU(greenVals[i][j]) * factor); - STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor); - } - -#endif - for (; j < W; ++j) { - const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma); - red[i][j] = redVals[i][j] * factor; - green[i][j] = greenVals[i][j] * factor; - blue[i][j] = blueVals[i][j] * factor; - } - } - Stop2.stop(); - delete Lbuffer; - delete YOldbuffer; - delete YNewbuffer; - if (plistener) { - plistener->setProgress(1.0); - } -} - void RawImageSource::cleanup () { delete phaseOneIccCurve; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index bbc15c448..5e1c9b424 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -311,7 +311,7 @@ protected: void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; - void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override; + void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override; }; } diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 175f664f8..6b4a67773 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -102,7 +102,7 @@ public: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;} void flushRGB () override; - void captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override {}; + void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override {}; }; } #endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 4029d0b9b..db0c24123 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -169,7 +169,6 @@ void ParamsEdited::set(bool v) pdsharpening.contrast = v; pdsharpening.autoContrast = v; pdsharpening.gamma = v; - pdsharpening.deconvamount = v; pdsharpening.deconvradius = v; pdsharpening.deconviter = v; prsharpening.enabled = v; @@ -1733,10 +1732,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.autoContrast = mods.pdsharpening.autoContrast; } - if (pdsharpening.deconvamount) { - toEdit.pdsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.pdsharpening.deconvamount + mods.pdsharpening.deconvamount : mods.pdsharpening.deconvamount; - } - if (pdsharpening.gamma) { toEdit.pdsharpening.gamma = dontforceSet && options.baBehav[ADDSET_SHARP_GAMMA] ? toEdit.pdsharpening.gamma + mods.pdsharpening.gamma : mods.pdsharpening.gamma; } @@ -3292,7 +3287,7 @@ bool FilmNegativeParamsEdited::isUnchanged() const return enabled && redRatio && greenExp && blueRatio; } -bool SharpeningParamsEdited::isUnchanged() const +bool CaptureSharpeningParamsEdited::isUnchanged() const { return enabled && contrast && autoContrast && gamma && deconvradius && deconviter; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 6d229e689..c697aaacd 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -196,6 +196,15 @@ struct SharpeningParamsEdited { bool deconvradius; bool deconviter; bool deconvdamping; +}; + +struct CaptureSharpeningParamsEdited { + bool enabled; + bool contrast; + bool autoContrast; + bool gamma; + bool deconvradius; + bool deconviter; bool isUnchanged() const; }; @@ -687,7 +696,7 @@ struct ParamsEdited { ColorToningEdited colorToning; RetinexParamsEdited retinex; SharpeningParamsEdited sharpening; - SharpeningParamsEdited pdsharpening; + CaptureSharpeningParamsEdited pdsharpening; SharpeningParamsEdited prsharpening; SharpenEdgeParamsEdited sharpenEdge; SharpenMicroParamsEdited sharpenMicro; From a060b57ff607bf595c7e1e154ada078b40d85edf Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Tue, 27 Aug 2019 17:44:35 -0400 Subject: [PATCH 152/222] rtgui/thumbbrowserbase - Improve behavior with smooth scrolling devices Devices such as trackpads will emit smooth scrolling (GDK_SMOOTH_SCROLL) events with deltas smaller than +/-1.0 at high frequency. Quantizing these to +/-1.0 leads to significant amplification of scroll speed to the point of unusability Scroll by delta instead of +/-1.0 in these cases, permitting smooth scrolling through thumbnails Some mice emit GDK_SMOOTH_SCROLL with deltas of +/-1.0 per detent. This patch will not change behavior with such devices. However, if any mice emit deltas of smaller magnitude, the per-detent behavior will change. --- rtgui/thumbbrowserbase.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index caf7d7b97..13709d8f7 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -79,10 +79,19 @@ void ThumbBrowserBase::scroll (int direction, double deltaX, double deltaY) delta = deltaY; } if (direction == GDK_SCROLL_SMOOTH && delta == 0.0) { - // sometimes this case happens. To avoid scrolling the wrong direction in this case, we just do nothing + // sometimes this case happens. To avoid scrolling the wrong direction in this case, we just do nothing + // This is probably no longer necessary now that coef is no longer quantized to +/-1.0 but why waste CPU cycles? return; } - double coef = direction == GDK_SCROLL_DOWN || (direction == GDK_SCROLL_SMOOTH && delta > 0.0) ? +1.0 : -1.0; + //GDK_SCROLL_SMOOTH can come in as many events with small deltas, don't quantize these to +/-1.0 so trackpads work well + double coef; + if(direction == GDK_SCROLL_SMOOTH) { + coef = delta; + } else if (direction == GDK_SCROLL_DOWN) { + coef = +1.0; + } else { + coef = -1.0; + } // GUI already acquired when here if (direction == GDK_SCROLL_UP || direction == GDK_SCROLL_DOWN || direction == GDK_SCROLL_SMOOTH) { From dadf01fe95b9f7ef61226703b1071e037dd553d1 Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Wed, 28 Aug 2019 18:19:53 -0400 Subject: [PATCH 153/222] rtgui/guiutils - Improve behavior with smooth scrolling devices Devices such as trackpads will emit smooth scrolling (GDK_SMOOTH_SCROLL) events with deltas smaller than +/-1.0 at high frequency. Quantizing these to +/-1.0 leads to significant amplification of scroll speed to the point of unusability Scroll by delta instead of +/-1.0 in these cases, permitting smooth scrolling through panels that use this code Some mice emit GDK_SMOOTH_SCROLL with deltas of +/-1.0 per detent. This patch will not change behavior with such devices. However, if any mice emit deltas of smaller magnitude, the per-detent behavior will change. --- rtgui/guiutils.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index ec0bf6588..19762fd92 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -971,9 +971,8 @@ bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { - if (abs(event->delta_y) > 0.1) { - value2 = rtengine::LIM(value + (event->delta_y > 0 ? step : -step), lowerBound, upperBound); - } + value2 = rtengine::LIM(value + event->delta_y * step, lowerBound, upperBound); + if (value2 != value) { scroll->set_value(value2); } From 1a6d1b038fa446d60715838344dd8cb25356d05b Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Wed, 28 Aug 2019 18:40:00 -0400 Subject: [PATCH 154/222] rtgui/cropwindow: Improve behavior with smooth scrolling devices Accumulate/coalesce GDK_SCROLL_SMOOTH events until we equal or exceed +/-1.0 This avoids having one zoom adjustment for every single event which makes touchpad zooming unusable due to frequent small deltas This makes trackpad zooming usable while having no effect on mice that emit GDK_SMOOTH_SCROLL with values of +/-1.0 instead of GDK_SCROLL_UP and GDK_SCROLL_DOWN If any mice exist that have scroll wheel detents but emit smaller values per detent, this may have the negative effect of requiring multiple detents per zoom level. It remains to be seen whether any mice behave like this. The discrete step implementation of zoomSteps requires us to coalesce events instead of smoothly zooming in and out. --- rtgui/cropwindow.cc | 15 ++++++++++----- rtgui/cropwindow.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 575afd54b..1364855b0 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -51,7 +51,7 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet backColor(options.bgcolor), decorated(true), isFlawnOver(false), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3), upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), width(0), height(0), imgAreaX(0), imgAreaY(0), imgAreaW(0), imgAreaH(0), imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr), - pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr), + pmlistener(nullptr), pmhlistener(nullptr), scrollAccum(0.0), observedCropWin(nullptr), crop_custom_ratio(0.f) { initZoomSteps(); @@ -295,11 +295,16 @@ void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y, } else { delta = deltaY; } - if (delta == 0.0 && direction == GDK_SCROLL_SMOOTH) { - // sometimes this case happens. To avoid zooming into the wrong direction in this case, we just do nothing - return; + + if (direction == GDK_SCROLL_SMOOTH) { + scrollAccum += delta; + //Only change zoom level if we've accumulated +/- 1.0 of deltas. This conditional handles the previous delta=0.0 case + if (abs(scrollAccum) < 1.0) { + return; + } } - bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && delta < 0.0); + bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && scrollAccum < 0.0); + scrollAccum = 0.0; if ((state & GDK_CONTROL_MASK) && onArea(ColorPicker, x, y)) { // resizing a color picker if (isUp) { diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 26edf69ee..8c944cf0a 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -102,6 +102,7 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed PointerMotionListener* pmlistener; PointerMotionListener* pmhlistener; std::list listeners; + double scrollAccum; CropWindow* observedCropWin; // Pointer to the currently active detail CropWindow From 5ea18efeb862ec323e57eace05f98eec83812776 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 1 Sep 2019 20:22:42 +0200 Subject: [PATCH 155/222] RT crashes on loading Hasselblad H6D-100cMS pixelshift files, fixes #5433 --- rtengine/rawimagesource.cc | 36 ++++++++++++++++++++++++++++++++++-- rtengine/rawimagesource.h | 6 +++--- rtengine/rtthumbnail.cc | 11 +++++++++++ rtgui/bayerprocess.cc | 2 +- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index e8eb17c31..838d49ce9 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -999,11 +999,43 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) if (errCode) { return errCode; } - numFrames = firstFrameOnly ? 1 : ri->getFrameCount(); + numFrames = firstFrameOnly ? (numFrames < 7 ? 1 : ri->getFrameCount()) : ri->getFrameCount(); errCode = 0; - if(numFrames > 1) { + if(numFrames >= 7) { + // special case to avoid crash when loading Hasselblad H6D-100cMS pixelshift files + // limit to 6 frames and skip first frame, as first frame is not bayer + if (firstFrameOnly) { + numFrames = 1; + } else { + numFrames = 6; + } +#ifdef _OPENMP99 + #pragma omp parallel +#endif + { + int errCodeThr = 0; +#ifdef _OPENMP99 + #pragma omp for nowait +#endif + for(unsigned int i = 0; i < numFrames; ++i) { + if(i == 0) { + riFrames[i] = ri; + errCodeThr = riFrames[i]->loadRaw (true, i + 1, true, plistener, 0.8); + } else { + riFrames[i] = new RawImage(fname); + errCodeThr = riFrames[i]->loadRaw (true, i + 1); + } + } +#ifdef _OPENMP99 + #pragma omp critical +#endif + { + errCode = errCodeThr ? errCodeThr : errCode; + } + } + } else if(numFrames > 1) { #ifdef _OPENMP #pragma omp parallel #endif diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 7c50991c0..940773271 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -74,13 +74,13 @@ protected: bool rgbSourceModified; RawImage* ri; // Copy of raw pixels, NOT corrected for initial gain, blackpoint etc. - RawImage* riFrames[4] = {nullptr}; + RawImage* riFrames[6] = {nullptr}; unsigned int currFrame = 0; unsigned int numFrames = 0; int flatFieldAutoClipValue = 0; array2D rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column - array2D *rawDataFrames[4] = {nullptr}; - array2D *rawDataBuffer[3] = {nullptr}; + array2D *rawDataFrames[6] = {nullptr}; + array2D *rawDataBuffer[5] = {nullptr}; // the interpolated green plane: array2D green; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 2a35176e6..5efb75d48 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -547,6 +547,17 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati return nullptr; } + if (ri->getFrameCount() == 7) { + // special case for Hasselblad H6D-100cMS pixelshift files + // first frame is not bayer, load second frame + int r = ri->loadRaw (1, 1, 0); + + if ( r ) { + delete ri; + sensorType = ST_NONE; + return nullptr; + } + } sensorType = ri->getSensorType(); int width = ri->get_width(); diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 6f38f4c43..c361ded16 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -729,7 +729,7 @@ void BayerProcess::FrameCountChanged(int n, int frameNum) imageNumber->remove_all(); imageNumber->append("1"); - for (int i = 2; i <= std::min(n, 4); ++i) { + for (int i = 2; i <= std::min(n, 6); ++i) { std::ostringstream entry; entry << i; imageNumber->append(entry.str()); From bb97a30058b38d34f33fc388ecf3a7d6156ffbbb Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 1 Sep 2019 21:39:28 +0200 Subject: [PATCH 156/222] Update rawimagesource.cc Enable parallel decoding for Hasselblad H6D-100cMS pixelshift frames --- rtengine/rawimagesource.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 838d49ce9..a1762af93 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1011,12 +1011,12 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) } else { numFrames = 6; } -#ifdef _OPENMP99 +#ifdef _OPENMP #pragma omp parallel #endif { int errCodeThr = 0; -#ifdef _OPENMP99 +#ifdef _OPENMP #pragma omp for nowait #endif for(unsigned int i = 0; i < numFrames; ++i) { @@ -1028,7 +1028,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) errCodeThr = riFrames[i]->loadRaw (true, i + 1); } } -#ifdef _OPENMP99 +#ifdef _OPENMP #pragma omp critical #endif { From fb51c4ca920f840d250938324f64ac06f828d3c5 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 3 Sep 2019 17:08:37 +0200 Subject: [PATCH 157/222] capture sharpening: Fix crash when using gamma < 1.0, #5412 --- rtengine/capturesharpening.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 71cefaca6..eb95d2633 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -192,7 +192,7 @@ BENCHFUN #ifdef __SSE2__ const vfloat gammav = F2V(gamma); for (; j < W - 3; j += 4) { - const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); + const vfloat factor = pow_F(vmaxf(LVFU(YNew[i][j]), ZEROV) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); STVFU(red[i][j], LVFU(redVals[i][j]) * factor); STVFU(green[i][j], LVFU(greenVals[i][j]) * factor); STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor); @@ -200,7 +200,7 @@ BENCHFUN #endif for (; j < W; ++j) { - const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma); + const float factor = pow_F(std::max(YNew[i][j], 0.f) / std::max(YOld[i][j], 0.00001f), gamma); red[i][j] = redVals[i][j] * factor; green[i][j] = greenVals[i][j] * factor; blue[i][j] = blueVals[i][j] * factor; From ce04447c7a98b675071f565b0dfe38aedcf41fd9 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 3 Sep 2019 22:18:20 +0200 Subject: [PATCH 158/222] Fix crash while rotating several thumbnails in File Browser Fix issue #4858 and possibly #5310 --- rtengine/rtthumbnail.cc | 28 ++++++++++++---------- rtgui/filebrowserentry.cc | 43 +++++++++++++++++++++++++++++++--- rtgui/thumbbrowserentrybase.cc | 9 ++++--- rtgui/thumbnail.h | 10 ++++---- 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 5efb75d48..1ffaf939a 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1483,6 +1483,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT delete labView; delete baseImg; + /* // calculate scale if (params.coarse.rotate == 90 || params.coarse.rotate == 270) { myscale = scale * thumbImg->getWidth() / fh; @@ -1491,19 +1492,20 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT } myscale = 1.0 / myscale; - /* // apply crop - if (params.crop.enabled) { - int ix = 0; - for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { - readyImg->data[ix++] /= 3; - readyImg->data[ix++] /= 3; - readyImg->data[ix++] /= 3; - } - else - ix += 3; - }*/ + // apply crop + if (params.crop.enabled) { + int ix = 0; + for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + } + else + ix += 3; + } + */ return readyImg; } diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 8b518335c..87a48a7ea 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -255,17 +255,20 @@ void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rten const bool resize = !preview || prew != img->getWidth(); prew = img->getWidth (); - GThreadLock lock; - // Check if image has been rotated since last time rotated = preview && newLandscape != landscape; if (resize) { - delete [] preview; + if (preview) { + delete [] preview; + } preview = new guint8 [prew * preh * 3]; } memcpy(preview, img->getData(), prew * preh * 3); + { + GThreadLock lock; updateBackBuffer (); + } } landscape = newLandscape; @@ -318,24 +321,36 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->y = action_y + (y - press_y) / scale; cropParams->h += oy - cropParams->y; cropgl->cropHeight1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeH2 && cropgl) { cropParams->h = action_y + (y - press_y) / scale; cropgl->cropHeight2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeW1 && cropgl) { int ox = cropParams->x; cropParams->x = action_x + (x - press_x) / scale; cropParams->w += ox - cropParams->x; cropgl->cropWidth1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeW2 && cropgl) { cropParams->w = action_x + (x - press_x) / scale; cropgl->cropWidth2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeTL && cropgl) { int ox = cropParams->x; @@ -345,7 +360,10 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->y = action_y + (y - press_y) / scale; cropParams->h += oy - cropParams->y; cropgl->cropTopLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeTR && cropgl) { cropParams->w = action_x + (x - press_x) / scale; @@ -353,7 +371,10 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->y = action_y + (y - press_y) / scale; cropParams->h += oy - cropParams->y; cropgl->cropTopRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeBL && cropgl) { int ox = cropParams->x; @@ -361,19 +382,28 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->w += ox - cropParams->x; cropParams->h = action_y + (y - press_y) / scale; cropgl->cropBottomLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeBR && cropgl) { cropParams->w = action_x + (x - press_x) / scale; cropParams->h = action_y + (y - press_y) / scale; cropgl->cropBottomRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SCropMove && cropgl) { cropParams->x = action_x + (x - press_x) / scale; cropParams->y = action_y + (y - press_y) / scale; cropgl->cropMoved (cropParams->x, cropParams->y, cropParams->w, cropParams->h); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SCropSelecting && cropgl) { int cx1 = press_x, cy1 = press_y; @@ -396,7 +426,10 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->h = cy1 - cy2 + 1; } + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } @@ -564,6 +597,7 @@ bool FileBrowserEntry::releaseNotify (int button, int type, int bstate, int x, i bool FileBrowserEntry::onArea (CursorArea a, int x, int y) { + MYREADERLOCK(l, lockRW); if (!drawable || !preview) { return false; } @@ -764,6 +798,8 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) int y2 = action_y; int x2 = action_x; + { + MYREADERLOCK(l, lockRW); if (x2 < prex + ofsX + startx) { y2 = y1 - (double)(y1 - y2) * (x1 - (prex + ofsX + startx)) / (x1 - x2); x2 = prex + ofsX + startx; @@ -779,6 +815,7 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) x2 = x1 - (double)(x1 - x2) * (y1 - (preh + prey + ofsY + starty - 1)) / (y1 - y2); y2 = preh + prey + ofsY + starty - 1; } + } cr->set_line_width (1.5); cr->set_source_rgb (1.0, 1.0, 1.0); diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index e660e794b..4dacb1adf 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -494,6 +494,7 @@ void ThumbBrowserEntryBase::resize (int h) height = h; int old_preh = preh; + int old_prew = prew; // dimensions of the button set int bsw = 0, bsh = 0; @@ -555,9 +556,11 @@ void ThumbBrowserEntryBase::resize (int h) width = bsw + 2 * sideMargin + 2 * borderWidth; } - if (preh != old_preh) { - delete [] preview; - preview = nullptr; + if (preh != old_preh || prew != old_prew) { // if new thumbnail height or new orientation + if (preview) { + delete [] preview; + preview = nullptr; + } refreshThumbnailImage (); } else if (backBuffer) { backBuffer->setDirty(true); // This will force a backBuffer update on queue_draw diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 0bcdd470a..e3196778c 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -49,17 +49,17 @@ class Thumbnail rtengine::Thumbnail* tpp; int tw, th; // dimensions of timgdata (it stores tpp->width and tpp->height in processed mode for simplicity) float imgRatio; // hack to avoid rounding error -// double scale; // portion of the sizes of the processed thumbnail image and the full scale image +// double scale; // portion of the sizes of the processed thumbnail image and the full scale image const std::unique_ptr pparams; bool pparamsValid; bool imageLoading; // these are the data of the result image of the last getthumbnailimage call (for caching purposes) - unsigned char* lastImg; - int lastW; - int lastH; - double lastScale; + unsigned char* lastImg; // pointer to the processed and scaled base ImageIO image + int lastW; // non rotated width of the cached ImageIO image + int lastH; // non rotated height of the cached ImageIO image + double lastScale; // scale of the cached ImageIO image // exif & date/time strings Glib::ustring exifString; From e9ac64a49534f2d130cc9e4a567c505f79a905e1 Mon Sep 17 00:00:00 2001 From: Roel Baars <6567747+Thanatomanic@users.noreply.github.com> Date: Wed, 4 Sep 2019 19:35:13 +0200 Subject: [PATCH 159/222] Fixes #5436 --- rtgui/histogrampanel.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 12da0cc0d..ae5ca1e4f 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -151,6 +151,8 @@ HistogramPanel::HistogramPanel () else showMode->set_image(*mode2Image); showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g); + + raw_toggled(); // Make sure the luma/chroma toggles are enabled or disabled setExpandAlignProperties(showRed , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); setExpandAlignProperties(showGreen, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); From 20ca4946b53eac795fe620b941dbbf7dda19a4fd Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 4 Sep 2019 22:05:24 +0200 Subject: [PATCH 160/222] Improve SAMSUNG EX2F support #1897 Improved raw crop eliminates white border on ISO >=800 shots, lower ISO shots did not exhibit white border. Patch by Ingo Weyrich --- rtengine/camconst.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 4dbfe80f9..7f481e104 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2250,6 +2250,11 @@ Camera constants: } }, + { // Quality C, only raw crop + "make_model": "Samsung EX2F", + "raw_crop": [ 16, 7, -4, -4 ] + }, + { // Quality B, corrections for raw crop vs dcraw9.21, matched to Samsung's default "make_model": "Samsung NX mini", "dcraw_matrix": [ 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 ], // dng 8.6 d65 From d0c6440af94b147f79d42ec182541a43c4de7c07 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 4 Sep 2019 22:12:53 +0200 Subject: [PATCH 161/222] Suppress debug output in CA correction Debug output still visible in verbose mode. Closes #5437 --- rtengine/CA_correct_RT.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index bad95a4d8..46a62cc4b 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -106,6 +106,10 @@ bool LinEqSolve(int nDim, double* pfMatr, double* pfVect, double* pfSolution) //end of linear equation solver } +namespace rtengine { + extern const Settings* settings; +} + using namespace std; using namespace rtengine; @@ -701,7 +705,9 @@ float* RawImageSource::CA_correct_RT( blockvar[dir][c] = blocksqave[dir][c] / blockdenom[dir][c] - SQR(blockave[dir][c] / blockdenom[dir][c]); } else { processpasstwo = false; - std::cout << "blockdenom vanishes" << std::endl; + if (settings->verbose) { + std::cout << "blockdenom vanishes" << std::endl; + } break; } } @@ -801,7 +807,9 @@ float* RawImageSource::CA_correct_RT( numpar = 4; if (numblox[1] < 10) { - std::cout << "numblox = " << numblox[1] << std::endl; + if (settings->verbose) { + std::cout << "numblox = " << numblox[1] << std::endl; + } processpasstwo = false; } } From 500fac34cd539e60ecb1788226d5de25b68cf05a Mon Sep 17 00:00:00 2001 From: Hombre Date: Thu, 5 Sep 2019 01:09:48 +0200 Subject: [PATCH 162/222] The svg2png icon cache is now cleared on new minor version The `version` value from the `Options` file is compared to the harcoded value (computed at build time) of the running application. If the major or minor version is different, the `svg2png` folder is cleaned at startup-time. --- rtgui/options.cc | 12 ++++++++++++ rtgui/options.h | 1 + rtgui/rtimage.cc | 4 ++-- rtgui/rtimage.h | 2 +- rtgui/rtscalable.cc | 4 ++-- rtgui/rtscalable.h | 2 +- rtgui/rtwindow.cc | 13 ++++--------- rtgui/rtwindow.h | 1 - 8 files changed, 23 insertions(+), 16 deletions(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index 640aa0243..b667f8679 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -2475,6 +2475,18 @@ bool Options::has_retained_extention(const Glib::ustring& fname) return parsedExtensionsSet.find(getExtension(fname).lowercase()) != parsedExtensionsSet.end(); } +// Pattern matches "5.1" from "5.1-23-g12345678", when comparing option.version to RTVERSION +bool Options::is_new_version() { + const std::string vs[] = {versionString, version}; + std::vector vMajor; + + for (const auto& v : vs) { + vMajor.emplace_back(v, 0, v.find_first_not_of("0123456789.")); + } + + return vMajor.size() == 2 && vMajor[0] != vMajor[1]; +} + /* * return true if ext is an enabled extension */ diff --git a/rtgui/options.h b/rtgui/options.h index d1d14a11f..0c580b034 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -426,6 +426,7 @@ public: Glib::ustring findProfilePath (Glib::ustring &profName); bool is_parse_extention (Glib::ustring fname); bool has_retained_extention (const Glib::ustring& fname); + bool is_new_version(); bool is_extention_enabled (const Glib::ustring& ext); bool is_defProfRawMissing(); bool is_bundledDefProfRawMissing(); diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 3fdf743f5..5ae3e4ddb 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -169,7 +169,7 @@ void RTImage::init() scaleBack = RTScalable::getScale(); } -void RTImage::cleanup() +void RTImage::cleanup(bool all) { for (auto& entry : pixbufCache) { entry.second.reset(); @@ -177,7 +177,7 @@ void RTImage::cleanup() for (auto& entry : surfaceCache) { entry.second.clear(); } - RTScalable::cleanup(); + RTScalable::cleanup(all); } void RTImage::updateImages() diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index 244d0030a..15978f65c 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -52,7 +52,7 @@ public: static void init(); - static void cleanup(); + static void cleanup(bool all = false); static void updateImages (); static void setDPInScale (const double newDPI, const int newScale); static void setScale (const int newScale); diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 079ece8d2..ae3214520 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -119,7 +119,7 @@ void RTScalable::deleteDir(const Glib::ustring& path) } } -void RTScalable::cleanup() +void RTScalable::cleanup(bool all) { Glib::ustring imagesCacheFolder = Glib::build_filename (options.cacheBaseDir, "svg2png"); Glib::ustring sDPI = Glib::ustring::compose("%1", (int)getTweakedDPI()); @@ -134,7 +134,7 @@ void RTScalable::cleanup() continue; } - if (fileName != sDPI) { + if (all || fileName != sDPI) { deleteDir(filePath); } } diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index e6180eaa1..b8db9953c 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -50,7 +50,7 @@ public: #endif static void init(Gtk::Window *window); - static void cleanup(); + static void cleanup(bool all = false); static double getDPI (); static double getTweakedDPI (); // The returned value is tweaked DPI to adapt to main the font size. Maybe not an ideal solution. static int getScale (); diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 85b902727..131016cb0 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -95,6 +95,9 @@ RTWindow::RTWindow () , fpanel (nullptr) { + if (options.is_new_version()) { + RTImage::cleanup(true); + } cacheMgr->init (); ProfilePanel::init (this); @@ -475,16 +478,8 @@ void RTWindow::on_realize () mainWindowCursorManager.init (get_window()); // Display release notes only if new major version. - // Pattern matches "5.1" from "5.1-23-g12345678" - const std::string vs[] = {versionString, options.version}; - std::vector vMajor; - - for (const auto& v : vs) { - vMajor.emplace_back(v, 0, v.find_first_not_of("0123456789.")); - } - bool waitForSplash = false; - if (vMajor.size() == 2 && vMajor[0] != vMajor[1]) { + if (options.is_new_version()) { // Update the version parameter with the right value options.version = versionString; diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index d037d8875..48662858f 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -53,7 +53,6 @@ private: { return !options.tabbedUI && ! (options.multiDisplayMode > 0); }; - void findVerNumbers (int* numbers, Glib::ustring versionStr); bool on_expose_event_epanel (GdkEventExpose* event); bool on_expose_event_fpanel (GdkEventExpose* event); From 10a346113f6ccbabfd2cfd4a36914f5cb6cbf505 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Thu, 5 Sep 2019 01:44:45 +0200 Subject: [PATCH 163/222] Increase visibility of blue histogram, closes #5438 --- rtgui/histogrampanel.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index ae5ca1e4f..b82df7ebf 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -142,7 +142,7 @@ HistogramPanel::HistogramPanel () showGreen->set_image (showGreen->get_active() ? *greenImage : *greenImage_g); showBlue->set_image (showBlue->get_active() ? *blueImage : *blueImage_g); showValue->set_image (showValue->get_active() ? *valueImage : *valueImage_g); - showChro->set_image (showChro->get_active() ? *chroImage : *chroImage_g); + showChro->set_image (showChro->get_active() ? *chroImage : *chroImage_g); showRAW->set_image (showRAW->get_active() ? *rawImage : *rawImage_g); if (options.histogramDrawMode == 0) showMode->set_image(*mode0Image); @@ -504,7 +504,7 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin if (needBlue) { // Blue - cc->set_source_rgb(0.0, 0.0, 1.0); + cc->set_source_rgb(0.0, 0.4, 1.0); if (options.histogramDrawMode < 2) { cc->move_to(b * (winw - 1.) / 255.0 + 0.5*s, 0); cc->line_to(b * (winw - 1.) / 255.0 + 0.5*s, winh - 0); @@ -964,7 +964,7 @@ void HistogramArea::updateBackBuffer () if (needBlue) { drawCurve(cr, bhchanged, realhistheight, w, h); - cr->set_source_rgb (0.0, 0.0, 1.0); + cr->set_source_rgb (0.0, 0.4, 1.0); cr->stroke (); drawMarks(cr, bhchanged, realhistheight, w, ui, oi); } From 9165d0acb7ba312d6eb57010cbf48f3eb0688602 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 5 Sep 2019 12:08:36 +0200 Subject: [PATCH 164/222] Crop area not shown on File Browser window thumbnails, fixes #5440 --- rtengine/rtthumbnail.cc | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 1ffaf939a..2c78e84bf 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1483,29 +1483,33 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT delete labView; delete baseImg; - /* - // calculate scale - if (params.coarse.rotate == 90 || params.coarse.rotate == 270) { - myscale = scale * thumbImg->getWidth() / fh; - } else { - myscale = scale * thumbImg->getHeight() / fh; - } - myscale = 1.0 / myscale; + // apply crop if (params.crop.enabled) { + double lscale; + // calculate scale + if (params.coarse.rotate == 90 || params.coarse.rotate == 270) { + lscale = scale * thumbImg->getWidth() / fh; + } else { + lscale = scale * thumbImg->getHeight() / fh; + } + + lscale = 1.0 / lscale; int ix = 0; - for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { + for (int i = 0; i < fh; ++i) { + for (int j = 0; j < fw; ++j) { + if (i < params.crop.y * lscale || i > (params.crop.y + params.crop.h) * lscale || j < params.crop.x * lscale || j > (params.crop.x + params.crop.w) * lscale) { readyImg->data[ix++] /= 3; readyImg->data[ix++] /= 3; readyImg->data[ix++] /= 3; - } - else + } else { ix += 3; + } + } + } } - */ + return readyImg; } From 11bf7e5eb5e79642feafcc9b9217b43a39824d75 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 5 Sep 2019 15:16:24 +0200 Subject: [PATCH 165/222] fix broken crop lines in file browser, fixes #5440 --- rtengine/rtthumbnail.cc | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 2c78e84bf..3e970ed0d 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1483,23 +1483,20 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT delete labView; delete baseImg; + // calculate scale + if (params.coarse.rotate == 90 || params.coarse.rotate == 270) { + myscale = scale * thumbImg->getWidth() / fh; + } else { + myscale = scale * thumbImg->getHeight() / fh; + } - + myscale = 1.0 / myscale; // apply crop if (params.crop.enabled) { - double lscale; - // calculate scale - if (params.coarse.rotate == 90 || params.coarse.rotate == 270) { - lscale = scale * thumbImg->getWidth() / fh; - } else { - lscale = scale * thumbImg->getHeight() / fh; - } - - lscale = 1.0 / lscale; int ix = 0; for (int i = 0; i < fh; ++i) { for (int j = 0; j < fw; ++j) { - if (i < params.crop.y * lscale || i > (params.crop.y + params.crop.h) * lscale || j < params.crop.x * lscale || j > (params.crop.x + params.crop.w) * lscale) { + if (i < params.crop.y * myscale || i > (params.crop.y + params.crop.h) * myscale || j < params.crop.x * myscale || j > (params.crop.x + params.crop.w) * myscale) { readyImg->data[ix++] /= 3; readyImg->data[ix++] /= 3; readyImg->data[ix++] /= 3; From b858bfb2c98a0dd4dd75cd607fd0e57af279c96f Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Fri, 6 Sep 2019 22:15:37 +0200 Subject: [PATCH 166/222] Update "Advanced" tab shortcut to Alt-a Back when it was called the "Wavelet" tab the Alt-w shortcut was used. Closes #4322 --- rtdata/languages/Catala | 2 +- rtdata/languages/Chinese (Simplified) | 2 +- rtdata/languages/Czech | 2 +- rtdata/languages/Deutsch | 2 +- rtdata/languages/English (UK) | 2 +- rtdata/languages/English (US) | 2 +- rtdata/languages/Espanol | 2 +- rtdata/languages/Francais | 2 +- rtdata/languages/Italiano | 2 +- rtdata/languages/Japanese | 2 +- rtdata/languages/Magyar | 2 +- rtdata/languages/Nederlands | 2 +- rtdata/languages/Polish | 2 +- rtdata/languages/Portugues | 2 +- rtdata/languages/Portugues (Brasil) | 2 +- rtdata/languages/Russian | 2 +- rtdata/languages/Serbian (Cyrilic Characters) | 2 +- rtdata/languages/Swedish | 2 +- rtdata/languages/default | 2 +- rtgui/toolpanelcoord.cc | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 8b2bc5992..407348417 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1423,7 +1423,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TAB_INSPECT; Inspect diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index b01c39d84..b93aed7af 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1468,7 +1468,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: theme-based\nShortcut: 9 diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index ce16e057f..d0b4d89f3 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -934,7 +934,7 @@ MAIN_MSG_SETPATHFIRST;K použití této funkce musíte nejprve zadat cílovou ce MAIN_MSG_TOOMANYOPENEDITORS;Příliš mnoho otevřených editorů.\nPro pokračování nejprve některý ukončete. MAIN_MSG_WRITEFAILED;Chyba zápisu\n"%1"\n\nUjistěte se, že složka existuje a máte práva do ní zapisovat. MAIN_TAB_ADVANCED;Pokročilé -MAIN_TAB_ADVANCED_TOOLTIP;Zkratka: Alt-w +MAIN_TAB_ADVANCED_TOOLTIP;Zkratka: Alt-a MAIN_TAB_COLOR;Barvy MAIN_TAB_COLOR_TOOLTIP;Zkratka: Alt-c MAIN_TAB_DETAIL;Detaily diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 7967786dd..57236e1e6 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -984,7 +984,7 @@ MAIN_MSG_SETPATHFIRST;Um diese Funktion zu nutzen, müssen Sie zuerst in den Ein MAIN_MSG_TOOMANYOPENEDITORS;Zu viele geöffnete Editorfenster.\nUm fortzufahren, schließen sie bitte ein Editorfenster. MAIN_MSG_WRITEFAILED;Fehler beim Schreiben von\n\n"%1"\n\nStellen Sie sicher, dass das Verzeichnis existiert und dass Sie Schreibrechte besitzen. MAIN_TAB_ADVANCED;Erweitert -MAIN_TAB_ADVANCED_TOOLTIP;Taste: Alt + w +MAIN_TAB_ADVANCED_TOOLTIP;Taste: Alt + a MAIN_TAB_COLOR;Farbe MAIN_TAB_COLOR_TOOLTIP;Taste: Alt + c MAIN_TAB_DETAIL;Details diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 503e63860..c6b521c12 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -990,7 +990,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-c !MAIN_TAB_DETAIL;Detail !MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-d diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 52caa23e4..9b8eda038 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -902,7 +902,7 @@ !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_COLOR;Color !MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-c !MAIN_TAB_DETAIL;Detail diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol index c91bd4a6b..1e3b84371 100644 --- a/rtdata/languages/Espanol +++ b/rtdata/languages/Espanol @@ -954,7 +954,7 @@ MAIN_MSG_SETPATHFIRST;Para poder usar esta función, primero tiene que establece MAIN_MSG_TOOMANYOPENEDITORS;Demasiados editores abiertos.\nPor favor cierre un editor para continuar. MAIN_MSG_WRITEFAILED;Falla al escribir\n\n"%1"\n\nAsegurese de que el folder exista y que usted tenga permiso de escritura sobre él. MAIN_TAB_ADVANCED;Avanzado -MAIN_TAB_ADVANCED_TOOLTIP;Tecla de Atajo: Alt-w +MAIN_TAB_ADVANCED_TOOLTIP;Tecla de Atajo: Alt-a MAIN_TAB_COLOR;Color MAIN_TAB_COLOR_TOOLTIP;Tecla de Atajo: Alt-C MAIN_TAB_DETAIL;Detalle diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 2c5017a6e..082cff1f1 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -889,7 +889,7 @@ MAIN_MSG_SETPATHFIRST;Vous devez d'abord choisir un dossier cible dans Préfére MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. MAIN_MSG_WRITEFAILED;Échec de l'enregistrement du fichier\n\n"%1"\n\nAssurez-vous que le dossier existe et qu'il est permis d'y écrire. MAIN_TAB_ADVANCED;Avancé -MAIN_TAB_ADVANCED_TOOLTIP;Raccourci: Alt-w +MAIN_TAB_ADVANCED_TOOLTIP;Raccourci: Alt-a MAIN_TAB_COLOR;Couleur MAIN_TAB_COLOR_TOOLTIP;Raccourci:Alt-c MAIN_TAB_DETAIL;Détail diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 977277a73..f11423d7a 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -1640,7 +1640,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !MAIN_FRAME_PLACES_DEL;Remove !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TAB_INSPECT; Inspect diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 96ffea174..16dafb297 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -933,7 +933,7 @@ MAIN_MSG_SETPATHFIRST;この関数を使用するには、最初に環境設定 MAIN_MSG_TOOMANYOPENEDITORS;編集画面が多すぎます\n操作を続けるには何れかの画面を閉じてください MAIN_MSG_WRITEFAILED;書き込みに失敗しました\n\n"%1"\n\nフォルダが在るか書き込み権限を持っているか確認してください MAIN_TAB_ADVANCED;高度な機能 -MAIN_TAB_ADVANCED_TOOLTIP;ショートカット: Alt-w +MAIN_TAB_ADVANCED_TOOLTIP;ショートカット: Alt-a MAIN_TAB_COLOR;カラー MAIN_TAB_COLOR_TOOLTIP;ショートカット: Alt-c MAIN_TAB_DETAIL;CbDL diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 26f1b1aa0..5879bf130 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1357,7 +1357,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TAB_INSPECT; Inspect diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 43afc8efa..d39173a52 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -2111,7 +2111,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !MAIN_FRAME_PLACES_DEL;Remove !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 528b6a198..a631353c3 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1722,7 +1722,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !MAIN_FRAME_PLACES_DEL;Remove !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TAB_INSPECT; Inspect diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index e68f93e56..766b14e0b 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -889,7 +889,7 @@ MAIN_MSG_SETPATHFIRST;Para usar esta função, primeiro tem de configurar um cam MAIN_MSG_TOOMANYOPENEDITORS;Existem demasiados editores abertos.\nPor favor, feche um editor para continuar. MAIN_MSG_WRITEFAILED;Falha ao gravar\n"%1"\n\nVerifique se a pasta existe e se tem permissão para gravar nela. MAIN_TAB_ADVANCED;Avançado -MAIN_TAB_ADVANCED_TOOLTIP;Atalho: Alt-w +MAIN_TAB_ADVANCED_TOOLTIP;Atalho: Alt-a MAIN_TAB_COLOR;Cor MAIN_TAB_COLOR_TOOLTIP;Atalho: Alt-c MAIN_TAB_DETAIL;Detalhe diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index c7cc2dfe7..aef5fcde9 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -888,7 +888,7 @@ MAIN_MSG_SETPATHFIRST;Para usar esta função primeiro defina um objetivo em Pre MAIN_MSG_TOOMANYOPENEDITORS;Muitos editores abertos.\nPor favor, feche um editor para continuar. MAIN_MSG_WRITEFAILED;Falha ao escrever\n"%1"\n\nVerifique se a pasta existe e se tens permissão para gravar nela. MAIN_TAB_ADVANCED;Avançado -MAIN_TAB_ADVANCED_TOOLTIP;Atalho: Alt-w +MAIN_TAB_ADVANCED_TOOLTIP;Atalho: Alt-a MAIN_TAB_COLOR;Cor MAIN_TAB_COLOR_TOOLTIP;Atalho: Alt-c MAIN_TAB_DETAIL;Detalhe diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index a33458ef6..79c6bebfc 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -589,7 +589,7 @@ MAIN_MSG_QOVERWRITE;Вы хотите перезаписать его? MAIN_MSG_SETPATHFIRST;Прежде необходимо установить целевой каталог в настройках\nчтоб использовать эту функцию! MAIN_MSG_WRITEFAILED;Не удалось записать\n\n"%1".\n\nУбедитесь, что каталог существует и у вас есть права на запись в него. MAIN_TAB_ADVANCED;Дополнительные -MAIN_TAB_ADVANCED_TOOLTIP;Горячая клавиша: Alt-W +MAIN_TAB_ADVANCED_TOOLTIP;Горячая клавиша: Alt-a MAIN_TAB_COLOR;Цвет MAIN_TAB_COLOR_TOOLTIP;Горячая клавиша: Alt-C MAIN_TAB_DETAIL;Детализация diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 98d74a5dd..2b98cfe2a 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1614,7 +1614,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !MAIN_FRAME_PLACES_DEL;Remove !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TAB_INSPECT; Inspect diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 17bf0299f..220339a45 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -1963,7 +1963,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !MAIN_FRAME_PLACES_DEL;Remove !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 diff --git a/rtdata/languages/default b/rtdata/languages/default index e8392db6b..499005d32 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -901,7 +901,7 @@ MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in orde MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. MAIN_TAB_ADVANCED;Advanced -MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-w +MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a MAIN_TAB_COLOR;Color MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-c MAIN_TAB_DETAIL;Detail diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index f7e2991e1..d9bc6fc2a 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -922,7 +922,7 @@ bool ToolPanelCoordinator::handleShortcutKey (GdkEventKey* event) toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*rawPanelSW)); return true; - case GDK_KEY_w: + case GDK_KEY_a: toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*advancedPanelSW)); return true; From 50f9be3e600d5eeadb72a00fa1eeb44f5a4598e5 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Fri, 6 Sep 2019 22:51:46 +0200 Subject: [PATCH 167/222] Preparing for release 5.7 --- RELEASE_NOTES.txt | 21 ++++--- com.rawtherapee.RawTherapee.appdata.xml | 1 + rtdata/images/svg/splash.svg | 77 ++++--------------------- 3 files changed, 22 insertions(+), 77 deletions(-) diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 17cf14fd6..6765177d4 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,17 +1,10 @@ -RAWTHERAPEE 5.6-dev RELEASE NOTES +RAWTHERAPEE 5.7 RELEASE NOTES -This is a development version of RawTherapee. We update the code almost daily. Every few months, once enough changes have accumulated and the code is stabilized, we make a new official release. Every code change between these releases is known as a "development" version, and this is one of them. +This is RawTherapee 5.7, released on 2019-09-08. Start by reading the "Getting Started" article on RawPedia: http://rawpedia.rawtherapee.com/ -While we only commit tested and relatively stable code and so the development versions should be fairly stable, you should be aware that: -- Development versions only had limited testing, so there may be bugs unknown to us. -- You should report these bugs so that they get fixed for the next stable release. See - www.rawpedia.rawtherapee.com/How_to_write_useful_bug_reports -- The way new tools work in the development versions is likely to change as we tweak and tune them, so your processing profiles may produce different results when used in a future stable version. -- Bugs present in the stable versions get fixed in the development versions, and make it into the next stable version when we make a new official release. That means that in some ways the development versions can be "more stable" than the latest stable release. At the same time, new features may introduce new bugs. This is a trade-off you should be aware of. - NEWS RELEVANT TO PHOTOGRAPHERS @@ -27,15 +20,21 @@ In order to use RawTherapee efficiently you should know that: - There are many keyboard shortcuts which make working with RawTherapee much faster and give you greater control. Make sure you familiarize yourself with them on RawPedia's "Keyboard Shortcuts" page! New features since 5.6: -TODO. +- Film Negative tool, for easily developing raw photographs of film negatives. +- Support for reading "rating" tags from Exif and XMP, shown in the File Browser/Filmstrip using RawTherapee's star rating system. +- Hundreds of bug fixes, speed optimizations and raw format support improvements. NEWS RELEVANT TO PACKAGE MAINTAINERS +New since 5.6: +- Requires CMake >=3.5. + In general: - To get the source code, either clone from git or use the tarball from http://rawtherapee.com/shared/source/ . Do not use the auto-generated GitHub release tarballs. -- Requires GTK+ version >=3.16, though >=3.22.24 is recommended. GTK+ versions 3.24.2 - 3.24.6 have an issue with missing combobox menu arrows and are to be avoided. +- Requires GTK+ version >=3.16, though >=3.22.24 is recommended. +- GTK+ versions 3.24.2 - 3.24.6 have an issue where combobox menu scroll-arrows are missing when the combobox list does not fit vertically on the screen. As a result, users would not be able to scroll in the following comboboxes: Processing Profiles, Film Simulation, and the camera and lens profiles in Profiled Lens Correction. - RawTherapee 5 requires GCC-4.9 or higher, or Clang. - Do not use -ffast-math, it will not make RawTherapee faster but will introduce artifacts. - Use -O3, it will make RawTherapee faster with no known side-effects. diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index a53ccbf06..efe6224b3 100644 --- a/com.rawtherapee.RawTherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -36,6 +36,7 @@ https://discuss.pixls.us/t/localization-how-to-translate-rawtherapee-and-rawpedia/2594 rawtherapee.desktop + diff --git a/rtdata/images/svg/splash.svg b/rtdata/images/svg/splash.svg index 2e46f0e6d..a3bf9f8d2 100644 --- a/rtdata/images/svg/splash.svg +++ b/rtdata/images/svg/splash.svg @@ -15,7 +15,7 @@ viewBox="0 0 146.05 91.545836" version="1.1" id="svg783" - inkscape:version="0.92.2 2405546, 2018-03-11" + inkscape:version="0.92.4 5da689c313, 2019-01-14" sodipodi:docname="splash.svg" inkscape:export-filename="/tmp/splash.png" inkscape:export-xdpi="96" @@ -480,8 +480,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.93979686" - inkscape:cx="-66.836581" - inkscape:cy="136.82017" + inkscape:cx="-57.792073" + inkscape:cy="126.17957" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -574,7 +574,7 @@ RawTherapee splash screen - 2019-02-27 + Maciej Dworak @@ -996,7 +996,7 @@ id="tspan595" x="283.85016" y="2.2370076" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:49.34799576px;line-height:1.25;font-family:'Eras Bold ITC';-inkscape-font-specification:'Eras Bold ITC Bold';letter-spacing:-7.09514618px">. 6 + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:49.34799576px;line-height:1.25;font-family:'Eras Bold ITC';-inkscape-font-specification:'Eras Bold ITC Bold';letter-spacing:-7.09514618px">. 8 Raw + id="text191"> + id="path193" /> - - - - - - - - - - - - - - - + id="path195" /> From 062b5a6bbc4333ab7d95d766e63e834835adc389 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 7 Sep 2019 16:16:28 +0200 Subject: [PATCH 168/222] Capture Sharpening: change default values for iterations and gamma --- rtengine/procparams.cc | 4 ++-- rtgui/pdsharpening.cc | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index d88892a3b..4f31d7539 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1153,9 +1153,9 @@ CaptureSharpeningParams::CaptureSharpeningParams() : enabled(false), autoContrast(true), contrast(10.0), - gamma(1.35), + gamma(1.00), deconvradius(0.75), - deconviter(30) + deconviter(20) { } diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 8e7c0e8b8..85d174df8 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -49,9 +49,9 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS pack_start(*hb); Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); - gamma = Gtk::manage(new Adjuster(M("TP_SHARPENING_GAMMA"), 0.5, 6.0, 0.05, 1.35)); - dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_EDRADIUS"), 0.4, 1.0, 0.01, 0.75)); - diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + 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)); + 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(*diter); From ec2f7778bbedcfbd6c70d7af74ebb150fae30ef2 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 9 Sep 2019 15:48:00 +0200 Subject: [PATCH 169/222] trigger capture sharpening less often --- rtengine/improccoordinator.cc | 4 ++-- rtengine/refreshmap.h | 2 ++ rtgui/pdsharpening.cc | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 10d484495..ee7d07b11 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -340,11 +340,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); } // if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag - todo |= M_INIT; + todo |= (M_INIT | M_CSHARP); } - if ((todo & M_INIT) && params->pdsharpening.enabled) { + if ((todo & (M_RAW | M_CSHARP)) && params->pdsharpening.enabled) { double pdSharpencontrastThreshold = params->pdsharpening.contrast; imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold); if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) { diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index b9ccc2b65..72d8dcadd 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -32,6 +32,7 @@ // Elementary functions that can be done to // the preview image when an event occurs +#define M_CSHARP (1<<18) #define M_MONITOR (1<<14) #define M_RETINEX (1<<13) #define M_CROP (1<<12) @@ -56,6 +57,7 @@ #define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define ALLNORAW (M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define CAPTURESHARPEN (M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR|M_CSHARP) #define HDR (M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define AUTOEXP (M_HDR|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 85d174df8..c85b42e95 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -30,11 +30,11 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS { auto m = ProcEventMapper::getInstance(); - EvPdShrContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_CONTRAST"); - EvPdSharpenGamma = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_GAMMA"); - EvPdShrDRadius = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_RADIUS"); - EvPdShrDIterations = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); - EvPdShrAutoContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); + EvPdShrContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CONTRAST"); + EvPdSharpenGamma = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_GAMMA"); + EvPdShrDRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS"); + EvPdShrDIterations = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); + EvPdShrAutoContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); Gtk::HBox* hb = Gtk::manage(new Gtk::HBox()); hb->show(); From 37d6b98ee3bb55da48ee77f0e357f67509aaa8ff Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Tue, 10 Sep 2019 12:30:54 +0200 Subject: [PATCH 170/222] Update RELEASE_NOTES.txt --- RELEASE_NOTES.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 6765177d4..0974af86c 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,9 +1,9 @@ RAWTHERAPEE 5.7 RELEASE NOTES -This is RawTherapee 5.7, released on 2019-09-08. +This is RawTherapee 5.7, released on 2019-09-10. Start by reading the "Getting Started" article on RawPedia: -http://rawpedia.rawtherapee.com/ +https://rawpedia.rawtherapee.com/ @@ -32,7 +32,7 @@ New since 5.6: - Requires CMake >=3.5. In general: -- To get the source code, either clone from git or use the tarball from http://rawtherapee.com/shared/source/ . Do not use the auto-generated GitHub release tarballs. +- To get the source code, either clone from git or use the tarball from https://rawtherapee.com/shared/source/ . Do not use the auto-generated GitHub release tarballs. - Requires GTK+ version >=3.16, though >=3.22.24 is recommended. - GTK+ versions 3.24.2 - 3.24.6 have an issue where combobox menu scroll-arrows are missing when the combobox list does not fit vertically on the screen. As a result, users would not be able to scroll in the following comboboxes: Processing Profiles, Film Simulation, and the camera and lens profiles in Profiled Lens Correction. - RawTherapee 5 requires GCC-4.9 or higher, or Clang. @@ -51,15 +51,14 @@ See CONTRIBUTING.md DOCUMENTATION -http://rawpedia.rawtherapee.com/ -http://rawtherapee.com/blog/documentation +https://rawpedia.rawtherapee.com/ REPORTING BUGS If you found a problem, don't keep it to yourself. Read the "How to write useful bug reports" article to get the problem fixed: -http://rawpedia.rawtherapee.com/How_to_write_useful_bug_reports +https://rawpedia.rawtherapee.com/How_to_write_useful_bug_reports @@ -77,8 +76,8 @@ Server: chat.freenode.net Channel: #rawtherapee You can use freenode webchat to communicate without installing anything: -http://webchat.freenode.net/?randomnick=1&channels=rawtherapee&prompt=1 -More information here: http://rawpedia.rawtherapee.com/IRC +https://webchat.freenode.net/?randomnick=1&channels=rawtherapee&prompt=1 +More information here: https://rawpedia.rawtherapee.com/IRC From ef722d37cbd6a64eef1279cf9c7b3b0988100d1c Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Tue, 10 Sep 2019 12:34:40 +0200 Subject: [PATCH 171/222] Updated appdata --- com.rawtherapee.RawTherapee.appdata.xml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index efe6224b3..0e5dfef50 100644 --- a/com.rawtherapee.RawTherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -31,12 +31,12 @@ GPL-3.0+ https://github.com/Beep6581/RawTherapee/issues/new https://www.paypal.me/rawtherapee - http://rawpedia.rawtherapee.com/ - http://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,16 +48,20 @@ + Color-correcting a drosera rotundifolia in RawTherapee 5.7. + https://rawtherapee.com/images/screenshots/rt570_1.jpg + + HDR DNG of a misty morning in the countryside - http://rawtherapee.com/images/screenshots/rt540_1.jpg + https://rawtherapee.com/images/screenshots/rt540_1.jpg Straight-out-of-camera vs RawTherapee - http://rawtherapee.com/images/screenshots/rt540_2.jpg + https://rawtherapee.com/images/screenshots/rt540_2.jpg RawTherapee using the Auto-Matched Tone Curve tool - http://rawtherapee.com/images/screenshots/rt540_3.jpg + https://rawtherapee.com/images/screenshots/rt540_3.jpg contactus@rawtherapee.com From 60b2196bcefd7be06bc8cfed28b5cd869e861977 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Tue, 10 Sep 2019 12:34:57 +0200 Subject: [PATCH 172/222] Updated gnu.org links to use HTTPS --- LICENSE.txt | 2 +- cmake/modules/FindUnalignedMalloc.cmake | 2 +- cmake/modules/FindX87Math.cmake | 2 +- header | 2 +- rtdata/languages/LICENSE | 2 +- rtdata/themes/RawTherapee-GTK3-20_.css | 2 +- rtdata/themes/RawTherapee-GTK3-_19.css | 2 +- rtdata/themes/TooWaBlue - Bright-GTK3-20_.css | 2 +- rtdata/themes/TooWaBlue - Dark-GTK3-20_.css | 2 +- rtdata/themes/TooWaBlue-GTK3-20_.css | 2 +- rtdata/themes/TooWaBlue-GTK3-_19.css | 2 +- rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css | 2 +- rtdata/themes/TooWaGrey - Bright-GTK3-20_.css | 2 +- rtdata/themes/TooWaGrey - Dark-GTK3-20_.css | 2 +- rtdata/themes/TooWaGrey-GTK3-20_.css | 2 +- rtengine/CA_correct_RT.cc | 2 +- rtengine/FTblockDN.cc | 2 +- rtengine/LUT.h | 2 +- rtengine/PF_correct_RT.cc | 2 +- rtengine/StopWatch.h | 2 +- rtengine/ahd_demosaic_RT.cc | 2 +- rtengine/alignedbuffer.h | 2 +- rtengine/amaze_demosaic_RT.cc | 2 +- rtengine/array2D.h | 2 +- rtengine/badpixels.cc | 2 +- rtengine/bilateral2.h | 2 +- rtengine/boxblur.h | 2 +- rtengine/cache.h | 2 +- rtengine/cfa_linedn_RT.cc | 2 +- rtengine/ciecam02.cc | 2 +- rtengine/ciecam02.h | 2 +- rtengine/cieimage.h | 2 +- rtengine/color.cc | 2 +- rtengine/color.h | 2 +- rtengine/colortemp.cc | 2 +- rtengine/colortemp.h | 2 +- rtengine/coord.cc | 2 +- rtengine/coord.h | 2 +- rtengine/coord2d.h | 2 +- rtengine/cplx_wavelet_dec.cc | 2 +- rtengine/cplx_wavelet_dec.h | 2 +- rtengine/cplx_wavelet_filter_coeffs.h | 2 +- rtengine/cplx_wavelet_level.h | 2 +- rtengine/curves.cc | 2 +- rtengine/curves.h | 2 +- rtengine/dcp.cc | 2 +- rtengine/dcp.h | 2 +- rtengine/dcraw.h | 2 +- rtengine/dcrop.cc | 2 +- rtengine/dcrop.h | 2 +- rtengine/demosaic_algos.cc | 4 ++-- rtengine/dfmanager.cc | 2 +- rtengine/dfmanager.h | 2 +- rtengine/diagonalcurves.cc | 2 +- rtengine/dirpyr_equalizer.cc | 2 +- rtengine/dual_demosaic_RT.cc | 2 +- rtengine/dynamicprofile.cc | 2 +- rtengine/dynamicprofile.h | 2 +- rtengine/eahd_demosaic.cc | 2 +- rtengine/fast_demo.cc | 2 +- rtengine/ffmanager.cc | 2 +- rtengine/ffmanager.h | 2 +- rtengine/filmnegativeproc.cc | 2 +- rtengine/filmnegativethumb.cc | 2 +- rtengine/flatcurves.cc | 2 +- rtengine/gamutwarning.cc | 2 +- rtengine/gamutwarning.h | 2 +- rtengine/gauss.cc | 2 +- rtengine/gauss.h | 2 +- rtengine/green_equil_RT.cc | 2 +- rtengine/guidedfilter.cc | 2 +- rtengine/guidedfilter.h | 2 +- rtengine/hilite_recon.cc | 2 +- rtengine/histmatching.cc | 2 +- rtengine/hphd_demosaic_RT.cc | 2 +- rtengine/iccmatrices.h | 2 +- rtengine/iccstore.cc | 2 +- rtengine/iccstore.h | 2 +- rtengine/iimage.cc | 2 +- rtengine/iimage.h | 2 +- rtengine/image16.cc | 2 +- rtengine/image16.h | 2 +- rtengine/image8.cc | 2 +- rtengine/image8.h | 2 +- rtengine/imagedata.cc | 2 +- rtengine/imagedata.h | 2 +- rtengine/imagedimensions.cc | 2 +- rtengine/imagedimensions.h | 2 +- rtengine/imagefloat.cc | 2 +- rtengine/imagefloat.h | 2 +- rtengine/imageformat.h | 2 +- rtengine/imageio.cc | 2 +- rtengine/imageio.h | 2 +- rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 2 +- rtengine/improccoordinator.h | 2 +- rtengine/improcfun.cc | 4 ++-- rtengine/improcfun.h | 2 +- rtengine/impulse_denoise.cc | 2 +- rtengine/init.cc | 2 +- rtengine/ipdehaze.cc | 2 +- rtengine/iplab2rgb.cc | 2 +- rtengine/iplabregions.cc | 2 +- rtengine/iplocalcontrast.cc | 2 +- rtengine/ipresize.cc | 2 +- rtengine/ipretinex.cc | 2 +- rtengine/ipshadowshighlights.cc | 2 +- rtengine/ipsharpen.cc | 2 +- rtengine/ipsoftlight.cc | 2 +- rtengine/iptcpairs.h | 2 +- rtengine/iptransform.cc | 2 +- rtengine/ipvibrance.cc | 2 +- rtengine/ipwavelet.cc | 2 +- rtengine/jaggedarray.h | 2 +- rtengine/labimage.cc | 2 +- rtengine/labimage.h | 2 +- rtengine/lcp.cc | 2 +- rtengine/lcp.h | 2 +- rtengine/loadinitial.cc | 2 +- rtengine/median.h | 2 +- rtengine/myfile.cc | 2 +- rtengine/myfile.h | 2 +- rtengine/mytime.h | 2 +- rtengine/noncopyable.h | 2 +- rtengine/opthelper.h | 2 +- rtengine/pdaflinesfilter.cc | 2 +- rtengine/pdaflinesfilter.h | 2 +- rtengine/pipettebuffer.cc | 2 +- rtengine/pipettebuffer.h | 2 +- rtengine/pixelshift.cc | 2 +- rtengine/pixelsmap.h | 2 +- rtengine/previewimage.cc | 2 +- rtengine/previewimage.h | 2 +- rtengine/processingjob.cc | 2 +- rtengine/processingjob.h | 2 +- rtengine/procevents.h | 2 +- rtengine/procparams.cc | 2 +- rtengine/procparams.h | 2 +- rtengine/profilestore.cc | 2 +- rtengine/profilestore.h | 2 +- rtengine/rawimage.h | 2 +- rtengine/rawimagesource.cc | 2 +- rtengine/rawimagesource.h | 2 +- rtengine/rawimagesource_i.h | 2 +- rtengine/rawmetadatalocation.h | 2 +- rtengine/rcd_demosaic.cc | 2 +- rtengine/refreshmap.cc | 2 +- rtengine/refreshmap.h | 2 +- rtengine/rescale.h | 2 +- rtengine/rt_algo.cc | 2 +- rtengine/rt_algo.h | 2 +- rtengine/rtengine.h | 2 +- rtengine/rtlensfun.cc | 2 +- rtengine/rtlensfun.h | 2 +- rtengine/rtthumbnail.cc | 2 +- rtengine/rtthumbnail.h | 2 +- rtengine/settings.h | 2 +- rtengine/shmap.cc | 2 +- rtengine/shmap.h | 2 +- rtengine/simpleprocess.cc | 2 +- rtengine/slicer.cc | 2 +- rtengine/slicer.h | 2 +- rtengine/stdimagesource.cc | 2 +- rtengine/stdimagesource.h | 2 +- rtengine/tmo_fattal02.cc | 2 +- rtengine/utils.cc | 2 +- rtengine/utils.h | 2 +- rtengine/vng4_demosaic_RT.cc | 2 +- rtengine/xtrans_demosaic.cc | 2 +- rtexif/canonattribs.cc | 2 +- rtexif/fujiattribs.cc | 2 +- rtexif/nikonattribs.cc | 2 +- rtexif/olympusattribs.cc | 2 +- rtexif/pentaxattribs.cc | 2 +- rtexif/rtexif.cc | 2 +- rtexif/rtexif.h | 2 +- rtexif/sonyminoltaattribs.cc | 2 +- rtexif/stdattribs.cc | 2 +- rtgui/adjuster.cc | 2 +- rtgui/adjuster.h | 2 +- rtgui/alignedmalloc.cc | 2 +- rtgui/batchqueue.cc | 2 +- rtgui/batchqueue.h | 2 +- rtgui/batchqueuebuttonset.cc | 2 +- rtgui/batchqueuebuttonset.h | 2 +- rtgui/batchqueueentry.cc | 2 +- rtgui/batchqueueentry.h | 2 +- rtgui/batchqueuepanel.cc | 2 +- rtgui/batchqueuepanel.h | 2 +- rtgui/batchtoolpanelcoord.cc | 2 +- rtgui/batchtoolpanelcoord.h | 2 +- rtgui/bayerpreprocess.cc | 2 +- rtgui/bayerpreprocess.h | 2 +- rtgui/bayerprocess.cc | 2 +- rtgui/bayerprocess.h | 2 +- rtgui/bayerrawexposure.cc | 2 +- rtgui/bayerrawexposure.h | 2 +- rtgui/blackwhite.cc | 2 +- rtgui/blackwhite.h | 2 +- rtgui/bqentryupdater.cc | 2 +- rtgui/bqentryupdater.h | 2 +- rtgui/browserfilter.cc | 2 +- rtgui/browserfilter.h | 2 +- rtgui/cacheimagedata.cc | 2 +- rtgui/cacheimagedata.h | 2 +- rtgui/cachemanager.cc | 2 +- rtgui/cachemanager.h | 2 +- rtgui/cacorrection.cc | 2 +- rtgui/cacorrection.h | 2 +- rtgui/checkbox.cc | 2 +- rtgui/checkbox.h | 2 +- rtgui/chmixer.cc | 2 +- rtgui/chmixer.h | 2 +- rtgui/clipboard.cc | 2 +- rtgui/clipboard.h | 2 +- rtgui/coarsepanel.cc | 2 +- rtgui/coarsepanel.h | 2 +- rtgui/colorappearance.cc | 2 +- rtgui/colorappearance.h | 2 +- rtgui/coloredbar.cc | 2 +- rtgui/coloredbar.h | 2 +- rtgui/colorprovider.h | 2 +- rtgui/config.h.in | 2 +- rtgui/coordinateadjuster.cc | 2 +- rtgui/coordinateadjuster.h | 2 +- rtgui/crop.cc | 2 +- rtgui/crop.h | 2 +- rtgui/cropguilistener.h | 2 +- rtgui/crophandler.cc | 2 +- rtgui/crophandler.h | 2 +- rtgui/cropwindow.cc | 2 +- rtgui/cropwindow.h | 2 +- rtgui/cursormanager.cc | 2 +- rtgui/cursormanager.h | 2 +- rtgui/curveeditor.cc | 2 +- rtgui/curveeditor.h | 2 +- rtgui/curveeditorgroup.cc | 2 +- rtgui/curveeditorgroup.h | 2 +- rtgui/curvelistener.h | 2 +- rtgui/darkframe.cc | 2 +- rtgui/darkframe.h | 2 +- rtgui/defringe.cc | 2 +- rtgui/defringe.h | 2 +- rtgui/dehaze.cc | 2 +- rtgui/dehaze.h | 2 +- rtgui/diagonalcurveeditorsubgroup.cc | 2 +- rtgui/diagonalcurveeditorsubgroup.h | 2 +- rtgui/dirbrowser.cc | 2 +- rtgui/dirbrowser.h | 2 +- rtgui/dirpyrdenoise.cc | 2 +- rtgui/dirpyrdenoise.h | 2 +- rtgui/dirpyrequalizer.cc | 2 +- rtgui/dirpyrequalizer.h | 2 +- rtgui/distortion.cc | 2 +- rtgui/distortion.h | 2 +- rtgui/dynamicprofilepanel.cc | 2 +- rtgui/dynamicprofilepanel.h | 2 +- rtgui/editbuffer.cc | 2 +- rtgui/editbuffer.h | 2 +- rtgui/editcallbacks.cc | 2 +- rtgui/editcallbacks.h | 2 +- rtgui/editcoordsys.h | 2 +- rtgui/editedstate.h | 2 +- rtgui/editenums.h | 2 +- rtgui/editid.h | 2 +- rtgui/editorpanel.cc | 2 +- rtgui/editorpanel.h | 2 +- rtgui/editwidgets.cc | 2 +- rtgui/editwidgets.h | 2 +- rtgui/editwindow.cc | 2 +- rtgui/editwindow.h | 2 +- rtgui/epd.cc | 2 +- rtgui/epd.h | 2 +- rtgui/eventmapper.cc | 2 +- rtgui/eventmapper.h | 2 +- rtgui/exiffiltersettings.cc | 2 +- rtgui/exiffiltersettings.h | 2 +- rtgui/exifpanel.cc | 2 +- rtgui/exifpanel.h | 2 +- rtgui/exportpanel.cc | 2 +- rtgui/exportpanel.h | 2 +- rtgui/extprog.cc | 2 +- rtgui/extprog.h | 2 +- rtgui/fattaltonemap.cc | 2 +- rtgui/fattaltonemap.h | 2 +- rtgui/favoritbrowser.cc | 2 +- rtgui/favoritbrowser.h | 2 +- rtgui/filebrowser.cc | 2 +- rtgui/filebrowser.h | 2 +- rtgui/filebrowserentry.cc | 2 +- rtgui/filebrowserentry.h | 2 +- rtgui/filecatalog.cc | 2 +- rtgui/filecatalog.h | 2 +- rtgui/filepanel.cc | 2 +- rtgui/filepanel.h | 2 +- rtgui/fileselectionchangelistener.h | 2 +- rtgui/fileselectionlistener.h | 2 +- rtgui/filethumbnailbuttonset.cc | 2 +- rtgui/filethumbnailbuttonset.h | 2 +- rtgui/filmnegative.cc | 2 +- rtgui/filmnegative.h | 2 +- rtgui/filterpanel.cc | 2 +- rtgui/filterpanel.h | 2 +- rtgui/flatcurveeditorsubgroup.cc | 2 +- rtgui/flatcurveeditorsubgroup.h | 2 +- rtgui/flatfield.cc | 2 +- rtgui/flatfield.h | 2 +- rtgui/guiutils.cc | 2 +- rtgui/guiutils.h | 2 +- rtgui/histogrampanel.cc | 2 +- rtgui/histogrampanel.h | 2 +- rtgui/history.cc | 2 +- rtgui/history.h | 2 +- rtgui/hsvequalizer.cc | 2 +- rtgui/hsvequalizer.h | 2 +- rtgui/iccprofilecreator.cc | 2 +- rtgui/iccprofilecreator.h | 2 +- rtgui/icmpanel.cc | 2 +- rtgui/icmpanel.h | 2 +- rtgui/ilabel.cc | 2 +- rtgui/ilabel.h | 2 +- rtgui/imagearea.cc | 2 +- rtgui/imagearea.h | 2 +- rtgui/imageareapanel.cc | 2 +- rtgui/imageareapanel.h | 2 +- rtgui/imageareatoollistener.h | 2 +- rtgui/impulsedenoise.cc | 2 +- rtgui/impulsedenoise.h | 2 +- rtgui/indclippedpanel.cc | 2 +- rtgui/indclippedpanel.h | 2 +- rtgui/inspector.cc | 2 +- rtgui/inspector.h | 2 +- rtgui/iptcpanel.cc | 2 +- rtgui/iptcpanel.h | 2 +- rtgui/labcurve.cc | 2 +- rtgui/labcurve.h | 2 +- rtgui/labgrid.cc | 4 ++-- rtgui/labgrid.h | 4 ++-- rtgui/lensgeom.cc | 2 +- rtgui/lensgeom.h | 2 +- rtgui/lensgeomlistener.h | 2 +- rtgui/lensprofile.cc | 2 +- rtgui/lensprofile.h | 2 +- rtgui/localcontrast.cc | 2 +- rtgui/localcontrast.h | 2 +- rtgui/lockablecolorpicker.cc | 2 +- rtgui/lockablecolorpicker.h | 2 +- rtgui/lwbutton.cc | 2 +- rtgui/lwbutton.h | 2 +- rtgui/lwbuttonset.cc | 2 +- rtgui/lwbuttonset.h | 2 +- rtgui/main-cli.cc | 2 +- rtgui/main.cc | 2 +- rtgui/metadatapanel.cc | 2 +- rtgui/metadatapanel.h | 2 +- rtgui/multilangmgr.cc | 2 +- rtgui/multilangmgr.h | 2 +- rtgui/mycurve.cc | 2 +- rtgui/mycurve.h | 2 +- rtgui/mydiagonalcurve.cc | 2 +- rtgui/mydiagonalcurve.h | 2 +- rtgui/myflatcurve.cc | 2 +- rtgui/myflatcurve.h | 2 +- rtgui/navigator.cc | 2 +- rtgui/navigator.h | 2 +- rtgui/options.cc | 2 +- rtgui/options.h | 2 +- rtgui/paramsedited.cc | 2 +- rtgui/paramsedited.h | 2 +- rtgui/partialpastedlg.cc | 2 +- rtgui/partialpastedlg.h | 2 +- rtgui/pathutils.cc | 2 +- rtgui/pathutils.h | 2 +- rtgui/perspective.cc | 2 +- rtgui/perspective.h | 2 +- rtgui/placesbrowser.cc | 2 +- rtgui/placesbrowser.h | 2 +- rtgui/pointermotionlistener.h | 2 +- rtgui/popupbutton.cc | 2 +- rtgui/popupbutton.h | 2 +- rtgui/popupcommon.cc | 2 +- rtgui/popupcommon.h | 2 +- rtgui/popuptogglebutton.cc | 2 +- rtgui/popuptogglebutton.h | 2 +- rtgui/pparamschangelistener.h | 2 +- rtgui/preferences.cc | 2 +- rtgui/preferences.h | 2 +- rtgui/preprocess.cc | 2 +- rtgui/preprocess.h | 2 +- rtgui/previewhandler.cc | 2 +- rtgui/previewhandler.h | 2 +- rtgui/previewloader.cc | 2 +- rtgui/previewloader.h | 2 +- rtgui/previewmodepanel.cc | 2 +- rtgui/previewmodepanel.h | 2 +- rtgui/previewwindow.cc | 2 +- rtgui/previewwindow.h | 2 +- rtgui/procparamchangers.h | 2 +- rtgui/profilechangelistener.h | 2 +- rtgui/profilepanel.cc | 2 +- rtgui/profilepanel.h | 2 +- rtgui/profilestorecombobox.cc | 2 +- rtgui/profilestorecombobox.h | 2 +- rtgui/progressconnector.h | 2 +- rtgui/prsharpening.cc | 2 +- rtgui/prsharpening.h | 2 +- rtgui/rawcacorrection.cc | 2 +- rtgui/rawcacorrection.h | 2 +- rtgui/rawexposure.cc | 2 +- rtgui/rawexposure.h | 2 +- rtgui/recentbrowser.cc | 2 +- rtgui/recentbrowser.h | 2 +- rtgui/renamedlg.cc | 2 +- rtgui/renamedlg.h | 2 +- rtgui/resize.cc | 2 +- rtgui/resize.h | 2 +- rtgui/rgbcurves.cc | 2 +- rtgui/rgbcurves.h | 2 +- rtgui/rotate.cc | 2 +- rtgui/rotate.h | 2 +- rtgui/rtimage.cc | 2 +- rtgui/rtimage.h | 2 +- rtgui/rtscalable.cc | 2 +- rtgui/rtscalable.h | 2 +- rtgui/rtsurface.cc | 2 +- rtgui/rtsurface.h | 2 +- rtgui/rtwindow.cc | 2 +- rtgui/rtwindow.h | 2 +- rtgui/saveasdlg.cc | 2 +- rtgui/saveasdlg.h | 2 +- rtgui/saveformatpanel.cc | 2 +- rtgui/saveformatpanel.h | 2 +- rtgui/sensorbayer.cc | 2 +- rtgui/sensorbayer.h | 2 +- rtgui/sensorxtrans.cc | 2 +- rtgui/sensorxtrans.h | 2 +- rtgui/shadowshighlights.cc | 2 +- rtgui/shadowshighlights.h | 2 +- rtgui/sharpenedge.cc | 2 +- rtgui/sharpenedge.h | 2 +- rtgui/sharpening.cc | 2 +- rtgui/sharpening.h | 2 +- rtgui/sharpenmicro.cc | 2 +- rtgui/sharpenmicro.h | 2 +- rtgui/shcselector.cc | 2 +- rtgui/shcselector.h | 2 +- rtgui/softlight.cc | 2 +- rtgui/softlight.h | 2 +- rtgui/soundman.cc | 2 +- rtgui/soundman.h | 2 +- rtgui/splash.cc | 2 +- rtgui/splash.h | 2 +- rtgui/threadutils.cc | 2 +- rtgui/threadutils.h | 2 +- rtgui/thresholdadjuster.cc | 2 +- rtgui/thresholdadjuster.h | 2 +- rtgui/thresholdselector.cc | 2 +- rtgui/thresholdselector.h | 2 +- rtgui/thumbbrowserbase.cc | 2 +- rtgui/thumbbrowserbase.h | 2 +- rtgui/thumbbrowserentrybase.cc | 2 +- rtgui/thumbbrowserentrybase.h | 2 +- rtgui/thumbimageupdater.cc | 2 +- rtgui/thumbimageupdater.h | 2 +- rtgui/thumbnail.cc | 2 +- rtgui/thumbnail.h | 2 +- rtgui/thumbnailbrowser.h | 2 +- rtgui/thumbnaillistener.h | 2 +- rtgui/tonecurve.cc | 2 +- rtgui/tonecurve.h | 2 +- rtgui/toolbar.cc | 2 +- rtgui/toolbar.h | 2 +- rtgui/toolenum.h | 2 +- rtgui/toolpanel.cc | 2 +- rtgui/toolpanel.h | 2 +- rtgui/toolpanelcoord.cc | 2 +- rtgui/toolpanelcoord.h | 2 +- rtgui/vibrance.cc | 2 +- rtgui/vibrance.h | 2 +- rtgui/vignetting.cc | 2 +- rtgui/vignetting.h | 2 +- rtgui/wavelet.cc | 2 +- rtgui/wavelet.h | 2 +- rtgui/wbprovider.h | 2 +- rtgui/whitebalance.cc | 2 +- rtgui/whitebalance.h | 2 +- rtgui/xtransprocess.cc | 2 +- rtgui/xtransprocess.h | 2 +- rtgui/xtransrawexposure.cc | 2 +- rtgui/xtransrawexposure.h | 2 +- rtgui/zoompanel.cc | 2 +- rtgui/zoompanel.h | 2 +- tools/gimp-plugin/file-formats.h | 2 +- tools/gimp-plugin/file-rawtherapee.c | 2 +- 494 files changed, 498 insertions(+), 498 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 0aa0df7c8..653f0ac50 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -13,7 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/cmake/modules/FindUnalignedMalloc.cmake b/cmake/modules/FindUnalignedMalloc.cmake index 4ddfb2afc..bce150c14 100644 --- a/cmake/modules/FindUnalignedMalloc.cmake +++ b/cmake/modules/FindUnalignedMalloc.cmake @@ -13,7 +13,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RawTherapee. If not, see . +# along with RawTherapee. If not, see . include(CheckCXXSourceCompiles) diff --git a/cmake/modules/FindX87Math.cmake b/cmake/modules/FindX87Math.cmake index b25ba3292..c079c584b 100644 --- a/cmake/modules/FindX87Math.cmake +++ b/cmake/modules/FindX87Math.cmake @@ -13,7 +13,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RawTherapee. If not, see . +# along with RawTherapee. If not, see . include(CheckCXXSourceCompiles) diff --git a/header b/header index c42b87574..966153c0e 100644 --- a/header +++ b/header @@ -14,5 +14,5 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ diff --git a/rtdata/languages/LICENSE b/rtdata/languages/LICENSE index fbc14b67e..b269339a6 100755 --- a/rtdata/languages/LICENSE +++ b/rtdata/languages/LICENSE @@ -13,6 +13,6 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RawTherapee. If not, see . +# along with RawTherapee. If not, see . # diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index 45dec6e39..3f5072f48 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ /***************************/ diff --git a/rtdata/themes/RawTherapee-GTK3-_19.css b/rtdata/themes/RawTherapee-GTK3-_19.css index a796b60a1..58742e8ca 100644 --- a/rtdata/themes/RawTherapee-GTK3-_19.css +++ b/rtdata/themes/RawTherapee-GTK3-_19.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ * { diff --git a/rtdata/themes/TooWaBlue - Bright-GTK3-20_.css b/rtdata/themes/TooWaBlue - Bright-GTK3-20_.css index d1bb4fdbc..19e2eb049 100644 --- a/rtdata/themes/TooWaBlue - Bright-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue - Bright-GTK3-20_.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ diff --git a/rtdata/themes/TooWaBlue - Dark-GTK3-20_.css b/rtdata/themes/TooWaBlue - Dark-GTK3-20_.css index 581549750..5875e2132 100644 --- a/rtdata/themes/TooWaBlue - Dark-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue - Dark-GTK3-20_.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ diff --git a/rtdata/themes/TooWaBlue-GTK3-20_.css b/rtdata/themes/TooWaBlue-GTK3-20_.css index 7b5089430..ce4bb8d28 100644 --- a/rtdata/themes/TooWaBlue-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue-GTK3-20_.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/TooWaBlue-GTK3-_19.css b/rtdata/themes/TooWaBlue-GTK3-_19.css index 530ae3d3a..31676ca8d 100644 --- a/rtdata/themes/TooWaBlue-GTK3-_19.css +++ b/rtdata/themes/TooWaBlue-GTK3-_19.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css b/rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css index 29ebd6c96..8f045e206 100644 --- a/rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ diff --git a/rtdata/themes/TooWaGrey - Bright-GTK3-20_.css b/rtdata/themes/TooWaGrey - Bright-GTK3-20_.css index 74dd5c7f0..579ca7a00 100644 --- a/rtdata/themes/TooWaGrey - Bright-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey - Bright-GTK3-20_.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ diff --git a/rtdata/themes/TooWaGrey - Dark-GTK3-20_.css b/rtdata/themes/TooWaGrey - Dark-GTK3-20_.css index 0f61e0935..8d6d05152 100644 --- a/rtdata/themes/TooWaGrey - Dark-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey - Dark-GTK3-20_.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ diff --git a/rtdata/themes/TooWaGrey-GTK3-20_.css b/rtdata/themes/TooWaGrey-GTK3-20_.css index f681ef374..0b29ed2e7 100644 --- a/rtdata/themes/TooWaGrey-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey-GTK3-20_.css @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . + along with RawTherapee. If not, see . */ diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index 46a62cc4b..a2d68402f 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -18,7 +18,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index ccffbe59c..d1e659114 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -18,7 +18,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/LUT.h b/rtengine/LUT.h index 6584eefe6..34f572f58 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /* diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index fe89a7b65..7df042663 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -23,7 +23,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/StopWatch.h b/rtengine/StopWatch.h index 5eb103da4..94be402e4 100644 --- a/rtengine/StopWatch.h +++ b/rtengine/StopWatch.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Author: reine */ diff --git a/rtengine/ahd_demosaic_RT.cc b/rtengine/ahd_demosaic_RT.cc index 13cbd4d2a..b3a34295c 100644 --- a/rtengine/ahd_demosaic_RT.cc +++ b/rtengine/ahd_demosaic_RT.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ // diff --git a/rtengine/alignedbuffer.h b/rtengine/alignedbuffer.h index 846c4c47d..b2c720bd8 100644 --- a/rtengine/alignedbuffer.h +++ b/rtengine/alignedbuffer.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _ALIGNEDBUFFER_ #define _ALIGNEDBUFFER_ diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index 47aa45c14..43aef0f71 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -22,7 +22,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/array2D.h b/rtengine/array2D.h index 84728f043..7713cd55c 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /* diff --git a/rtengine/badpixels.cc b/rtengine/badpixels.cc index 376e58b3b..79b8187f7 100644 --- a/rtengine/badpixels.cc +++ b/rtengine/badpixels.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "array2D.h" diff --git a/rtengine/bilateral2.h b/rtengine/bilateral2.h index e754ac891..d0496810d 100644 --- a/rtengine/bilateral2.h +++ b/rtengine/bilateral2.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BILATERAL2_ #define _BILATERAL2_ diff --git a/rtengine/boxblur.h b/rtengine/boxblur.h index d686ad43e..da302964b 100644 --- a/rtengine/boxblur.h +++ b/rtengine/boxblur.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BOXBLUR_H_ #define _BOXBLUR_H_ diff --git a/rtengine/cache.h b/rtengine/cache.h index ec284b2ae..6c1dacf43 100644 --- a/rtengine/cache.h +++ b/rtengine/cache.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/cfa_linedn_RT.cc b/rtengine/cfa_linedn_RT.cc index a7b789caf..5f6e46f8f 100644 --- a/rtengine/cfa_linedn_RT.cc +++ b/rtengine/cfa_linedn_RT.cc @@ -18,7 +18,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc index 86b67e000..dfef273d6 100644 --- a/rtengine/ciecam02.cc +++ b/rtengine/ciecam02.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "ciecam02.h" #include "rtengine.h" diff --git a/rtengine/ciecam02.h b/rtengine/ciecam02.h index 68763b965..fea35ab12 100644 --- a/rtengine/ciecam02.h +++ b/rtengine/ciecam02.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CIECAM02_ #define _CIECAM02_ diff --git a/rtengine/cieimage.h b/rtengine/cieimage.h index 23b080ae3..660d40e78 100644 --- a/rtengine/cieimage.h +++ b/rtengine/cieimage.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CIEIMAGE_H_ #define _CIEIMAGE_H_ diff --git a/rtengine/color.cc b/rtengine/color.cc index 7c12c0ca5..24266e52d 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #include "rtengine.h" diff --git a/rtengine/color.h b/rtengine/color.h index 5bf178636..214f420d7 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index a22caddb8..3ddbdc28a 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "colortemp.h" #include "rtengine.h" diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index d529d844e..da83177be 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _COLORTEMP_ #define _COLORTEMP_ diff --git a/rtengine/coord.cc b/rtengine/coord.cc index bf9ee816e..0a73cc29d 100644 --- a/rtengine/coord.cc +++ b/rtengine/coord.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "coord.h" diff --git a/rtengine/coord.h b/rtengine/coord.h index 2f1325434..5f16cf606 100644 --- a/rtengine/coord.h +++ b/rtengine/coord.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __COORD__ diff --git a/rtengine/coord2d.h b/rtengine/coord2d.h index bc030f22e..252219e47 100644 --- a/rtengine/coord2d.h +++ b/rtengine/coord2d.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __COORD2D__ #define __COORD2D__ diff --git a/rtengine/cplx_wavelet_dec.cc b/rtengine/cplx_wavelet_dec.cc index a43a7b8b6..5b3650adc 100644 --- a/rtengine/cplx_wavelet_dec.cc +++ b/rtengine/cplx_wavelet_dec.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2010 Ilya Popov * 2012 Emil Martinec diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h index fab6119d9..91e71fcd5 100644 --- a/rtengine/cplx_wavelet_dec.h +++ b/rtengine/cplx_wavelet_dec.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2010 Ilya Popov * 2012 Emil Martinec diff --git a/rtengine/cplx_wavelet_filter_coeffs.h b/rtengine/cplx_wavelet_filter_coeffs.h index bd333d4b9..6b8255b89 100644 --- a/rtengine/cplx_wavelet_filter_coeffs.h +++ b/rtengine/cplx_wavelet_filter_coeffs.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2012 Emil Martinec * 2014 Jacques Desmis diff --git a/rtengine/cplx_wavelet_level.h b/rtengine/cplx_wavelet_level.h index cab0d8e3e..4c98addfe 100644 --- a/rtengine/cplx_wavelet_level.h +++ b/rtengine/cplx_wavelet_level.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2010 Ilya Popov * 2012 Emil Martinec diff --git a/rtengine/curves.cc b/rtengine/curves.cc index ef2a5bf92..a7e3337c8 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/curves.h b/rtengine/curves.h index 55068630a..25272d44c 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __CURVES_H__ #define __CURVES_H__ diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 6c948717a..8127ebfcb 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #include diff --git a/rtengine/dcp.h b/rtengine/dcp.h index 48b881661..826f073a5 100644 --- a/rtengine/dcp.h +++ b/rtengine/dcp.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 81da41718..fdebda0cc 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef DCRAW_H diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 69af056bf..61b96b3a3 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "curves.h" #include "dcrop.h" diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index 04274ca0c..6ce034f3f 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index dc12bc01a..49b386b0a 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include @@ -1121,7 +1121,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, array2D &r * Contact info: luis.sanz.rodriguez@gmail.com * * This code is distributed under a GNU General Public License, version 3. -* Visit for more information. +* Visit for more information. * ***/ // Adapted to RawTherapee by Jacques Desmis 3/2013 diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index 311921c52..4877aacd8 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "dfmanager.h" #include "../rtgui/options.h" diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h index 541981492..23ca97d14 100644 --- a/rtengine/dfmanager.h +++ b/rtengine/dfmanager.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index dd85b87de..bb20b7cc1 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 94826e06e..e822d8492 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * (C) 2010 Emil Martinec * diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index 4873ee670..60cce506b 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -19,7 +19,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 7b7f2a517..af6ecd2ff 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "../rtengine/dynamicprofile.h" diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index fc5c85e4c..aaffc5c4f 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DYNAMICPROFILE_H_ #define _DYNAMICPROFILE_H_ diff --git a/rtengine/eahd_demosaic.cc b/rtengine/eahd_demosaic.cc index 1663a087d..aa8fdf485 100644 --- a/rtengine/eahd_demosaic.cc +++ b/rtengine/eahd_demosaic.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/fast_demo.cc b/rtengine/fast_demo.cc index 4e3fbdabe..a40f107af 100644 --- a/rtengine/fast_demo.cc +++ b/rtengine/fast_demo.cc @@ -18,7 +18,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 56660a82a..e1a9134a8 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "ffmanager.h" #include "../rtgui/options.h" diff --git a/rtengine/ffmanager.h b/rtengine/ffmanager.h index 43fb2f368..537f8ee46 100644 --- a/rtengine/ffmanager.h +++ b/rtengine/ffmanager.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 12f19fba9..1a7270b82 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc index 8c7564b86..6a4da31b0 100644 --- a/rtengine/filmnegativethumb.cc +++ b/rtengine/filmnegativethumb.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/flatcurves.cc b/rtengine/flatcurves.cc index fe5ecc5e1..d24c20a70 100644 --- a/rtengine/flatcurves.cc +++ b/rtengine/flatcurves.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "curves.h" #include diff --git a/rtengine/gamutwarning.cc b/rtengine/gamutwarning.cc index c76e2a285..3fc20d43a 100644 --- a/rtengine/gamutwarning.cc +++ b/rtengine/gamutwarning.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /** diff --git a/rtengine/gamutwarning.h b/rtengine/gamutwarning.h index 19a27cdfd..e0aaa98d9 100644 --- a/rtengine/gamutwarning.h +++ b/rtengine/gamutwarning.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /** diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc index b7de67851..40014f211 100644 --- a/rtengine/gauss.cc +++ b/rtengine/gauss.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "gauss.h" #include diff --git a/rtengine/gauss.h b/rtengine/gauss.h index 72f115cc4..b63301d2b 100644 --- a/rtengine/gauss.h +++ b/rtengine/gauss.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _GAUSS_H_ #define _GAUSS_H_ diff --git a/rtengine/green_equil_RT.cc b/rtengine/green_equil_RT.cc index 361bde882..fc4f18548 100644 --- a/rtengine/green_equil_RT.cc +++ b/rtengine/green_equil_RT.cc @@ -19,7 +19,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/guidedfilter.cc b/rtengine/guidedfilter.cc index e7fe9b8af..0ebe6c172 100644 --- a/rtengine/guidedfilter.cc +++ b/rtengine/guidedfilter.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /** diff --git a/rtengine/guidedfilter.h b/rtengine/guidedfilter.h index 6691af251..af8ed0901 100644 --- a/rtengine/guidedfilter.h +++ b/rtengine/guidedfilter.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 7134ac34f..35dd74463 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -20,7 +20,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index f9268ea5d..212b11d00 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rawimagesource.h" diff --git a/rtengine/hphd_demosaic_RT.cc b/rtengine/hphd_demosaic_RT.cc index 7e27b90a5..0e56eae48 100644 --- a/rtengine/hphd_demosaic_RT.cc +++ b/rtengine/hphd_demosaic_RT.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/iccmatrices.h b/rtengine/iccmatrices.h index 29426c62d..3e0d0b5d6 100644 --- a/rtengine/iccmatrices.h +++ b/rtengine/iccmatrices.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _ICCMATRICES_ #define _ICCMATRICES_ diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 268a6b1c2..a8d54b810 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 6b57fd072..5c76660e5 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/iimage.cc b/rtengine/iimage.cc index c9a4f223a..a1ec979a1 100644 --- a/rtengine/iimage.cc +++ b/rtengine/iimage.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "procparams.h" diff --git a/rtengine/iimage.h b/rtengine/iimage.h index ff016df1a..b04b4bf9a 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IIMAGE_ #define _IIMAGE_ diff --git a/rtengine/image16.cc b/rtengine/image16.cc index 7d4d3e41d..0cdcc578f 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "image16.h" #include "imagefloat.h" diff --git a/rtengine/image16.h b/rtengine/image16.h index f31626939..07747a172 100644 --- a/rtengine/image16.h +++ b/rtengine/image16.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ // // A class representing a 16 bit rgb image with separate planes and 16 byte aligned data diff --git a/rtengine/image8.cc b/rtengine/image8.cc index 850ec87c0..abcd4efae 100644 --- a/rtengine/image8.cc +++ b/rtengine/image8.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/image8.h b/rtengine/image8.h index 57852b7af..969627f69 100644 --- a/rtengine/image8.h +++ b/rtengine/image8.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ // // A class representing a 8 bit rgb image without alpha channel diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index b074cdbb2..403f4708c 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 774547487..99caaf361 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __IMAGEDATA_H__ #define __IMAGEDATA_H__ diff --git a/rtengine/imagedimensions.cc b/rtengine/imagedimensions.cc index 7dec1358a..5b60e5da7 100644 --- a/rtengine/imagedimensions.cc +++ b/rtengine/imagedimensions.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "imagedimensions.h" diff --git a/rtengine/imagedimensions.h b/rtengine/imagedimensions.h index 63b1a1062..eb92798c3 100644 --- a/rtengine/imagedimensions.h +++ b/rtengine/imagedimensions.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index 793915604..8a9a511a6 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "imagefloat.h" diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index 805971e7a..261a0677c 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ // // A class representing a 16 bit rgb image with separate planes and 16 byte aligned data diff --git a/rtengine/imageformat.h b/rtengine/imageformat.h index 22708daef..dc40cf147 100644 --- a/rtengine/imageformat.h +++ b/rtengine/imageformat.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IMAGEFORMAT_ #define _IMAGEFORMAT_ diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 1e4f8c008..f335f5be8 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/imageio.h b/rtengine/imageio.h index fd2cbc2b9..89c482ca3 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IMAGEIO_ #define _IMAGEIO_ diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index bf73b5bb2..705d29d62 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index daadcb16c..b74c14e2e 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "improccoordinator.h" #include "curves.h" diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index fdf74d297..fbe233607 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IMPROCCOORDINATOR_H_ #define _IMPROCCOORDINATOR_H_ diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 23dc4b1ba..db77e02fa 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include @@ -5815,7 +5815,7 @@ void ImProcFunctions::lab2rgb (const LabImage &src, Imagefloat &dst, const Glib: GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with darktable. If not, see . + along with darktable. If not, see . */ void ImProcFunctions::colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread) { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 987a460d7..8278e2f37 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IMPROCFUN_H_ #define _IMPROCFUN_H_ diff --git a/rtengine/impulse_denoise.cc b/rtengine/impulse_denoise.cc index 907afc1a1..c08f55700 100644 --- a/rtengine/impulse_denoise.cc +++ b/rtengine/impulse_denoise.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2010 Emil Martinec * diff --git a/rtengine/init.cc b/rtengine/init.cc index 8d7ee451f..8d3ee96cb 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "../rtgui/profilestorecombobox.h" diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 42a5f92b3..60d4cb9ff 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /* diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 8b5a2cb71..14aeb4049 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtengine.h" #include "improcfun.h" diff --git a/rtengine/iplabregions.cc b/rtengine/iplabregions.cc index 5945398d2..af6567c3c 100644 --- a/rtengine/iplabregions.cc +++ b/rtengine/iplabregions.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifdef _OPENMP diff --git a/rtengine/iplocalcontrast.cc b/rtengine/iplocalcontrast.cc index 1bf21829e..6143f48a3 100644 --- a/rtengine/iplocalcontrast.cc +++ b/rtengine/iplocalcontrast.cc @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifdef _OPENMP diff --git a/rtengine/ipresize.cc b/rtengine/ipresize.cc index 2a66e68cb..0c1fb1ad8 100644 --- a/rtengine/ipresize.cc +++ b/rtengine/ipresize.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "improcfun.h" diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 309c7073b..7117c9f2a 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . * adaptation to RawTherapee * 2015 Jacques Desmis diff --git a/rtengine/ipshadowshighlights.cc b/rtengine/ipshadowshighlights.cc index 2433ca13c..cddc8734b 100644 --- a/rtengine/ipshadowshighlights.cc +++ b/rtengine/ipshadowshighlights.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "improcfun.h" diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 9d7358fa9..73510fe92 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "improcfun.h" diff --git a/rtengine/ipsoftlight.cc b/rtengine/ipsoftlight.cc index 6aca9b8eb..c7a4d1af7 100644 --- a/rtengine/ipsoftlight.cc +++ b/rtengine/ipsoftlight.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifdef _OPENMP diff --git a/rtengine/iptcpairs.h b/rtengine/iptcpairs.h index e0b34180f..21099735a 100644 --- a/rtengine/iptcpairs.h +++ b/rtengine/iptcpairs.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IPTCPAIRS_ #define _IPTCPAIRS_ diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 5b1e7c458..8dee92479 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtengine.h" #include "improcfun.h" diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc index ca938fbbe..a7199064a 100644 --- a/rtengine/ipvibrance.cc +++ b/rtengine/ipvibrance.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rt_math.h" diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index ff7aefa19..07e9da85b 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -16,7 +16,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // * 2014 Jacques Desmis // * 2014 Ingo Weyrich diff --git a/rtengine/jaggedarray.h b/rtengine/jaggedarray.h index 01da776a6..59c1485d8 100644 --- a/rtengine/jaggedarray.h +++ b/rtengine/jaggedarray.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/labimage.cc b/rtengine/labimage.cc index 81b1a4303..b31bc89a1 100644 --- a/rtengine/labimage.cc +++ b/rtengine/labimage.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/labimage.h b/rtengine/labimage.h index 28bb891a9..bcc2484ab 100644 --- a/rtengine/labimage.h +++ b/rtengine/labimage.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _LABIMAGE_H_ #define _LABIMAGE_H_ diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index cf025ddbe..b456fc478 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #include diff --git a/rtengine/lcp.h b/rtengine/lcp.h index 2d9707907..30b7e5191 100644 --- a/rtengine/lcp.h +++ b/rtengine/lcp.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/loadinitial.cc b/rtengine/loadinitial.cc index 6192ca6db..00dbbf836 100644 --- a/rtengine/loadinitial.cc +++ b/rtengine/loadinitial.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtengine.h" #include "stdimagesource.h" diff --git a/rtengine/median.h b/rtengine/median.h index 30adbacb3..acd92235c 100644 --- a/rtengine/median.h +++ b/rtengine/median.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * These median implementations from Flössie and Ingo Weyrich are inspired by this work: * diff --git a/rtengine/myfile.cc b/rtengine/myfile.cc index 28d187e4c..259e08565 100644 --- a/rtengine/myfile.cc +++ b/rtengine/myfile.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "myfile.h" #include diff --git a/rtengine/myfile.h b/rtengine/myfile.h index e4609c697..f2ed4150c 100644 --- a/rtengine/myfile.h +++ b/rtengine/myfile.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _MYFILE_ #define _MYFILE_ diff --git a/rtengine/mytime.h b/rtengine/mytime.h index a0ce15bc7..80fb0899a 100644 --- a/rtengine/mytime.h +++ b/rtengine/mytime.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/noncopyable.h b/rtengine/noncopyable.h index d34c42441..d915a6f78 100644 --- a/rtengine/noncopyable.h +++ b/rtengine/noncopyable.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/opthelper.h b/rtengine/opthelper.h index ce1f620e1..b65ede227 100644 --- a/rtengine/opthelper.h +++ b/rtengine/opthelper.h @@ -15,7 +15,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/pdaflinesfilter.cc b/rtengine/pdaflinesfilter.cc index 0c5b2d786..d0694fd11 100644 --- a/rtengine/pdaflinesfilter.cc +++ b/rtengine/pdaflinesfilter.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "pdaflinesfilter.h" diff --git a/rtengine/pdaflinesfilter.h b/rtengine/pdaflinesfilter.h index 3ae406ec8..7f4c7985b 100644 --- a/rtengine/pdaflinesfilter.h +++ b/rtengine/pdaflinesfilter.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/pipettebuffer.cc b/rtengine/pipettebuffer.cc index 4ad8afad1..d915381ef 100644 --- a/rtengine/pipettebuffer.cc +++ b/rtengine/pipettebuffer.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "pipettebuffer.h" diff --git a/rtengine/pipettebuffer.h b/rtengine/pipettebuffer.h index ab9ba6197..01b24720c 100644 --- a/rtengine/pipettebuffer.h +++ b/rtengine/pipettebuffer.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index b31ff62c9..4b93f3f61 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -16,7 +16,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/pixelsmap.h b/rtengine/pixelsmap.h index b359d61d9..f747c52d9 100644 --- a/rtengine/pixelsmap.h +++ b/rtengine/pixelsmap.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index e62a1adea..7216e6a34 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "previewimage.h" diff --git a/rtengine/previewimage.h b/rtengine/previewimage.h index 26b9a85d2..71ddefe8a 100644 --- a/rtengine/previewimage.h +++ b/rtengine/previewimage.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PREVIEWIMAGE_ #define _PREVIEWIMAGE_ diff --git a/rtengine/processingjob.cc b/rtengine/processingjob.cc index a377e3963..2f9c15196 100644 --- a/rtengine/processingjob.cc +++ b/rtengine/processingjob.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "processingjob.h" diff --git a/rtengine/processingjob.h b/rtengine/processingjob.h index b2a81e4c2..004eb006f 100644 --- a/rtengine/processingjob.h +++ b/rtengine/processingjob.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PROCESSINGJOB_ #define _PROCESSINGJOB_ diff --git a/rtengine/procevents.h b/rtengine/procevents.h index bb6a30038..32fdb0f4e 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __PROCEVENT__ #define __PROCEVENT__ diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f14d72871..0d7d55286 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6ae807d7e..253ed26eb 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 776dd7caa..5c38cf705 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "profilestore.h" diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index d8c193935..384aa2a46 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PROFILESTORE_ #define _PROFILESTORE_ diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index ae0bcea84..9c6d42969 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __RAWIMAGE_H #define __RAWIMAGE_H diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index a1762af93..d0fb87313 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 940773271..decdcef12 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/rawimagesource_i.h b/rtengine/rawimagesource_i.h index b24115e0a..485205d9d 100644 --- a/rtengine/rawimagesource_i.h +++ b/rtengine/rawimagesource_i.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef RAWIMAGESOURCE_I_H_INCLUDED diff --git a/rtengine/rawmetadatalocation.h b/rtengine/rawmetadatalocation.h index de6c6a0d7..559815a4f 100644 --- a/rtengine/rawmetadatalocation.h +++ b/rtengine/rawmetadatalocation.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RAWMETADATALOCATION_ #define _RAWMETADATALOCATION_ diff --git a/rtengine/rcd_demosaic.cc b/rtengine/rcd_demosaic.cc index 95c5b4792..48c3ad334 100644 --- a/rtengine/rcd_demosaic.cc +++ b/rtengine/rcd_demosaic.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index d741b1744..94c3e71f8 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "refreshmap.h" #include "procevents.h" diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index b9ccc2b65..2890d8f19 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __REFRESHMAP__ #define __REFRESHMAP__ diff --git a/rtengine/rescale.h b/rtengine/rescale.h index ba9a01c99..e9d476fea 100644 --- a/rtengine/rescale.h +++ b/rtengine/rescale.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc index 1011ae7b7..5c5da6bca 100644 --- a/rtengine/rt_algo.cc +++ b/rtengine/rt_algo.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/rt_algo.h b/rtengine/rt_algo.h index a8e2e3e23..bf442b9be 100644 --- a/rtengine/rt_algo.h +++ b/rtengine/rt_algo.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index f772975b0..a0be5a7f6 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 5f0ffdd91..8c634eaa8 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtlensfun.h" diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h index 8b097b30e..092e2bf01 100644 --- a/rtengine/rtlensfun.h +++ b/rtengine/rtlensfun.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 3e970ed0d..25f50980d 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtengine.h" #include "rtthumbnail.h" diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index 09a0510eb..8b3f27a8b 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THUMBPROCESSINGPARAMETERS_ #define _THUMBPROCESSINGPARAMETERS_ diff --git a/rtengine/settings.h b/rtengine/settings.h index 1fc3b222c..8852c05c8 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RTSETTINGS_ #define _RTSETTINGS_ diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index 1eb911220..6b59c4b40 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "shmap.h" #include "gauss.h" diff --git a/rtengine/shmap.h b/rtengine/shmap.h index 4234e203d..539ef99ff 100644 --- a/rtengine/shmap.h +++ b/rtengine/shmap.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __SHMAP__ #define __SHMAP__ diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 8d24514d6..d80abe045 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtengine.h" #include "colortemp.h" diff --git a/rtengine/slicer.cc b/rtengine/slicer.cc index 72a42e07e..96c0a0ee8 100644 --- a/rtengine/slicer.cc +++ b/rtengine/slicer.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtengine/slicer.h b/rtengine/slicer.h index 06e1522cd..658133e5f 100644 --- a/rtengine/slicer.h +++ b/rtengine/slicer.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SLICER_ #define _SLICER_ diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index e5c98a93a..2ec1529f7 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "stdimagesource.h" diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 8f16880dc..8ad8cb8ea 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _STDIMAGESOURCE_ #define _STDIMAGESOURCE_ diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index 76da1f03d..6b5460ffd 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /** diff --git a/rtengine/utils.cc b/rtengine/utils.cc index 613b67be8..a07a1235f 100644 --- a/rtengine/utils.cc +++ b/rtengine/utils.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtengine/utils.h b/rtengine/utils.h index 14593edae..e0097d76e 100644 --- a/rtengine/utils.h +++ b/rtengine/utils.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtengine/vng4_demosaic_RT.cc b/rtengine/vng4_demosaic_RT.cc index f9a4c5bc2..66413e4c7 100644 --- a/rtengine/vng4_demosaic_RT.cc +++ b/rtengine/vng4_demosaic_RT.cc @@ -16,7 +16,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index 866bc9714..e84b5217e 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -15,7 +15,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . // //////////////////////////////////////////////////////////////// diff --git a/rtexif/canonattribs.cc b/rtexif/canonattribs.cc index 2dcbdd96f..0e6f7eb2f 100644 --- a/rtexif/canonattribs.cc +++ b/rtexif/canonattribs.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CANONATTRIBS_ #define _CANONATTRIBS_ diff --git a/rtexif/fujiattribs.cc b/rtexif/fujiattribs.cc index 2e17a68f9..0eaa505f6 100644 --- a/rtexif/fujiattribs.cc +++ b/rtexif/fujiattribs.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FUJIATTRIBS_ #define _FUJIATTRIBS_ diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc index 678b4b568..77720dde0 100644 --- a/rtexif/nikonattribs.cc +++ b/rtexif/nikonattribs.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _NIKONATTRIBS_ #define _NIKONATTRIBS_ diff --git a/rtexif/olympusattribs.cc b/rtexif/olympusattribs.cc index e42763e35..f9869f13e 100644 --- a/rtexif/olympusattribs.cc +++ b/rtexif/olympusattribs.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _OLYMPUSATTRIBS_ #define _OLYMPUSATTRIBS_ diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc index 7e861d64f..898150696 100644 --- a/rtexif/pentaxattribs.cc +++ b/rtexif/pentaxattribs.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PENTAXATTRIBS_ #define _PENTAXATTRIBS_ diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index dcc0ed56d..4e3be8486 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 0ee18ec7e..f4b0e089e 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _MEXIF3_ #define _MEXIF3_ diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc index 0c6e433ff..4410a4051 100644 --- a/rtexif/sonyminoltaattribs.cc +++ b/rtexif/sonyminoltaattribs.cc @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SONYMINOLTAATTRIBS_ #define _SONYMINOLTAATTRIBS_ diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc index ec5534381..8e076152d 100644 --- a/rtexif/stdattribs.cc +++ b/rtexif/stdattribs.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _STDATTRIBS_ #define _STDATTRIBS_ diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index 5a3f783db..5182cd825 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "adjuster.h" #include diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h index f3f256940..52857a3d2 100644 --- a/rtgui/adjuster.h +++ b/rtgui/adjuster.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _ADJUSTER_H_ #define _ADJUSTER_H_ diff --git a/rtgui/alignedmalloc.cc b/rtgui/alignedmalloc.cc index 91fe15a85..85517e5c0 100644 --- a/rtgui/alignedmalloc.cc +++ b/rtgui/alignedmalloc.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "config.h" diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 3fb2cd438..abb37b24d 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index 6f1b8f7f8..f61b7b5c4 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BATCHQUEUE_ #define _BATCHQUEUE_ diff --git a/rtgui/batchqueuebuttonset.cc b/rtgui/batchqueuebuttonset.cc index b42d3c773..a8be9eedf 100644 --- a/rtgui/batchqueuebuttonset.cc +++ b/rtgui/batchqueuebuttonset.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "batchqueuebuttonset.h" diff --git a/rtgui/batchqueuebuttonset.h b/rtgui/batchqueuebuttonset.h index e97819719..19479ccc1 100644 --- a/rtgui/batchqueuebuttonset.h +++ b/rtgui/batchqueuebuttonset.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BATCHQUEUEBUTTONSET_ #define _BATCHQUEUEBUTTONSET_ diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 78e3991c7..424c8e486 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "batchqueueentry.h" diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index 4972eaf7a..03097e55e 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BATCHQUEUEENTRY_ #define _BATCHQUEUEENTRY_ diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index b800907e9..9107aaaa8 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "batchqueuepanel.h" #include "options.h" diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index a1ee7326f..2f8e27057 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BATCHQUEUEPANEL_ #define _BATCHQUEUEPANEL_ diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 1a0eaeb28..592b59a4f 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "multilangmgr.h" #include "batchtoolpanelcoord.h" diff --git a/rtgui/batchtoolpanelcoord.h b/rtgui/batchtoolpanelcoord.h index f5889f967..f03d1d4b2 100644 --- a/rtgui/batchtoolpanelcoord.h +++ b/rtgui/batchtoolpanelcoord.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __BATCHTOOLPANELCCORD__ #define __BATCHTOOLPANELCCORD__ diff --git a/rtgui/bayerpreprocess.cc b/rtgui/bayerpreprocess.cc index 0ba60d045..0c01213e7 100644 --- a/rtgui/bayerpreprocess.cc +++ b/rtgui/bayerpreprocess.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/bayerpreprocess.h b/rtgui/bayerpreprocess.h index f50ac90bb..5d2b101d9 100644 --- a/rtgui/bayerpreprocess.h +++ b/rtgui/bayerpreprocess.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BAYERPREPROCESS_H_ #define _BAYERPREPROCESS_H_ diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index c361ded16..aa09067e4 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "bayerprocess.h" diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index df0c39d00..893010e65 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BAYERPROCESS_H_ #define _BAYERPROCESS_H_ diff --git a/rtgui/bayerrawexposure.cc b/rtgui/bayerrawexposure.cc index 12158c774..9d8f9fff8 100644 --- a/rtgui/bayerrawexposure.cc +++ b/rtgui/bayerrawexposure.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "bayerrawexposure.h" diff --git a/rtgui/bayerrawexposure.h b/rtgui/bayerrawexposure.h index e955afc12..5825383be 100644 --- a/rtgui/bayerrawexposure.h +++ b/rtgui/bayerrawexposure.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BAYERRAWEXPOSURE_H_ #define _BAYERRAWEXPOSURE_H_ diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index 2b97188e2..b5ecb96bd 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/blackwhite.h b/rtgui/blackwhite.h index 242926924..36234cda5 100644 --- a/rtgui/blackwhite.h +++ b/rtgui/blackwhite.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BLACKWHITE_H_ #define _BLACKWHITE_H_ diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc index 46aedc869..21a0f5ad0 100644 --- a/rtgui/bqentryupdater.cc +++ b/rtgui/bqentryupdater.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "bqentryupdater.h" #include diff --git a/rtgui/bqentryupdater.h b/rtgui/bqentryupdater.h index e25f5aed4..efd63f9de 100644 --- a/rtgui/bqentryupdater.h +++ b/rtgui/bqentryupdater.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BQENTRYUPDATER_ #define _BQENTRYUPDATER_ diff --git a/rtgui/browserfilter.cc b/rtgui/browserfilter.cc index cd3af072e..c6a8ae46b 100644 --- a/rtgui/browserfilter.cc +++ b/rtgui/browserfilter.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "browserfilter.h" diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h index ac9818ce5..f5dac180e 100644 --- a/rtgui/browserfilter.h +++ b/rtgui/browserfilter.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _BROWSERFILTER_ #define _BROWSERFILTER_ diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 1756f523b..d31b6c7a5 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "cacheimagedata.h" #include diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 9de9d186f..72bf55749 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CACHEIMAGEDATA_ #define _CACHEIMAGEDATA_ diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc index b270c3795..419538656 100644 --- a/rtgui/cachemanager.cc +++ b/rtgui/cachemanager.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/cachemanager.h b/rtgui/cachemanager.h index 99c732e88..3e987866d 100644 --- a/rtgui/cachemanager.h +++ b/rtgui/cachemanager.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CACHEMANAGER_ #define _CACHEMANAGER_ diff --git a/rtgui/cacorrection.cc b/rtgui/cacorrection.cc index 5b66dd6c3..971c0a284 100644 --- a/rtgui/cacorrection.cc +++ b/rtgui/cacorrection.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/cacorrection.h b/rtgui/cacorrection.h index 4fa85038c..f6e1f89e3 100644 --- a/rtgui/cacorrection.h +++ b/rtgui/cacorrection.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CACORRECTION_H_ #define _CACORRECTION_H_ diff --git a/rtgui/checkbox.cc b/rtgui/checkbox.cc index 1e3c2b61e..e05ba061a 100644 --- a/rtgui/checkbox.cc +++ b/rtgui/checkbox.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/checkbox.h b/rtgui/checkbox.h index b5ab4945f..48324d4c8 100644 --- a/rtgui/checkbox.h +++ b/rtgui/checkbox.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CHECKBOX_H_ #define _CHECKBOX_H_ diff --git a/rtgui/chmixer.cc b/rtgui/chmixer.cc index 82e885f08..4b243f13c 100644 --- a/rtgui/chmixer.cc +++ b/rtgui/chmixer.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "chmixer.h" diff --git a/rtgui/chmixer.h b/rtgui/chmixer.h index a0fff9b26..94f54ed3d 100644 --- a/rtgui/chmixer.h +++ b/rtgui/chmixer.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CHMIXER_H_ #define _CHMIXER_H_ diff --git a/rtgui/clipboard.cc b/rtgui/clipboard.cc index c8eb94d7b..4cd50f574 100644 --- a/rtgui/clipboard.cc +++ b/rtgui/clipboard.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "clipboard.h" diff --git a/rtgui/clipboard.h b/rtgui/clipboard.h index 74c9f6770..4c0ec452f 100644 --- a/rtgui/clipboard.h +++ b/rtgui/clipboard.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CLIPBOARD_ #define _CLIPBOARD_ diff --git a/rtgui/coarsepanel.cc b/rtgui/coarsepanel.cc index 92c312554..c64d53017 100644 --- a/rtgui/coarsepanel.cc +++ b/rtgui/coarsepanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "coarsepanel.h" diff --git a/rtgui/coarsepanel.h b/rtgui/coarsepanel.h index bd4668eea..2da56b904 100644 --- a/rtgui/coarsepanel.h +++ b/rtgui/coarsepanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __COARSEPANEL__ #define __COARSEPANEL__ diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index f78a1f32b..f8eb736d4 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index 3f95d9f74..da2e3c8b9 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _COLORAPPEARANCE_H_ #define _COLORAPPEARANCE_H_ diff --git a/rtgui/coloredbar.cc b/rtgui/coloredbar.cc index 7d623949e..ca9a381cf 100644 --- a/rtgui/coloredbar.cc +++ b/rtgui/coloredbar.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "coloredbar.h" diff --git a/rtgui/coloredbar.h b/rtgui/coloredbar.h index 010d0dcb6..089dfa8cd 100644 --- a/rtgui/coloredbar.h +++ b/rtgui/coloredbar.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _COLOREDBAR_ #define _COLOREDBAR_ diff --git a/rtgui/colorprovider.h b/rtgui/colorprovider.h index ab6fb2865..feea792b6 100644 --- a/rtgui/colorprovider.h +++ b/rtgui/colorprovider.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _COLORPROVIDER_ #define _COLORPROVIDER_ diff --git a/rtgui/config.h.in b/rtgui/config.h.in index 2d1f41dbc..95217b689 100644 --- a/rtgui/config.h.in +++ b/rtgui/config.h.in @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __CONFIG_H__ diff --git a/rtgui/coordinateadjuster.cc b/rtgui/coordinateadjuster.cc index 5065606d9..ebf36b7e7 100644 --- a/rtgui/coordinateadjuster.cc +++ b/rtgui/coordinateadjuster.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "coordinateadjuster.h" diff --git a/rtgui/coordinateadjuster.h b/rtgui/coordinateadjuster.h index 33ea92bb2..d705915ab 100644 --- a/rtgui/coordinateadjuster.h +++ b/rtgui/coordinateadjuster.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _COORDINATEADJUSTER_ #define _COORDINATEADJUSTER_ diff --git a/rtgui/crop.cc b/rtgui/crop.cc index a8b12819e..b1780538e 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "crop.h" diff --git a/rtgui/crop.h b/rtgui/crop.h index ed0661598..1bbad548d 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CROP_H_ #define _CROP_H_ diff --git a/rtgui/cropguilistener.h b/rtgui/cropguilistener.h index 7a791ef93..c20d6556a 100644 --- a/rtgui/cropguilistener.h +++ b/rtgui/cropguilistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __CROPGUILISTENER__ #define __CROPGUILISTENER__ diff --git a/rtgui/crophandler.cc b/rtgui/crophandler.cc index ab2f3626c..c6ecde027 100644 --- a/rtgui/crophandler.cc +++ b/rtgui/crophandler.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "crophandler.h" #undef THREAD_PRIORITY_NORMAL diff --git a/rtgui/crophandler.h b/rtgui/crophandler.h index e90b96c25..77355b868 100644 --- a/rtgui/crophandler.h +++ b/rtgui/crophandler.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __CROPHANDLER__ #define __CROPHANDLER__ diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 1364855b0..ef682cf1f 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 8c944cf0a..99b0fd897 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CROPWINDOW_ #define _CROPWINDOW_ diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index 3181d288e..76b4eabfb 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "cursormanager.h" diff --git a/rtgui/cursormanager.h b/rtgui/cursormanager.h index 111652726..aec5110d1 100644 --- a/rtgui/cursormanager.h +++ b/rtgui/cursormanager.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CURSORMANAGER_ #define _CURSORMANAGER_ diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc index 528378423..2b3c100e0 100644 --- a/rtgui/curveeditor.cc +++ b/rtgui/curveeditor.cc @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "curveeditor.h" #include "curveeditorgroup.h" diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h index e38d3f205..bdd6d6b48 100644 --- a/rtgui/curveeditor.h +++ b/rtgui/curveeditor.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CURVEEDITOR_ #define _CURVEEDITOR_ diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index 495e4324b..0e7205518 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h index ae0ebee07..6f7b98d9b 100644 --- a/rtgui/curveeditorgroup.h +++ b/rtgui/curveeditorgroup.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CURVEEDITORGROUP_ #define _CURVEEDITORGROUP_ diff --git a/rtgui/curvelistener.h b/rtgui/curvelistener.h index 3c85db712..05a9a4e99 100644 --- a/rtgui/curvelistener.h +++ b/rtgui/curvelistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _CURVELISTENER_ #define _CURVELISTENER_ diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index 8ffca7544..af7ffeace 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/darkframe.h b/rtgui/darkframe.h index c385a2153..c576712a8 100644 --- a/rtgui/darkframe.h +++ b/rtgui/darkframe.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DARKFRAME_H_ #define _DARKFRAME_H_ diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc index 03bf648dd..659d41960 100644 --- a/rtgui/defringe.cc +++ b/rtgui/defringe.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/defringe.h b/rtgui/defringe.h index c02fd8d6a..8a6eb0753 100644 --- a/rtgui/defringe.h +++ b/rtgui/defringe.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DEFRINGE_H_ #define _DEFRINGE_H_ diff --git a/rtgui/dehaze.cc b/rtgui/dehaze.cc index 8204210db..6f60d08d6 100644 --- a/rtgui/dehaze.cc +++ b/rtgui/dehaze.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/dehaze.h b/rtgui/dehaze.h index 66720a9fd..3120dfc91 100644 --- a/rtgui/dehaze.h +++ b/rtgui/dehaze.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index 9e2406309..21b42a6ce 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "clipboard.h" diff --git a/rtgui/diagonalcurveeditorsubgroup.h b/rtgui/diagonalcurveeditorsubgroup.h index 68047e0c2..077ef590e 100644 --- a/rtgui/diagonalcurveeditorsubgroup.h +++ b/rtgui/diagonalcurveeditorsubgroup.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DIAGONALCURVEEDITORSUBGROUP_ #define _DIAGONALCURVEEDITORSUBGROUP_ diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index fcc40abc9..32361d5c5 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "dirbrowser.h" diff --git a/rtgui/dirbrowser.h b/rtgui/dirbrowser.h index 15b6dd201..68422f8be 100644 --- a/rtgui/dirbrowser.h +++ b/rtgui/dirbrowser.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DIRBROWSER_ #define _DIRBROWSER_ diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index c3528d5dd..2a0bba596 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index 7bdaff853..a513eb262 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DIRPYRDENOISE_H_ #define _DIRPYRDENOISE_H_ diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index be6f9c97b..fc03c83ad 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * (C) 2010 Emil Martinec */ diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index 4eb110428..e236dc29b 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * (C) 2010 Emil Martinec */ diff --git a/rtgui/distortion.cc b/rtgui/distortion.cc index 3620dbc21..165ccee06 100644 --- a/rtgui/distortion.cc +++ b/rtgui/distortion.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/distortion.h b/rtgui/distortion.h index a279913cb..5e1cf6a6b 100644 --- a/rtgui/distortion.h +++ b/rtgui/distortion.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DISTORTION_H_ #define _DISTORTION_H_ diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index d83c70669..38029af71 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "dynamicprofilepanel.h" diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index e271edc5a..fd4a6e80e 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _DYNAMICPROFILEPANEL_H_ #define _DYNAMICPROFILEPANEL_H_ diff --git a/rtgui/editbuffer.cc b/rtgui/editbuffer.cc index 882f3c084..80114ed11 100644 --- a/rtgui/editbuffer.cc +++ b/rtgui/editbuffer.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "editbuffer.h" diff --git a/rtgui/editbuffer.h b/rtgui/editbuffer.h index ffb80c48d..77afb6449 100644 --- a/rtgui/editbuffer.h +++ b/rtgui/editbuffer.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/editcallbacks.cc b/rtgui/editcallbacks.cc index d51d672a5..1538ef7ba 100644 --- a/rtgui/editcallbacks.cc +++ b/rtgui/editcallbacks.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "editcallbacks.h" diff --git a/rtgui/editcallbacks.h b/rtgui/editcallbacks.h index c4003f9ca..c2efcf53e 100644 --- a/rtgui/editcallbacks.h +++ b/rtgui/editcallbacks.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/editcoordsys.h b/rtgui/editcoordsys.h index 829225e3f..eff339ab9 100644 --- a/rtgui/editcoordsys.h +++ b/rtgui/editcoordsys.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ /** @file diff --git a/rtgui/editedstate.h b/rtgui/editedstate.h index db416c531..2cee07eb9 100644 --- a/rtgui/editedstate.h +++ b/rtgui/editedstate.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EDITEDSTATE_ #define _EDITEDSTATE_ diff --git a/rtgui/editenums.h b/rtgui/editenums.h index 264576789..8fc28e922 100644 --- a/rtgui/editenums.h +++ b/rtgui/editenums.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EDITENUMS_ #define _EDITENUMS_ diff --git a/rtgui/editid.h b/rtgui/editid.h index 5c1cf2389..88d77f859 100644 --- a/rtgui/editid.h +++ b/rtgui/editid.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EDITID_H_ #define _EDITID_H_ diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index e0cc8fd92..6aab153a1 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "editorpanel.h" diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 7fe79b827..c4349f693 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EDITORPANEL_ #define _EDITORPANEL_ diff --git a/rtgui/editwidgets.cc b/rtgui/editwidgets.cc index 16cd67cd4..a7996ee42 100644 --- a/rtgui/editwidgets.cc +++ b/rtgui/editwidgets.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "editwidgets.h" diff --git a/rtgui/editwidgets.h b/rtgui/editwidgets.h index 1ae185f7a..9154db31f 100644 --- a/rtgui/editwidgets.h +++ b/rtgui/editwidgets.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index ec7201f84..50a1484cf 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #include "editwindow.h" diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h index 42c8ec20e..8a2ade6ba 100644 --- a/rtgui/editwindow.h +++ b/rtgui/editwindow.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EDITWINDOW_ #define _EDITWINDOW_ diff --git a/rtgui/epd.cc b/rtgui/epd.cc index ab6341866..307790ff7 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/epd.h b/rtgui/epd.h index 6b44d9147..d8781ef27 100644 --- a/rtgui/epd.h +++ b/rtgui/epd.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EPD_H_ #define _EPD_H_ diff --git a/rtgui/eventmapper.cc b/rtgui/eventmapper.cc index 81160c58e..b2e5067c7 100644 --- a/rtgui/eventmapper.cc +++ b/rtgui/eventmapper.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "eventmapper.h" diff --git a/rtgui/eventmapper.h b/rtgui/eventmapper.h index f977b0ff4..5cbb45388 100644 --- a/rtgui/eventmapper.h +++ b/rtgui/eventmapper.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/exiffiltersettings.cc b/rtgui/exiffiltersettings.cc index 0218677d8..567a22868 100644 --- a/rtgui/exiffiltersettings.cc +++ b/rtgui/exiffiltersettings.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "exiffiltersettings.h" diff --git a/rtgui/exiffiltersettings.h b/rtgui/exiffiltersettings.h index d692eb510..e820a2cac 100644 --- a/rtgui/exiffiltersettings.h +++ b/rtgui/exiffiltersettings.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EXIFFILTERSETTINGS_ #define _EXIFFILTERSETTINGS_ diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index f9324e90c..341d0f303 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "exifpanel.h" diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index c8597a287..f054f37c7 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EXIFPANEL_ #define _EXIFPANEL_ diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index 9a4c930d5..b4332f4a4 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "exportpanel.h" #include "multilangmgr.h" diff --git a/rtgui/exportpanel.h b/rtgui/exportpanel.h index dc9aa34a5..d13ca08ad 100644 --- a/rtgui/exportpanel.h +++ b/rtgui/exportpanel.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _EXPORTPANEL_ #define _EXPORTPANEL_ diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index 33424fac9..a6a9050c0 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #include "extprog.h" diff --git a/rtgui/extprog.h b/rtgui/extprog.h index 154a825e1..ea2749a61 100644 --- a/rtgui/extprog.h +++ b/rtgui/extprog.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #ifndef _EXTPROG_ diff --git a/rtgui/fattaltonemap.cc b/rtgui/fattaltonemap.cc index 032df6f40..a0baf3531 100644 --- a/rtgui/fattaltonemap.cc +++ b/rtgui/fattaltonemap.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/fattaltonemap.h b/rtgui/fattaltonemap.h index e6eafb605..9f788351c 100644 --- a/rtgui/fattaltonemap.h +++ b/rtgui/fattaltonemap.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc index 09deacfab..2d49ab087 100644 --- a/rtgui/favoritbrowser.cc +++ b/rtgui/favoritbrowser.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "multilangmgr.h" diff --git a/rtgui/favoritbrowser.h b/rtgui/favoritbrowser.h index ed522c1c4..292f17de6 100644 --- a/rtgui/favoritbrowser.h +++ b/rtgui/favoritbrowser.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FAVORITBROWSER_ #define _FAVORITBROWSER_ diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index f60e47518..f9afcef48 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index 03c7fc86c..6911a944f 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILEBROWSER_ #define _FILEBROWSER_ diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 87a48a7ea..44146b990 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "filebrowserentry.h" diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index bd3a266aa..646e8e67e 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILEBROWSERENTRY_ #define _FILEBROWSERENTRY_ diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 6eb8faab1..674501322 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "filecatalog.h" diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 0ff2fb1e8..09e2cc1ed 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILECATALOG_ #define _FILECATALOG_ diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index da33caddf..3e23cbc5d 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "filepanel.h" diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h index 0385c48d3..bdeb266f4 100644 --- a/rtgui/filepanel.h +++ b/rtgui/filepanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILEPANEL_ #define _FILEPANEL_ diff --git a/rtgui/fileselectionchangelistener.h b/rtgui/fileselectionchangelistener.h index 5f1b20fcc..1f3b8e612 100644 --- a/rtgui/fileselectionchangelistener.h +++ b/rtgui/fileselectionchangelistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILESELECTIONCHANGELISTENER_ #define _FILESELECTIONCHANGELISTENER_ diff --git a/rtgui/fileselectionlistener.h b/rtgui/fileselectionlistener.h index 0cac24d46..a7f7fb284 100644 --- a/rtgui/fileselectionlistener.h +++ b/rtgui/fileselectionlistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILESELECTIONLISTENER_ #define _FILESELECTIONLISTENER_ diff --git a/rtgui/filethumbnailbuttonset.cc b/rtgui/filethumbnailbuttonset.cc index 4c7d8743d..ef497a535 100644 --- a/rtgui/filethumbnailbuttonset.cc +++ b/rtgui/filethumbnailbuttonset.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "filethumbnailbuttonset.h" diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h index 13265b8c0..102b573c8 100644 --- a/rtgui/filethumbnailbuttonset.h +++ b/rtgui/filethumbnailbuttonset.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILETHUMBNAILBUTTONSET_ #define _FILETHUMBNAILBUTTONSET_ diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 6e93b2364..90cedf148 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index a1efdc455..85919bef9 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc index c140acfb0..301a7b188 100644 --- a/rtgui/filterpanel.cc +++ b/rtgui/filterpanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "filterpanel.h" #include "multilangmgr.h" diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h index 7f32a88d9..e6e41a416 100644 --- a/rtgui/filterpanel.h +++ b/rtgui/filterpanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FILTERPANEL_ #define _FILTERPANEL_ diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 376bb55c2..6dc3a1f5b 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "clipboard.h" diff --git a/rtgui/flatcurveeditorsubgroup.h b/rtgui/flatcurveeditorsubgroup.h index f931bf660..e9253cd08 100644 --- a/rtgui/flatcurveeditorsubgroup.h +++ b/rtgui/flatcurveeditorsubgroup.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FLATCURVEEDITORSUBGROUP_ #define _FLATCURVEEDITORSUBGROUP_ diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index f69b90170..03204c037 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h index 46e2f6ddd..b9997f65e 100644 --- a/rtgui/flatfield.h +++ b/rtgui/flatfield.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _FLATFIELD_H_ #define _FLATFIELD_H_ diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 19762fd92..189cf6178 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "../rtengine/rt_math.h" diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 73cd27171..b09e20abb 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __GUI_UTILS_ #define __GUI_UTILS_ diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index b82df7ebf..36803ddf2 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "histogrampanel.h" #include "multilangmgr.h" diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index f66d2e654..1515db97a 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _HISTOGRAMPANEL_ #define _HISTOGRAMPANEL_ diff --git a/rtgui/history.cc b/rtgui/history.cc index ec5e006bc..5305c258b 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "history.h" diff --git a/rtgui/history.h b/rtgui/history.h index 196b29b67..abf0d1ba5 100644 --- a/rtgui/history.h +++ b/rtgui/history.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _HISTORY_ #define _HISTORY_ diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc index f489696d2..b6b5b04f2 100644 --- a/rtgui/hsvequalizer.cc +++ b/rtgui/hsvequalizer.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2010 Ilya Popov */ diff --git a/rtgui/hsvequalizer.h b/rtgui/hsvequalizer.h index 8d34b486b..2ffa9fa0f 100644 --- a/rtgui/hsvequalizer.h +++ b/rtgui/hsvequalizer.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2010 Ilya Popov */ diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index ed880bd0e..9efa4360b 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "iccprofilecreator.h" diff --git a/rtgui/iccprofilecreator.h b/rtgui/iccprofilecreator.h index 5265d5ab2..b28ac29f2 100644 --- a/rtgui/iccprofilecreator.h +++ b/rtgui/iccprofilecreator.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index a6857eaa9..012aeca78 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index a03bd6fa7..9b4706ecd 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _ICMPANEL_ #define _ICMPANEL_ diff --git a/rtgui/ilabel.cc b/rtgui/ilabel.cc index 65040b93b..9dfd50b89 100644 --- a/rtgui/ilabel.cc +++ b/rtgui/ilabel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "ilabel.h" diff --git a/rtgui/ilabel.h b/rtgui/ilabel.h index 1f5340fa2..06da470b1 100644 --- a/rtgui/ilabel.h +++ b/rtgui/ilabel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _ILABEL_ #define _ILABEL_ diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 24b793fd9..b086f8baf 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "imagearea.h" #include diff --git a/rtgui/imagearea.h b/rtgui/imagearea.h index 0e8794840..375e3a536 100644 --- a/rtgui/imagearea.h +++ b/rtgui/imagearea.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __IMAGEAREA_H__ #define __IMAGEAREA_H__ diff --git a/rtgui/imageareapanel.cc b/rtgui/imageareapanel.cc index b0e680ade..f693c3181 100644 --- a/rtgui/imageareapanel.cc +++ b/rtgui/imageareapanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "imageareapanel.h" diff --git a/rtgui/imageareapanel.h b/rtgui/imageareapanel.h index 13fd6650b..4ec3ffcf3 100644 --- a/rtgui/imageareapanel.h +++ b/rtgui/imageareapanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IMAGEAREAPANEL_ #define _IMAGEAREAPANEL_ diff --git a/rtgui/imageareatoollistener.h b/rtgui/imageareatoollistener.h index 705888676..d387b595c 100644 --- a/rtgui/imageareatoollistener.h +++ b/rtgui/imageareatoollistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IMAGEAREATOOLLISTENER_ #define _IMAGEAREATOOLLISTENER_ diff --git a/rtgui/impulsedenoise.cc b/rtgui/impulsedenoise.cc index d4ecebfb5..cc2e10899 100644 --- a/rtgui/impulsedenoise.cc +++ b/rtgui/impulsedenoise.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/impulsedenoise.h b/rtgui/impulsedenoise.h index ae6aaa6a8..1ebdc430b 100644 --- a/rtgui/impulsedenoise.h +++ b/rtgui/impulsedenoise.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IMPULSEDENOISE_H_ #define _IMPULSEDENOISE_H_ diff --git a/rtgui/indclippedpanel.cc b/rtgui/indclippedpanel.cc index aff5035fe..df9f632ab 100644 --- a/rtgui/indclippedpanel.cc +++ b/rtgui/indclippedpanel.cc @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "indclippedpanel.h" #include "options.h" diff --git a/rtgui/indclippedpanel.h b/rtgui/indclippedpanel.h index c026d4611..54476af10 100644 --- a/rtgui/indclippedpanel.h +++ b/rtgui/indclippedpanel.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _INDCLIPPEDPANEL_ #define _INDCLIPPEDPANEL_ diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 85c5f463d..8bd9862a7 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "inspector.h" #include "guiutils.h" diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 86ad9114e..681b90aa3 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _INSPECTOR_ #define _INSPECTOR_ diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 7347927a0..25cd20560 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "iptcpanel.h" #include "clipboard.h" diff --git a/rtgui/iptcpanel.h b/rtgui/iptcpanel.h index 25683ccec..0317314a1 100644 --- a/rtgui/iptcpanel.h +++ b/rtgui/iptcpanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _IPTCPANEL_ #define _IPTCPANEL_ diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index eeb0cd18e..237f9ea9b 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index db75a686a..51ba0fdd6 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _LABCURVE_H_ #define _LABCURVE_H_ diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index 4576885e8..b6393f6f5 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ // adapted from the "color correction" module of Darktable. Original copyright follows @@ -33,7 +33,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with darktable. If not, see . + along with darktable. If not, see . */ #include "labgrid.h" diff --git a/rtgui/labgrid.h b/rtgui/labgrid.h index dbb0cc427..227b4cacc 100644 --- a/rtgui/labgrid.h +++ b/rtgui/labgrid.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ // adapted from the "color correction" module of Darktable. Original copyright follows @@ -33,7 +33,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with darktable. If not, see . + along with darktable. If not, see . */ #pragma once diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc index baf816c8b..76e0635eb 100644 --- a/rtgui/lensgeom.cc +++ b/rtgui/lensgeom.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "lensgeom.h" #include "guiutils.h" diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index 20bb4b7eb..06b8e5689 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _LENSGEOM_H_ #define _LENSGEOM_H_ diff --git a/rtgui/lensgeomlistener.h b/rtgui/lensgeomlistener.h index c6ba966b1..dbe58f1fa 100644 --- a/rtgui/lensgeomlistener.h +++ b/rtgui/lensgeomlistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _LENSGEOMLISTENER_H_ #define _LENSGEOMLISTENER_H_ diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 0dd3cb1b7..389f15461 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h index 76c15aa9a..7e740e26e 100644 --- a/rtgui/lensprofile.h +++ b/rtgui/lensprofile.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/localcontrast.cc b/rtgui/localcontrast.cc index cc4922a65..d91642b6c 100644 --- a/rtgui/localcontrast.cc +++ b/rtgui/localcontrast.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/localcontrast.h b/rtgui/localcontrast.h index 529c95c89..b23bac697 100644 --- a/rtgui/localcontrast.h +++ b/rtgui/localcontrast.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index 859057e2c..ef16df6ec 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "lockablecolorpicker.h" diff --git a/rtgui/lockablecolorpicker.h b/rtgui/lockablecolorpicker.h index cafea26be..f1a63d533 100644 --- a/rtgui/lockablecolorpicker.h +++ b/rtgui/lockablecolorpicker.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __COLORPICKER__ diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc index 3c97ff6bb..b5c10c532 100644 --- a/rtgui/lwbutton.cc +++ b/rtgui/lwbutton.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "lwbutton.h" #include "guiutils.h" diff --git a/rtgui/lwbutton.h b/rtgui/lwbutton.h index 12dbb6346..16e53a875 100644 --- a/rtgui/lwbutton.h +++ b/rtgui/lwbutton.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _LWBUTTON_ #define _LWBUTTON_ diff --git a/rtgui/lwbuttonset.cc b/rtgui/lwbuttonset.cc index d4d39bfe3..a03b3064b 100644 --- a/rtgui/lwbuttonset.cc +++ b/rtgui/lwbuttonset.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "lwbuttonset.h" diff --git a/rtgui/lwbuttonset.h b/rtgui/lwbuttonset.h index fa33620ae..07d17a135 100644 --- a/rtgui/lwbuttonset.h +++ b/rtgui/lwbuttonset.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index f71d7099d..09aab1cff 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifdef __GNUC__ diff --git a/rtgui/main.cc b/rtgui/main.cc index 5cfe93718..098963e0e 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifdef __GNUC__ diff --git a/rtgui/metadatapanel.cc b/rtgui/metadatapanel.cc index fed7622ea..f92152763 100644 --- a/rtgui/metadatapanel.cc +++ b/rtgui/metadatapanel.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "metadatapanel.h" diff --git a/rtgui/metadatapanel.h b/rtgui/metadatapanel.h index d34a04585..b39ffd2c1 100644 --- a/rtgui/metadatapanel.h +++ b/rtgui/metadatapanel.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc index 298f5d2dd..ecf744519 100644 --- a/rtgui/multilangmgr.cc +++ b/rtgui/multilangmgr.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "multilangmgr.h" diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h index 649865217..0c76b4c01 100644 --- a/rtgui/multilangmgr.h +++ b/rtgui/multilangmgr.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _MULTILANGMGR_ #define _MULTILANGMGR_ diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index 5684bec33..6c00e3f56 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "mycurve.h" #include "../rtengine/curves.h" diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index 81a747bcd..62d8d30f2 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _MYCURVE_ #define _MYCURVE_ diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index cb96c039f..d393c7200 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/mydiagonalcurve.h b/rtgui/mydiagonalcurve.h index 5b0f6f01e..33fac6090 100644 --- a/rtgui/mydiagonalcurve.h +++ b/rtgui/mydiagonalcurve.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _MYDIAGONALCURVE_ #define _MYDIAGONALCURVE_ diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index ebd0a9d0c..ec46908ce 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/myflatcurve.h b/rtgui/myflatcurve.h index c0223bfcf..fa4466b8d 100644 --- a/rtgui/myflatcurve.h +++ b/rtgui/myflatcurve.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _MYFLATCURVE_ #define _MYFLATCURVE_ diff --git a/rtgui/navigator.cc b/rtgui/navigator.cc index 732b9f323..de07ffcd7 100644 --- a/rtgui/navigator.cc +++ b/rtgui/navigator.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "navigator.h" diff --git a/rtgui/navigator.h b/rtgui/navigator.h index 1b898f895..eb4584f42 100644 --- a/rtgui/navigator.h +++ b/rtgui/navigator.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _NAVIGATOR_ #define _NAVIGATOR_ diff --git a/rtgui/options.cc b/rtgui/options.cc index b667f8679..20e20620a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "options.h" #include diff --git a/rtgui/options.h b/rtgui/options.h index 0c580b034..3bd83cd5b 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _OPTIONS_ #define _OPTIONS_ diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index cb3d4151c..e0e3ea47b 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 08a41fc7a..0b765db22 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 52adcfbf7..a7d2bd0d1 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "partialpastedlg.h" #include "multilangmgr.h" diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index b5b93b11a..eebb08705 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PARTIALPASTEDLG_ #define _PARTIALPASTEDLG_ diff --git a/rtgui/pathutils.cc b/rtgui/pathutils.cc index 21c452d4c..71ff8b0b2 100644 --- a/rtgui/pathutils.cc +++ b/rtgui/pathutils.cc @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "pathutils.h" diff --git a/rtgui/pathutils.h b/rtgui/pathutils.h index ce58103b9..ed7d21984 100644 --- a/rtgui/pathutils.h +++ b/rtgui/pathutils.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __PATH_UTILS_ #define __PATH_UTILS_ diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index 752b2289b..b86da6a52 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "perspective.h" diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 77fedc84a..9b36ed24d 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PERSPECTIVE_PANEL_H_ #define _PERSPECTIVE_PANEL_H_ diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc index 6fb04ac53..f1450cea2 100644 --- a/rtgui/placesbrowser.cc +++ b/rtgui/placesbrowser.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "placesbrowser.h" diff --git a/rtgui/placesbrowser.h b/rtgui/placesbrowser.h index b3bed867c..6325bdb45 100644 --- a/rtgui/placesbrowser.h +++ b/rtgui/placesbrowser.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PLACESBROWSER_ #define _PLACESBROWSER_ diff --git a/rtgui/pointermotionlistener.h b/rtgui/pointermotionlistener.h index 88a4b2279..0a2931262 100644 --- a/rtgui/pointermotionlistener.h +++ b/rtgui/pointermotionlistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _POINTERMOTIONLISTENER_ #define _POINTERMOTIONLISTENER_ diff --git a/rtgui/popupbutton.cc b/rtgui/popupbutton.cc index 2aa43ddcb..7c15255c6 100644 --- a/rtgui/popupbutton.cc +++ b/rtgui/popupbutton.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h index be08cd1ba..fb0b66e0d 100644 --- a/rtgui/popupbutton.h +++ b/rtgui/popupbutton.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index c5a5a03e3..8c4c9dda1 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 92d6a6214..44ad0886a 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ diff --git a/rtgui/popuptogglebutton.cc b/rtgui/popuptogglebutton.cc index 9676a2bea..47c3e4088 100644 --- a/rtgui/popuptogglebutton.cc +++ b/rtgui/popuptogglebutton.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ diff --git a/rtgui/popuptogglebutton.h b/rtgui/popuptogglebutton.h index 58a7ff82a..b2949a0b8 100644 --- a/rtgui/popuptogglebutton.h +++ b/rtgui/popuptogglebutton.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ diff --git a/rtgui/pparamschangelistener.h b/rtgui/pparamschangelistener.h index c8338745e..2c73ea3f6 100644 --- a/rtgui/pparamschangelistener.h +++ b/rtgui/pparamschangelistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PPARAMSCHANGELISTENER_ #define _PPARAMSCHANGELISTENER_ diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 16a58f334..b4447fd44 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "preferences.h" diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 4f92e9e22..6ca302fe8 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __PREFERENCES_H__ #define __PREFERENCES_H__ diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc index 07e378832..4a663ad07 100644 --- a/rtgui/preprocess.cc +++ b/rtgui/preprocess.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h index ced119d7d..015fa3650 100644 --- a/rtgui/preprocess.h +++ b/rtgui/preprocess.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PREPROCESS_H_ #define _PREPROCESS_H_ diff --git a/rtgui/previewhandler.cc b/rtgui/previewhandler.cc index a1640b39c..1dad0676e 100644 --- a/rtgui/previewhandler.cc +++ b/rtgui/previewhandler.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "previewhandler.h" #include diff --git a/rtgui/previewhandler.h b/rtgui/previewhandler.h index 7a93ed480..7fe7b96f4 100644 --- a/rtgui/previewhandler.h +++ b/rtgui/previewhandler.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PREVIEWHANDLER_ #define _PREVIEWHANDLER_ diff --git a/rtgui/previewloader.cc b/rtgui/previewloader.cc index 34b42dcb7..67de50113 100644 --- a/rtgui/previewloader.cc +++ b/rtgui/previewloader.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/previewloader.h b/rtgui/previewloader.h index 311d9d5ce..52dbee43c 100644 --- a/rtgui/previewloader.h +++ b/rtgui/previewloader.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PREVIEWLOADER_ #define _PREVIEWLOADER_ diff --git a/rtgui/previewmodepanel.cc b/rtgui/previewmodepanel.cc index 086f6ab17..37b3f6468 100644 --- a/rtgui/previewmodepanel.cc +++ b/rtgui/previewmodepanel.cc @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "previewmodepanel.h" #include "options.h" diff --git a/rtgui/previewmodepanel.h b/rtgui/previewmodepanel.h index 4924b77af..b43e8484c 100644 --- a/rtgui/previewmodepanel.h +++ b/rtgui/previewmodepanel.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PREVIEWMODEPANEL_ #define _PREVIEWMODEPANEL_ diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc index 7688c0470..54d785313 100644 --- a/rtgui/previewwindow.cc +++ b/rtgui/previewwindow.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "previewwindow.h" #include "guiutils.h" diff --git a/rtgui/previewwindow.h b/rtgui/previewwindow.h index c89c89d4e..64aa84afd 100644 --- a/rtgui/previewwindow.h +++ b/rtgui/previewwindow.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PREVIEWWINDOW_ #define _PREVIEWWINDOW_ diff --git a/rtgui/procparamchangers.h b/rtgui/procparamchangers.h index aeebae4fb..8dd3769c6 100644 --- a/rtgui/procparamchangers.h +++ b/rtgui/procparamchangers.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #define UNKNOWN -1 #define FILEBROWSER 1 diff --git a/rtgui/profilechangelistener.h b/rtgui/profilechangelistener.h index e333933ea..fa7e1b877 100644 --- a/rtgui/profilechangelistener.h +++ b/rtgui/profilechangelistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PROFILECHANGELISTENER_ #define _PROFILECHANGELISTENER_ diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index c969d13c0..b4b85dfd0 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "profilepanel.h" diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index bc42f96c3..c5717d523 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PROFILEPANEL_ #define _PROFILEPANEL_ diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index ae84bd951..bb294189f 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "../rtengine/profilestore.h" #include "profilestorecombobox.h" diff --git a/rtgui/profilestorecombobox.h b/rtgui/profilestorecombobox.h index 3796e0471..5d04813d6 100644 --- a/rtgui/profilestorecombobox.h +++ b/rtgui/profilestorecombobox.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PROFILESTORECOMBOBOX_ #define _PROFILESTORECOMBOBOX_ diff --git a/rtgui/progressconnector.h b/rtgui/progressconnector.h index 394ad3909..012039ba6 100644 --- a/rtgui/progressconnector.h +++ b/rtgui/progressconnector.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PROGRESSCONNECTOR_ #define _PROGRESSCONNECTOR_ diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc index b12da977d..d065dbc07 100644 --- a/rtgui/prsharpening.cc +++ b/rtgui/prsharpening.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "eventmapper.h" diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h index d8a27c188..9d37fa8ba 100644 --- a/rtgui/prsharpening.h +++ b/rtgui/prsharpening.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _PRSHARPENING_H_ #define _PRSHARPENING_H_ diff --git a/rtgui/rawcacorrection.cc b/rtgui/rawcacorrection.cc index 003d8b629..9e5c592ef 100644 --- a/rtgui/rawcacorrection.cc +++ b/rtgui/rawcacorrection.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rawcacorrection.h" diff --git a/rtgui/rawcacorrection.h b/rtgui/rawcacorrection.h index ab80bd3ea..d3874d9f9 100644 --- a/rtgui/rawcacorrection.h +++ b/rtgui/rawcacorrection.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RAWCACORRECTION_H_ #define _RAWCACORRECTION_H_ diff --git a/rtgui/rawexposure.cc b/rtgui/rawexposure.cc index f8885eb76..7548bf4be 100644 --- a/rtgui/rawexposure.cc +++ b/rtgui/rawexposure.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/rawexposure.h b/rtgui/rawexposure.h index 95a15ade2..1dafd4d64 100644 --- a/rtgui/rawexposure.h +++ b/rtgui/rawexposure.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RAWEXPOSURE_H_ #define _RAWEXPOSURE_H_ diff --git a/rtgui/recentbrowser.cc b/rtgui/recentbrowser.cc index ec97f6ded..fca97cafa 100644 --- a/rtgui/recentbrowser.cc +++ b/rtgui/recentbrowser.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "recentbrowser.h" #include "multilangmgr.h" diff --git a/rtgui/recentbrowser.h b/rtgui/recentbrowser.h index 2d1e210f4..1ba2c17f4 100644 --- a/rtgui/recentbrowser.h +++ b/rtgui/recentbrowser.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RECENTBROWSER_ #define _RECENTBROWSER_ diff --git a/rtgui/renamedlg.cc b/rtgui/renamedlg.cc index 14931817f..8f55b3653 100644 --- a/rtgui/renamedlg.cc +++ b/rtgui/renamedlg.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "renamedlg.h" #include "multilangmgr.h" diff --git a/rtgui/renamedlg.h b/rtgui/renamedlg.h index ab51a43c6..a3e16ad0a 100644 --- a/rtgui/renamedlg.h +++ b/rtgui/renamedlg.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RENAMEDLG_ #define _RENAMEDLG_ diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 0525d64af..456b924ef 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "resize.h" diff --git a/rtgui/resize.h b/rtgui/resize.h index 3bcfe3f84..1d38ae674 100644 --- a/rtgui/resize.h +++ b/rtgui/resize.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RESIZE_H_ #define _RESIZE_H_ diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index 81d997add..2350783e0 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rgbcurves.h" diff --git a/rtgui/rgbcurves.h b/rtgui/rgbcurves.h index a7846f9ab..e62fdd7c7 100644 --- a/rtgui/rgbcurves.h +++ b/rtgui/rgbcurves.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RGBCURVES_H_ #define _RGBCURVES_H_ diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc index 822443cf8..7436186c3 100644 --- a/rtgui/rotate.cc +++ b/rtgui/rotate.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/rotate.h b/rtgui/rotate.h index c3d18fecb..bd0613609 100644 --- a/rtgui/rotate.h +++ b/rtgui/rotate.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _ROTATE_H_ #define _ROTATE_H_ diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 5ae3e4ddb..e35a6d164 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtimage.h" diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index 15978f65c..b68becd82 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index ae3214520..15211a7ee 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "rtscalable.h" diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index b8db9953c..28ebf7be8 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/rtsurface.cc b/rtgui/rtsurface.cc index 230c3ff4f..62dfe36d5 100644 --- a/rtgui/rtsurface.cc +++ b/rtgui/rtsurface.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index b442b7493..1944cc2dc 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 131016cb0..3983f93b1 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index 48662858f..93e1c31b9 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _RTWINDOW_ #define _RTWINDOW_ diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc index f2a7206b9..1b61d7d3d 100644 --- a/rtgui/saveasdlg.cc +++ b/rtgui/saveasdlg.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/saveasdlg.h b/rtgui/saveasdlg.h index e02be340f..dd120337d 100644 --- a/rtgui/saveasdlg.h +++ b/rtgui/saveasdlg.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SAVEASDLG_ #define _SAVEASDLG_ diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc index 483565446..00f6e7b2b 100644 --- a/rtgui/saveformatpanel.cc +++ b/rtgui/saveformatpanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index 7d7210282..ab5ffef3e 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __SAVEFORMATPANEL_H__ #define __SAVEFORMATPANEL_H__ diff --git a/rtgui/sensorbayer.cc b/rtgui/sensorbayer.cc index 44afdd2e8..39ed5cb91 100644 --- a/rtgui/sensorbayer.cc +++ b/rtgui/sensorbayer.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "sensorbayer.h" #include "guiutils.h" diff --git a/rtgui/sensorbayer.h b/rtgui/sensorbayer.h index f3c620d88..2d68411ce 100644 --- a/rtgui/sensorbayer.h +++ b/rtgui/sensorbayer.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SENSORBAYER_H_ #define _SENSORBAYER_H_ diff --git a/rtgui/sensorxtrans.cc b/rtgui/sensorxtrans.cc index c0a704ebf..f13e6607f 100644 --- a/rtgui/sensorxtrans.cc +++ b/rtgui/sensorxtrans.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "sensorxtrans.h" #include "guiutils.h" diff --git a/rtgui/sensorxtrans.h b/rtgui/sensorxtrans.h index d723d29f7..fbf71b401 100644 --- a/rtgui/sensorxtrans.h +++ b/rtgui/sensorxtrans.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SENSORXTRANS_H_ #define _SENSORXTRANS_H_ diff --git a/rtgui/shadowshighlights.cc b/rtgui/shadowshighlights.cc index f58790051..3e3c277c7 100644 --- a/rtgui/shadowshighlights.cc +++ b/rtgui/shadowshighlights.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "shadowshighlights.h" diff --git a/rtgui/shadowshighlights.h b/rtgui/shadowshighlights.h index 5e56e0766..d675f40d6 100644 --- a/rtgui/shadowshighlights.h +++ b/rtgui/shadowshighlights.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SHADOWSHIGHLIGHTS_H_ #define _SHADOWSHIGHLIGHTS_H_ diff --git a/rtgui/sharpenedge.cc b/rtgui/sharpenedge.cc index 9d6466543..f4415bb15 100644 --- a/rtgui/sharpenedge.cc +++ b/rtgui/sharpenedge.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/sharpenedge.h b/rtgui/sharpenedge.h index a08c63b8a..b136d8e5e 100644 --- a/rtgui/sharpenedge.h +++ b/rtgui/sharpenedge.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * * Manuel Llorens' algorithm of edge sharpening diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index e698872dd..e16511279 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include "eventmapper.h" diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index b9f093aae..ac846a2b6 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SHARPENING_H_ #define _SHARPENING_H_ diff --git a/rtgui/sharpenmicro.cc b/rtgui/sharpenmicro.cc index 1d765652b..78228d27c 100644 --- a/rtgui/sharpenmicro.cc +++ b/rtgui/sharpenmicro.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/sharpenmicro.h b/rtgui/sharpenmicro.h index 8cb95b806..7c292413b 100644 --- a/rtgui/sharpenmicro.h +++ b/rtgui/sharpenmicro.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * * Manuel Llorens' algorithm of micro-contrast sharpening diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index d55ce30fd..6137c3ec8 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "shcselector.h" diff --git a/rtgui/shcselector.h b/rtgui/shcselector.h index ac6c8afed..d3ef2adb8 100644 --- a/rtgui/shcselector.h +++ b/rtgui/shcselector.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _SHCSELECTOR_ #define _SHCSELECTOR_ diff --git a/rtgui/softlight.cc b/rtgui/softlight.cc index 90c3890cd..84461f169 100644 --- a/rtgui/softlight.cc +++ b/rtgui/softlight.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include #include diff --git a/rtgui/softlight.h b/rtgui/softlight.h index f6ed8370d..a584d3a73 100644 --- a/rtgui/softlight.h +++ b/rtgui/softlight.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/soundman.cc b/rtgui/soundman.cc index 62c7d59b6..a4cf5337b 100644 --- a/rtgui/soundman.cc +++ b/rtgui/soundman.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . * */ diff --git a/rtgui/soundman.h b/rtgui/soundman.h index dd8e515fc..6d065c87a 100644 --- a/rtgui/soundman.h +++ b/rtgui/soundman.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License -* along with RawTherapee. If not, see . +* along with RawTherapee. If not, see . * */ diff --git a/rtgui/splash.cc b/rtgui/splash.cc index 36b796c4d..7ae5bf4d7 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "splash.h" diff --git a/rtgui/splash.h b/rtgui/splash.h index 00e9f556e..29dbb62cf 100644 --- a/rtgui/splash.h +++ b/rtgui/splash.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __SPLASH__ #define __SPLASH__ diff --git a/rtgui/threadutils.cc b/rtgui/threadutils.cc index 7ba296081..025abf300 100644 --- a/rtgui/threadutils.cc +++ b/rtgui/threadutils.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "threadutils.h" diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h index 1215d53a1..f8107d74c 100644 --- a/rtgui/threadutils.h +++ b/rtgui/threadutils.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THREADUTILS_ #define _THREADUTILS_ diff --git a/rtgui/thresholdadjuster.cc b/rtgui/thresholdadjuster.cc index 210f63333..c6ba96111 100644 --- a/rtgui/thresholdadjuster.cc +++ b/rtgui/thresholdadjuster.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "thresholdadjuster.h" #include diff --git a/rtgui/thresholdadjuster.h b/rtgui/thresholdadjuster.h index 54026a183..ea3822875 100644 --- a/rtgui/thresholdadjuster.h +++ b/rtgui/thresholdadjuster.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THRESHOLDADJUSTER_H_ #define _THRESHOLDADJUSTER_H_ diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index d9b0921ce..b44425be4 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/thresholdselector.h b/rtgui/thresholdselector.h index fff707959..6b9dda3d0 100644 --- a/rtgui/thresholdselector.h +++ b/rtgui/thresholdselector.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THRESHOLDSELECTOR_ #define _THRESHOLDSELECTOR_ diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 13709d8f7..adf451f05 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index aefd72044..890c37c87 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THUMBNAILBROWSERBASE_ #define _THUMBNAILBROWSERBASE_ diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index 4dacb1adf..9d74fbd79 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "thumbbrowserentrybase.h" diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index 6cbcb37d0..5f018eefd 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #pragma once diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc index c0df751a5..182eba704 100644 --- a/rtgui/thumbimageupdater.cc +++ b/rtgui/thumbimageupdater.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/thumbimageupdater.h b/rtgui/thumbimageupdater.h index a3be44d7c..0e46b11d7 100644 --- a/rtgui/thumbimageupdater.h +++ b/rtgui/thumbimageupdater.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THUMBIMAGEUPDATER_ #define _THUMBIMAGEUPDATER_ diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 79291c423..7ec1fef4e 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "multilangmgr.h" #include "thumbnail.h" diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index e3196778c..ec5dbd249 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THUMBNAIL_ #define _THUMBNAIL_ diff --git a/rtgui/thumbnailbrowser.h b/rtgui/thumbnailbrowser.h index 0c2d6ebab..9d40d1f7d 100644 --- a/rtgui/thumbnailbrowser.h +++ b/rtgui/thumbnailbrowser.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THUMBNAILBROWSER_ #define _THUMBNAILBROWSER_ diff --git a/rtgui/thumbnaillistener.h b/rtgui/thumbnaillistener.h index 99a9a9286..97503c420 100644 --- a/rtgui/thumbnaillistener.h +++ b/rtgui/thumbnaillistener.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _THUMBNAILLISTENER_ #define _THUMBNAILLISTENER_ diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index e0e475b4e..fa1c80ed8 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index 512dd4d5f..fb08c02c2 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _TONECURVE_H_ #define _TONECURVE_H_ diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc index 9bed78768..b8e0d64dc 100644 --- a/rtgui/toolbar.cc +++ b/rtgui/toolbar.cc @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "toolbar.h" #include "multilangmgr.h" diff --git a/rtgui/toolbar.h b/rtgui/toolbar.h index 2d859eac7..52f4dcbd4 100644 --- a/rtgui/toolbar.h +++ b/rtgui/toolbar.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __TOOLBAR_H__ #define __TOOLBAR_H__ diff --git a/rtgui/toolenum.h b/rtgui/toolenum.h index 85a7b954a..e90a0f685 100644 --- a/rtgui/toolenum.h +++ b/rtgui/toolenum.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _TOOLENUM_ #define _TOOLENUM_ diff --git a/rtgui/toolpanel.cc b/rtgui/toolpanel.cc index 1fe9808cd..27f68767e 100644 --- a/rtgui/toolpanel.cc +++ b/rtgui/toolpanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "toolpanel.h" #include "toolpanelcoord.h" diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index 1d3630c6d..8d4a55eab 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __TOOLPANEL__ #define __TOOLPANEL__ diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index d9bc6fc2a..e920e0e97 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "multilangmgr.h" #include "toolpanelcoord.h" diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index a1b26b29f..fea55990e 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef __TOOLPANELCCORD__ #define __TOOLPANELCCORD__ diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc index 82944bb81..461c4a79f 100644 --- a/rtgui/vibrance.cc +++ b/rtgui/vibrance.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "vibrance.h" diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h index 81d811f14..606bfa80a 100644 --- a/rtgui/vibrance.h +++ b/rtgui/vibrance.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _VIBRANCE_ #define _VIBRANCE_ diff --git a/rtgui/vignetting.cc b/rtgui/vignetting.cc index 87a835625..04a350b99 100644 --- a/rtgui/vignetting.cc +++ b/rtgui/vignetting.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "vignetting.h" diff --git a/rtgui/vignetting.h b/rtgui/vignetting.h index edd818431..094869f67 100644 --- a/rtgui/vignetting.h +++ b/rtgui/vignetting.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _VIGNETTING_H_ #define _VIGNETTING_H_ diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index bc59de087..94f96e0cc 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2014 Jacques Desmis */ diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 4df743fa7..feec85fc9 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -12,7 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . * * 2014 Jacques Desmis */ diff --git a/rtgui/wbprovider.h b/rtgui/wbprovider.h index df1329c84..31ba8331a 100644 --- a/rtgui/wbprovider.h +++ b/rtgui/wbprovider.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _WBPROVIDER_ #define _WBPROVIDER_ diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index aa3443829..109fb7502 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "whitebalance.h" diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 52c4b7f8c..fd7efe7ce 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _WB_H_ #define _WB_H_ diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc index 115fa3868..52c46be65 100644 --- a/rtgui/xtransprocess.cc +++ b/rtgui/xtransprocess.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "xtransprocess.h" diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h index e5389b566..dae93822f 100644 --- a/rtgui/xtransprocess.h +++ b/rtgui/xtransprocess.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _XTRANSPROCESS_H_ #define _XTRANSPROCESS_H_ diff --git a/rtgui/xtransrawexposure.cc b/rtgui/xtransrawexposure.cc index c4f7d7059..28059e69c 100644 --- a/rtgui/xtransrawexposure.cc +++ b/rtgui/xtransrawexposure.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include diff --git a/rtgui/xtransrawexposure.h b/rtgui/xtransrawexposure.h index 54b3de767..08cdcc8bf 100644 --- a/rtgui/xtransrawexposure.h +++ b/rtgui/xtransrawexposure.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _XTRANSRAWEXPOSURE_H_ #define _XTRANSRAWEXPOSURE_H_ diff --git a/rtgui/zoompanel.cc b/rtgui/zoompanel.cc index ea57b7fdc..c10ec97b9 100644 --- a/rtgui/zoompanel.cc +++ b/rtgui/zoompanel.cc @@ -14,7 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #include "zoompanel.h" #include "multilangmgr.h" diff --git a/rtgui/zoompanel.h b/rtgui/zoompanel.h index 69fe418d4..e1cb651e3 100644 --- a/rtgui/zoompanel.h +++ b/rtgui/zoompanel.h @@ -14,7 +14,7 @@ * GNU General Public License for more details. *l * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . + * along with RawTherapee. If not, see . */ #ifndef _ZOOMPANEL_ #define _ZOOMPANEL_ diff --git a/tools/gimp-plugin/file-formats.h b/tools/gimp-plugin/file-formats.h index fc6697ec7..ac8c2fa54 100644 --- a/tools/gimp-plugin/file-formats.h +++ b/tools/gimp-plugin/file-formats.h @@ -16,7 +16,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * along with this program. If not, see . */ /* These are the raw formats that file-rawtherapee will register */ diff --git a/tools/gimp-plugin/file-rawtherapee.c b/tools/gimp-plugin/file-rawtherapee.c index d78c30a10..2848e74fa 100644 --- a/tools/gimp-plugin/file-rawtherapee.c +++ b/tools/gimp-plugin/file-rawtherapee.c @@ -17,7 +17,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * along with this program. If not, see . */ #include "config.h" From 28dd16c4431c0b1ba8798809822ab7e68d1cc095 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Tue, 10 Sep 2019 12:41:29 +0200 Subject: [PATCH 173/222] Update README.md --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6d2c04875..ae9efd9c8 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,41 @@ -![RawTherapee logo](http://rawtherapee.com/images/logos/rawtherapee_logo_discuss.png) +![RawTherapee logo](https://www.rawtherapee.com/images/logos/rawtherapee_logo_discuss.png) -RawTherapee is a powerful, cross-platform raw photo processing program, released as [libre software](https://en.wikipedia.org/wiki/Free_software) under the [GNU General Public License Version 3](https://opensource.org/licenses/gpl-3.0.html). It is written mostly in C++ using a [GTK+](http://www.gtk.org/) front-end. It uses a patched version of [dcraw](http://www.cybercom.net/~dcoffin/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 a powerful, cross-platform raw photo processing program, released as [libre software](https://en.wikipedia.org/wiki/Free_software) under the [GNU General Public License Version 3](https://opensource.org/licenses/gpl-3.0.html). It is written mostly in C++ using a [GTK+](https://www.gtk.org) front-end. It uses a patched version of [dcraw](https://www.dechifro.org/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. -## Target audience +## Target Audience -RawTherapee is designed for developing raw files from a broad range of digital cameras, as well as [HDR DNG](https://helpx.adobe.com/photoshop/digital-negative.html) files and non-raw image formats ([JPEG](https://en.wikipedia.org/wiki/JPEG), [TIFF](https://en.wikipedia.org/wiki/Tagged_Image_File_Format) and [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics)). 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](http://rawpedia.rawtherapee.com/)) as well as look up basic concepts which lie outside the scope of RawPedia, such as [color balance](https://en.wikipedia.org/wiki/Color_balance), elsewhere. +RawTherapee is designed for developing raw files from a broad range of digital cameras, as well as [HDR DNG](https://helpx.adobe.com/photoshop/digital-negative.html) files and non-raw image formats ([JPEG](https://en.wikipedia.org/wiki/JPEG), [TIFF](https://en.wikipedia.org/wiki/Tagged_Image_File_Format) and [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics)). 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](https://rawpedia.rawtherapee.com/)) as well as look up basic concepts which lie outside the scope of RawPedia, such as [color balance](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/Digital_asset_management), printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the [open-source community](https://en.wikipedia.org/wiki/Open-source_movement) is sufficiently developed by now to offer all those peripheral features in other specialized software. +Professionals may use RawTherapee as well while enjoying complete freedom, but will probably lack some peripheral features such as [Digital Asset Management](https://en.wikipedia.org/wiki/Digital_asset_management), printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the [open-source community](https://en.wikipedia.org/wiki/Open-source_movement) is sufficiently developed by now to offer all those peripheral features in other specialized software. ## Links Website: -http://rawtherapee.com/ +https://www.rawtherapee.com/ Forum: https://discuss.pixls.us/c/software/rawtherapee Features: -http://rawpedia.rawtherapee.com/Features +https://rawpedia.rawtherapee.com/Features -Official documentation: -http://rawpedia.rawtherapee.com/ +Documentation: +https://rawpedia.rawtherapee.com/ Download RawTherapee: -http://rawtherapee.com/downloads +https://www.rawtherapee.com/downloads Download source code tarballs: -http://rawtherapee.com/shared/source/ +https://www.rawtherapee.com/shared/source/ -## Compilation, branches and Git +## Compilation, Branches and Git Refer to RawPedia for a detailed explanation of how to get the necessary dependencies and how to compile RawTherapee. Linux: -http://rawpedia.rawtherapee.com/Linux +https://rawpedia.rawtherapee.com/Linux Windows: -http://rawpedia.rawtherapee.com/Windows +https://rawpedia.rawtherapee.com/Windows macOS: -http://rawpedia.rawtherapee.com/macOS +https://rawpedia.rawtherapee.com/macOS From f335efe6a7c07c49b146f5885965dad2e7252af1 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Tue, 10 Sep 2019 12:45:01 +0200 Subject: [PATCH 174/222] Minor splash screen cleanup --- rtdata/images/svg/splash.svg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtdata/images/svg/splash.svg b/rtdata/images/svg/splash.svg index a3bf9f8d2..102916d0f 100644 --- a/rtdata/images/svg/splash.svg +++ b/rtdata/images/svg/splash.svg @@ -479,9 +479,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.93979686" - inkscape:cx="-57.792073" - inkscape:cy="126.17957" + inkscape:zoom="0.90075514" + inkscape:cx="-60.984253" + inkscape:cy="136.82017" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -574,7 +574,7 @@ RawTherapee splash screen - + Maciej Dworak From b643c90ba77e78168923e6c7dc56193fbb4b498a Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Tue, 10 Sep 2019 19:23:02 +0200 Subject: [PATCH 175/222] Changes for merging release 5.7 back into dev --- RELEASE_NOTES.txt | 21 ++++++----- rtdata/images/svg/splash.svg | 70 ++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 0974af86c..33a984c1c 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,10 +1,17 @@ -RAWTHERAPEE 5.7 RELEASE NOTES +RAWTHERAPEE 5.7-dev RELEASE NOTES -This is RawTherapee 5.7, released on 2019-09-10. +This is a development version of RawTherapee. We update the code almost daily. Every few months, once enough changes have accumulated and the code is stabilized, we make a new official release. Every code change between these releases is known as a "development" version, and this is one of them. Start by reading the "Getting Started" article on RawPedia: https://rawpedia.rawtherapee.com/ +While we only commit tested and relatively stable code and so the development versions should be fairly stable, you should be aware that: +- Development versions only had limited testing, so there may be bugs unknown to us. +- You should report these bugs so that they get fixed for the next stable release. See + www.rawpedia.rawtherapee.com/How_to_write_useful_bug_reports +- The way new tools work in the development versions is likely to change as we tweak and tune them, so your processing profiles may produce different results when used in a future stable version. +- Bugs present in the stable versions get fixed in the development versions, and make it into the next stable version when we make a new official release. That means that in some ways the development versions can be "more stable" than the latest stable release. At the same time, new features may introduce new bugs. This is a trade-off you should be aware of. + NEWS RELEVANT TO PHOTOGRAPHERS @@ -19,17 +26,15 @@ In order to use RawTherapee efficiently you should know that: - All curves support the Shift and Ctrl keys while dragging a point. Shift+drag makes the point snap to a meaningful axis (top, bottom, diagonal, other), while Ctrl+drag makes your mouse movement super-fine for precise point positioning. - There are many keyboard shortcuts which make working with RawTherapee much faster and give you greater control. Make sure you familiarize yourself with them on RawPedia's "Keyboard Shortcuts" page! -New features since 5.6: -- Film Negative tool, for easily developing raw photographs of film negatives. -- Support for reading "rating" tags from Exif and XMP, shown in the File Browser/Filmstrip using RawTherapee's star rating system. -- Hundreds of bug fixes, speed optimizations and raw format support improvements. +New features since 5.7: +- TODO NEWS RELEVANT TO PACKAGE MAINTAINERS -New since 5.6: -- Requires CMake >=3.5. +New since 5.7: +- TODO In general: - To get the source code, either clone from git or use the tarball from https://rawtherapee.com/shared/source/ . Do not use the auto-generated GitHub release tarballs. diff --git a/rtdata/images/svg/splash.svg b/rtdata/images/svg/splash.svg index 102916d0f..0989bfdb6 100644 --- a/rtdata/images/svg/splash.svg +++ b/rtdata/images/svg/splash.svg @@ -1061,5 +1061,75 @@ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:49.34799576px;line-height:1.25;font-family:'Eras Bold ITC';-inkscape-font-specification:'Eras Bold ITC Bold';letter-spacing:-7.09514618px" id="path195" /> + + + + + + + + + + + + + + + + From 2e34aa8a1de8c0f8c0786b050fad6e1bdea63e22 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 10 Sep 2019 23:23:37 +0200 Subject: [PATCH 176/222] Soft Light: speedup and reduce memory usage --- rtengine/ipsoftlight.cc | 115 +++++++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 25 deletions(-) diff --git a/rtengine/ipsoftlight.cc b/rtengine/ipsoftlight.cc index c7a4d1af7..1d94a29c2 100644 --- a/rtengine/ipsoftlight.cc +++ b/rtengine/ipsoftlight.cc @@ -3,6 +3,7 @@ * This file is part of RawTherapee. * * Copyright 2018 Alberto Griggio + * Optimized 2019 Ingo Weyrich * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,14 +19,10 @@ * along with RawTherapee. If not, see . */ -#ifdef _OPENMP -#include -#endif - #include "improcfun.h" - #include "procparams.h" - +#define BENCHMARK +#include "StopWatch.h" namespace rtengine { namespace { @@ -33,18 +30,29 @@ namespace { inline float sl(float blend, float x) { if (!OOG(x)) { - const float orig = 1.f - blend; float v = Color::gamma_srgb(x) / MAXVALF; - // Pegtop's formula from + // using Pegtop's formula from // https://en.wikipedia.org/wiki/Blend_modes#Soft_Light - float v2 = v * v; - float v22 = v2 * 2.f; - v = v2 + v22 - v22 * v; - x = blend * Color::igamma_srgb(v * MAXVALF) + orig * x; + // const float orig = 1.f - blend; + // float v2 = v * v; + // float v22 = v2 * 2.f; + // v = v2 + v22 - v22 * v; + // return blend * Color::igamma_srgb(v * MAXVALF) + orig * x; + + // using optimized formula (heckflosse67@gmx.de) + return intp(blend, Color::igamma_srgb(v * v * (3.f - 2.f * v) * MAXVALF), x); } return x; } +#ifdef __SSE2__ +inline vfloat sl(vfloat blend, vfloat x) +{ + const vfloat v = Color::gammatab_srgb[x] / F2V(MAXVALF); + return vself(vmaskf_gt(x, F2V(MAXVALF)), x, vself(vmaskf_lt(x, ZEROV), x, vintpf(blend, Color::igammatab_srgb[v * v * (F2V(3.f) - (v + v)) * MAXVALF], x))); +} +#endif + } // namespace @@ -53,24 +61,81 @@ void ImProcFunctions::softLight(LabImage *lab) if (!params->softlight.enabled || !params->softlight.strength) { return; } + BENCHFUN - Imagefloat working(lab->W, lab->H); - lab2rgb(*lab, working, params->icm.workingProfile); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + const float wp[3][3] = { + {static_cast (wprof[0][0]), static_cast (wprof[0][1]), static_cast (wprof[0][2])}, + {static_cast (wprof[1][0]), static_cast (wprof[1][1]), static_cast (wprof[1][2])}, + {static_cast (wprof[2][0]), static_cast (wprof[2][1]), static_cast (wprof[2][2])} + }; - const float blend = params->softlight.strength / 100.f; + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); + const float wip[3][3] = { + {static_cast (wiprof[0][0]), static_cast (wiprof[0][1]), static_cast (wiprof[0][2])}, + {static_cast (wiprof[1][0]), static_cast (wiprof[1][1]), static_cast (wiprof[1][2])}, + {static_cast (wiprof[2][0]), static_cast (wiprof[2][1]), static_cast (wiprof[2][2])} + }; -#ifdef _OPENMP - #pragma omp parallel for -#endif - for (int y = 0; y < working.getHeight(); ++y) { - for (int x = 0; x < working.getWidth(); ++x) { - working.r(y, x) = sl(blend, working.r(y, x)); - working.g(y, x) = sl(blend, working.g(y, x)); - working.b(y, x) = sl(blend, working.b(y, x)); +#ifdef __SSE2__ + vfloat wipv[3][3]; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + wipv[i][j] = F2V(wiprof[i][j]); + } + } + + vfloat wpv[3][3]; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + wpv[i][j] = F2V(wprof[i][j]); + } + } +#endif + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + const float blend = params->softlight.strength / 100.f; +#ifdef __SSE2__ + const vfloat blendv = F2V(blend); +#endif +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif + for (int i = 0; i < lab->H; ++i) { + int j = 0; +#ifdef __SSE2__ + for (; j < lab->W - 3; j += 4) { + vfloat Xv, Yv, Zv; + vfloat Rv, Gv, Bv; + Color::Lab2XYZ(LVFU(lab->L[i][j]),LVFU (lab->a[i][j]),LVFU (lab->b[i][j]), Xv, Yv, Zv); + Color::xyz2rgb(Xv, Yv, Zv, Rv, Gv, Bv, wipv); + Rv = sl(blendv, Rv); + Gv = sl(blendv, Gv); + Bv = sl(blendv, Bv); + Color::rgbxyz(Rv, Gv, Bv, Xv, Yv, Zv, wpv); + for (int k = 0; k < 4; ++k) { + Color::XYZ2Lab(Xv[k], Yv[k], Zv[k], lab->L[i][j + k], lab->a[i][j + k], lab->b[i][j+ k]); + } + } +#endif + for (; j < lab->W; j++) { + float X, Y, Z; + float R, G, B; + Color::Lab2XYZ(lab->L[i][j], lab->a[i][j], lab->b[i][j], X, Y, Z); + Color::xyz2rgb(X, Y, Z, R, G, B, wip); + R = sl(blend, R); + G = sl(blend, G); + B = sl(blend, B); + Color::rgbxyz(R, G, B, X, Y, Z, wp); + Color::XYZ2Lab(X, Y, Z, lab->L[i][j], lab->a[i][j], lab->b[i][j]); + } } } - - rgb2lab(working, *lab, params->icm.workingProfile); } } // namespace rtengine From 9a020899a32447be884d0e4b9b3c744cefbe00f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Wed, 11 Sep 2019 09:16:06 +0200 Subject: [PATCH 177/222] Minor cleanups --- rtengine/iptransform.cc | 95 +++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 608fa0337..1e739dac6 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -16,16 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include "rtengine.h" -#include "improcfun.h" -#include "procparams.h" +#include + #ifdef _OPENMP #include #endif + +#include "improcfun.h" + #include "mytime.h" +#include "procparams.h" #include "rt_math.h" -#include "sleef.c" +#include "rtengine.h" #include "rtlensfun.h" +#include "sleef.c" + #define BENCHMARK #include "StopWatch.h" @@ -147,7 +152,7 @@ inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, } #endif #ifdef __SSE2__ -inline void interpolateTransformChannelsCubic(const float* const * src, int xs, int ys, float Dx, float Dy, float &dest, float mul) +inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul) { constexpr float A = -0.85f; @@ -168,7 +173,7 @@ inline void interpolateTransformChannelsCubic(const float* const * src, int xs, dest = mul * vhadd(weight * cv); } #else -inline void interpolateTransformChannelsCubic(const float* const * src, int xs, int ys, float Dx, float Dy, float &dest, float mul) +inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul) { constexpr float A = -0.85f; @@ -859,29 +864,45 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I const bool enablePerspective = needsPerspective(); const bool enableDistortion = needsDistortion(); - const double w2 = (double) oW / 2.0 - 0.5; - const double h2 = (double) oH / 2.0 - 0.5; + const double w2 = static_cast(oW) / 2.0 - 0.5; + const double h2 = static_cast(oH) / 2.0 - 0.5; double vig_w2, vig_h2, maxRadius, v, b, mul; calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); - struct grad_params gp; + grad_params gp; if (enableGradient) { calcGradientParams(oW, oH, params->gradient, gp); } - struct pcv_params pcv; + pcv_params pcv; if (enablePCVignetting) { calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv); } - float** chOrig[3] = {original->r.ptrs, original->g.ptrs, original->b.ptrs}; - float** chTrans[3] = {transformed->r.ptrs, transformed->g.ptrs, transformed->b.ptrs}; + const std::array chOrig = { + original->r.ptrs, + original->g.ptrs, + original->b.ptrs + }; + const std::array chTrans = { + transformed->r.ptrs, + transformed->g.ptrs, + transformed->b.ptrs + }; // auxiliary variables for c/a correction - const double chDist[3] = {enableCA ? params->cacorrection.red : 0.0, 0.0, enableCA ? params->cacorrection.blue : 0.0}; + const std::array chDist = { + enableCA + ? params->cacorrection.red + : 0.0, + 0.0, + enableCA + ? params->cacorrection.blue + : 0.0 + }; // auxiliary variables for distortion correction const double distAmount = params->distortion.amount; @@ -893,16 +914,18 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I // auxiliary variables for vertical perspective correction const double vpdeg = params->perspective.vertical / 100.0 * 45.0; const double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI; - const double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oW * tan(vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) * - oW * tan(vpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oW * tan(vpalpha)))) / (SQR(maxRadius) * 8))); - const double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos(vpteta), vptanpt = tan(vpteta); + const double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oW * tan(vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) * + oW * tan(vpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oW * tan(vpalpha)))) / (SQR(maxRadius) * 8))); + const double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos(vpteta); + const double vptanpt = tan(vpteta); // auxiliary variables for horizontal perspective correction const double hpdeg = params->perspective.horizontal / 100.0 * 45.0; const double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI; - const double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oH * tan(hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) * - oH * tan(hpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oH * tan(hpalpha)))) / (SQR(maxRadius) * 8))); - const double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos(hpteta), hptanpt = tan(hpteta); + const double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oH * tan(hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) * + oH * tan(hpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oH * tan(hpalpha)))) / (SQR(maxRadius) * 8))); + const double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos(hpteta); + const double hptanpt = tan(hpteta); const double ascale = params->commonTrans.autofill ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0; @@ -915,9 +938,10 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I #pragma omp parallel for schedule(dynamic, 16) if(multiThread) #endif - for (int y = 0; y < transformed->getHeight(); y++) { - for (int x = 0; x < transformed->getWidth(); x++) { - double x_d = x, y_d = y; + for (int y = 0; y < transformed->getHeight(); ++y) { + for (int x = 0; x < transformed->getWidth(); ++x) { + double x_d = x; + double y_d = y; if (enableLCPDist) { pLCPMap->correctDistortion(x_d, y_d, cx, cy, ascale); // must be first transform @@ -944,14 +968,14 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I const double Dyc = x_d * sint + y_d * cost; // distortion correction - double s = 1; + double s = 1.0; if (enableDistortion) { - double r = sqrt(Dxc * Dxc + Dyc * Dyc) / maxRadius; + const double r = sqrt(Dxc * Dxc + Dyc * Dyc) / maxRadius; s = 1.0 - distAmount + distAmount * r; } - for (int c = 0; c < (enableCA ? 3 : 1); c++) { + for (int c = 0; c < (enableCA ? 3 : 1); ++c) { double Dx = Dxc * (s + chDist[c]); double Dy = Dyc * (s + chDist[c]); @@ -960,22 +984,21 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I Dy += h2; // Extract integer and fractions of source screen coordinates - int xc = (int)Dx; - Dx -= (double)xc; + int xc = Dx; + Dx -= xc; xc -= sx; - int yc = (int)Dy; - Dy -= (double)yc; + int yc = Dy; + Dy -= yc; yc -= sy; // Convert only valid pixels if (yc >= 0 && yc < original->getHeight() && xc >= 0 && xc < original->getWidth()) { - // multiplier for vignetting correction double vignmul = 1.0; if (enableVignetting) { - const double vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale - const double vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale + const double vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale + const double vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale const double vig_Dx = vig_x_d * cost - vig_y_d * sint; const double vig_Dy = vig_x_d * sint + vig_y_d * cost; const double r2 = sqrt(vig_Dx * vig_Dx + vig_Dy * vig_Dy); @@ -1007,10 +1030,10 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I } } else { // edge pixels - int y1 = LIM(yc, 0, original->getHeight() - 1); - int y2 = LIM(yc + 1, 0, original->getHeight() - 1); - int x1 = LIM(xc, 0, original->getWidth() - 1); - int x2 = LIM(xc + 1, 0, original->getWidth() - 1); + const int y1 = LIM(yc, 0, original->getHeight() - 1); + const int y2 = LIM(yc + 1, 0, original->getHeight() - 1); + const int x1 = LIM(xc, 0, original->getWidth() - 1); + const int x2 = LIM(xc + 1, 0, original->getWidth() - 1); if (enableCA) { chTrans[c][y][x] = vignmul * (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy); From 4079bb9920be8cf6c568c1b0f91bfbe3a2544b30 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 11 Sep 2019 18:56:07 +0200 Subject: [PATCH 178/222] Capture Sharpening: automatic radius calculation --- rtdata/languages/default | 2 + rtengine/capturesharpening.cc | 307 ++++++++++++++++++++++++++++++++-- rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 7 +- rtengine/improccoordinator.h | 6 + rtengine/procparams.cc | 4 + rtengine/procparams.h | 1 + rtengine/rawimagesource.h | 2 +- rtengine/refreshmap.cc | 2 +- rtengine/rt_algo.cc | 23 ++- rtengine/rt_algo.h | 2 +- rtengine/rtengine.h | 8 + rtengine/simpleprocess.cc | 2 +- rtengine/stdimagesource.h | 2 +- rtgui/paramsedited.cc | 8 +- rtgui/paramsedited.h | 1 + rtgui/pdsharpening.cc | 74 ++++++-- rtgui/pdsharpening.h | 5 +- rtgui/toolpanelcoord.cc | 1 + rtgui/toolpanelcoord.h | 1 - 20 files changed, 416 insertions(+), 44 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 5bf1863df..3749a706a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -766,6 +766,7 @@ HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_CONTRAST;CAS - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CAS - Auto threshold +HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CAS - Auto radius HISTORY_MSG_PDSHARPEN_GAMMA;CAS - Gamma HISTORY_MSG_PDSHARPEN_ITERATIONS;CAS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CAS - Radius @@ -1800,6 +1801,7 @@ TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse, TP_PCVIGNETTE_STRENGTH;Strength TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). TP_PDSHARPENING_LABEL;Capture Sharpening +TP_PDSHARPENING_AUTORADIUS_TOOLTIP;If the checkbox is checked, RawTherapee calculates a value based on the raw data of the image. TP_PERSPECTIVE_HORIZONTAL;Horizontal TP_PERSPECTIVE_LABEL;Perspective TP_PERSPECTIVE_VERTICAL;Vertical diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index eb95d2633..e741016db 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -37,6 +37,243 @@ #include "../rtgui/multilangmgr.h" namespace { + +void buildClipMaskBayer(const float * const *rawData, int W, int H, float** clipMask, const float whites[2][2]) +{ + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 0; row < H; ++row) { + for (int col = 0; col < W; ++col) { + clipMask[row][col] = 1.f; + } + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 2; row < H - 2; ++row) { + float clip0 = whites[row & 1][0]; + float clip1 = whites[row & 1][1]; + for (int col = 2; col < W - 2; ++col) { + if (rawData[row][col] >= clip0) { + clipMask[row - 2][col - 1] = clipMask[row - 2][col] = clipMask[row - 2][col + 1] = 0.f; + clipMask[row - 1][col - 2] = clipMask[row - 1][col - 1] = clipMask[row - 1][col] = clipMask[row - 1][col + 1] = clipMask[row - 1][col + 2] = 0.f; + clipMask[row][col - 2] = clipMask[row][col - 1] = clipMask[row][col] = clipMask[row][col + 1] = clipMask[row][col + 2] = 0.f; + clipMask[row + 1][col - 2] = clipMask[row + 1][col - 1] = clipMask[row + 1][col] = clipMask[row + 1][col + 1] = clipMask[row + 1][col + 2] = 0.f; + clipMask[row + 2][col - 1] = clipMask[row + 2][col] = clipMask[row + 2][col + 1] = 0.f; + } + std::swap(clip0, clip1); + } + } +} + +void buildClipMaskXtrans(const float * const *rawData, int W, int H, float** clipMask, const float whites[6][6]) +{ + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 0; row < H; ++row) { + for (int col = 0; col < W; ++col) { + clipMask[row][col] = 1.f; + } + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 2; row < H - 2; ++row) { + for (int col = 2; col < W - 2; ++col) { + const float clip = whites[row % 6][col % 6]; + if (rawData[row][col] >= clip) { + clipMask[row - 2][col - 1] = clipMask[row - 2][col] = clipMask[row - 2][col + 1] = 0.f; + clipMask[row - 1][col - 2] = clipMask[row - 1][col - 1] = clipMask[row - 1][col] = clipMask[row - 1][col + 1] = clipMask[row - 1][col + 2] = 0.f; + clipMask[row][col - 2] = clipMask[row][col - 1] = clipMask[row][col] = clipMask[row][col + 1] = clipMask[row][col + 2] = 0.f; + clipMask[row + 1][col - 2] = clipMask[row + 1][col - 1] = clipMask[row + 1][col] = clipMask[row + 1][col + 1] = clipMask[row + 1][col + 2] = 0.f; + clipMask[row + 2][col - 1] = clipMask[row + 2][col] = clipMask[row + 2][col + 1] = 0.f; + } + } + } +} + +void buildClipMaskMono(const float * const *rawData, int W, int H, float** clipMask, float white) +{ + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 0; row < H; ++row) { + for (int col = 0; col < W; ++col) { + clipMask[row][col] = 1.f; + } + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 2; row < H - 2; ++row) { + for (int col = 2; col < W - 2; ++col) { + if (rawData[row][col] >= white) { + clipMask[row - 2][col - 1] = clipMask[row - 2][col] = clipMask[row - 2][col + 1] = 0.f; + clipMask[row - 1][col - 2] = clipMask[row - 1][col - 1] = clipMask[row - 1][col] = clipMask[row - 1][col + 1] = clipMask[row - 1][col + 2] = 0.f; + clipMask[row][col - 2] = clipMask[row][col - 1] = clipMask[row][col] = clipMask[row][col + 1] = clipMask[row][col + 2] = 0.f; + clipMask[row + 1][col - 2] = clipMask[row + 1][col - 1] = clipMask[row + 1][col] = clipMask[row + 1][col + 1] = clipMask[row + 1][col + 2] = 0.f; + clipMask[row + 2][col - 1] = clipMask[row + 2][col] = clipMask[row + 2][col + 1] = 0.f; + } + } + } +} + +float calcRadiusBayer(const float * const *rawData, int W, int H, float lowerLimit, float upperLimit, const unsigned int fc[2]) +{ + + float maxRatio = 1.f; +#ifdef _OPENMP + #pragma omp parallel for reduction(max:maxRatio) schedule(dynamic, 16) +#endif + for (int row = 4; row < H - 4; ++row) { + for (int col = 5 + (fc[row & 1] & 1); col < W - 4; col += 2) { + const float val00 = rawData[row][col]; + if (val00 > 0.f) { + const float val1m1 = rawData[row + 1][col - 1]; + const float val1p1 = rawData[row + 1][col + 1]; + const float maxVal0 = std::max(val00, val1m1); + if (val1m1 > 0.f && maxVal0 > lowerLimit) { + const float minVal = std::min(val00, val1m1); + if (UNLIKELY(maxVal0 > maxRatio * minVal)) { + bool clipped = false; + if (maxVal0 == val00) { // check for influence by clipped green in neighborhood + if (rtengine::max(rawData[row - 1][col - 1], rawData[row - 1][col + 1], val1p1) >= upperLimit) { + clipped = true; + } + } else { // check for influence by clipped green in neighborhood + if (rtengine::max(rawData[row][col - 2], val00, rawData[row + 2][col - 2], rawData[row + 2][col]) >= upperLimit) { + clipped = true; + } + } + if (!clipped) { + maxRatio = maxVal0 / minVal; + } + } + } + const float maxVal1 = std::max(val00, val1p1); + if (val1p1 > 0.f && maxVal1 > lowerLimit) { + const float minVal = std::min(val00, val1p1); + if (UNLIKELY(maxVal1 > maxRatio * minVal)) { + if (maxVal1 == val00) { // check for influence by clipped green in neighborhood + if (rtengine::max(rawData[row - 1][col - 1], rawData[row - 1][col + 1], val1p1) >= upperLimit) { + continue; + } + } else { // check for influence by clipped green in neighborhood + if (rtengine::max(val00, rawData[row][col + 2], rawData[row + 2][col], rawData[row + 2][col + 2]) >= upperLimit) { + continue; + } + } + maxRatio = maxVal1 / minVal; + } + } + } + } + } + return std::sqrt((1.f / (std::log(1.f / maxRatio) / 2.f)) / -2.f); +} + +float calcRadiusXtrans(const float * const *rawData, int W, int H, float lowerLimit, float upperLimit, unsigned int starty, unsigned int startx) +{ + + float maxRatio = 1.f; +#ifdef _OPENMP + #pragma omp parallel for reduction(max:maxRatio) schedule(dynamic, 16) +#endif + for (int row = starty + 3; row < H - 4; row += 3) { + for (int col = startx + 3; col < W - 4; col += 3) { + const float valtl = rawData[row][col]; + const float valtr = rawData[row][col + 1]; + const float valbl = rawData[row + 1][col]; + const float valbr = rawData[row + 1][col + 1]; + if (valtl > 1.f) { + const float maxValtltr = std::max(valtl, valtr); + if (valtr > 1.f && maxValtltr > lowerLimit) { + const float minVal = std::min(valtl, valtr); + if (UNLIKELY(maxValtltr > maxRatio * minVal)) { + bool clipped = false; + if (maxValtltr == valtl) { // check for influence by clipped green in neighborhood + if (rtengine::max(rawData[row - 1][col - 1], valtr, valbl, valbr) >= upperLimit) { + clipped = true; + } + } else { // check for influence by clipped green in neighborhood + if (rtengine::max(rawData[row - 1][col + 2], valtl, valbl, valbr) >= upperLimit) { + clipped = true; + } + } + if (!clipped) { + maxRatio = maxValtltr / minVal; + } + } + } + const float maxValtlbl = std::max(valtl, valbl); + if (valbl > 1.f && maxValtlbl > lowerLimit) { + const float minVal = std::min(valtl, valbl); + if (UNLIKELY(maxValtlbl > maxRatio * minVal)) { + bool clipped = false; + if (maxValtlbl == valtl) { // check for influence by clipped green in neighborhood + if (rtengine::max(rawData[row - 1][col - 1], valtr, valbl, valbr) >= upperLimit) { + clipped = true; + } + } else { // check for influence by clipped green in neighborhood + if (rtengine::max(valtl, valtr, rawData[row + 2][col - 1], valbr) >= upperLimit) { + clipped = true; + } + } + if (!clipped) { + maxRatio = maxValtlbl / minVal; + } + } + } + } + if (valbr > 1.f) { + const float maxValblbr = std::max(valbl, valbr); + if (valbl > 1.f && maxValblbr > lowerLimit) { + const float minVal = std::min(valbl, valbr); + if (UNLIKELY(maxValblbr > maxRatio * minVal)) { + bool clipped = false; + if (maxValblbr == valbr) { // check for influence by clipped green in neighborhood + if (rtengine::max(valtl, valtr, valbl, rawData[row + 2][col + 2]) >= upperLimit) { + clipped = true; + } + } else { // check for influence by clipped green in neighborhood + if (rtengine::max(valtl, valtr, rawData[row + 2][col - 1], valbr) >= upperLimit) { + clipped = true; + } + } + if (!clipped) { + maxRatio = maxValblbr / minVal; + } + } + } + const float maxValtrbr = std::max(valtr, valbr); + if (valtr > 1.f && maxValtrbr > lowerLimit) { + const float minVal = std::min(valtr, valbr); + if (UNLIKELY(maxValtrbr > maxRatio * minVal)) { + if (maxValtrbr == valbr) { // check for influence by clipped green in neighborhood + if (rtengine::max(valtl, valtr, valbl, rawData[row + 2][col + 2]) >= upperLimit) { + continue; + } + } else { // check for influence by clipped green in neighborhood + if (rtengine::max(rawData[row - 1][col + 2], valtl, valbl, valbr) >= upperLimit) { + continue; + } + } + maxRatio = maxValtrbr / minVal; + } + } + } + } + } + return std::sqrt((1.f / (std::log(1.f / maxRatio))) / -2.f); +} void CaptureDeconvSharpening (float** luminance, float** tmp, const float * const * blend, int W, int H, double sigma, int iterations, rtengine::ProgressListener* plistener, double start, double step) { @@ -54,7 +291,7 @@ void CaptureDeconvSharpening (float** luminance, float** tmp, const float * cons tmpI[i][j] = max(luminance[i][j], 0.f); } } - + for (int k = 0; k < iterations; k++) { // apply gaussian blur and divide luminance by result of gaussian blur gaussianBlur(tmpI, tmp, W, H, sigma, nullptr, GAUSS_DIV, luminance); @@ -85,9 +322,7 @@ void CaptureDeconvSharpening (float** luminance, float** tmp, const float * cons namespace rtengine { -void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { -BENCHFUN - +void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) { if (plistener) { plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); @@ -102,12 +337,62 @@ BENCHFUN float contrast = conrastThreshold / 100.f; + const float clipVal = (ri->get_white(1) - ri->get_cblack(1)) * scale_mul[1]; + array2D& redVals = redCache ? *redCache : red; array2D& greenVals = greenCache ? *greenCache : green; array2D& blueVals = blueCache ? *blueCache : blue; + array2D clipMask(W, H); + constexpr float clipLimit = 0.95f; + if (ri->getSensorType() == ST_BAYER) { + const float whites[2][2] = { + {(ri->get_white(FC(0,0)) - c_black[FC(0,0)]) * scale_mul[FC(0,0)] * clipLimit, (ri->get_white(FC(0,1)) - c_black[FC(0,1)]) * scale_mul[FC(0,1)] * clipLimit}, + {(ri->get_white(FC(1,0)) - c_black[FC(1,0)]) * scale_mul[FC(1,0)] * clipLimit, (ri->get_white(FC(1,1)) - c_black[FC(1,1)]) * scale_mul[FC(1,1)] * clipLimit} + }; + buildClipMaskBayer(rawData, W, H, clipMask, whites); + const unsigned int fc[2] = {FC(0,0), FC(1,0)}; + if (sharpeningParams.autoRadius) { + radius = calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc); + } + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { + float whites[6][6]; + for (int i = 0; i < 6; ++i) { + for (int j = 0; j < 6; ++j) { + const auto color = ri->XTRANSFC(i, j); + whites[i][j] = (ri->get_white(color) - c_black[color]) * scale_mul[color] * clipLimit; + } + } + buildClipMaskXtrans(rawData, W, H, clipMask, whites); + bool found = false; + int i, j; + for (i = 6; i < 12 && !found; ++i) { + for (j = 6; j < 12 && !found; ++j) { + if (ri->XTRANSFC(i, j) == 1) { + if (ri->XTRANSFC(i, j - 1) != ri->XTRANSFC(i, j + 1)) { + if (ri->XTRANSFC(i - 1, j) != 1) { + if (ri->XTRANSFC(i, j - 1) != 1) { + found = true; + break; + } + } + } + } + } + } + if (sharpeningParams.autoRadius) { + radius = calcRadiusXtrans(rawData, W, H, 1000.f, clipVal, i, j); + } + + } else if (ri->get_colors() == 1) { + buildClipMaskMono(rawData, W, H, clipMask, (ri->get_white(0) - c_black[0]) * scale_mul[0] * clipLimit); + if (sharpeningParams.autoRadius) { + const unsigned int fc[2] = {0, 0}; + radius = calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc); + } + } + if (showMask) { - StopWatch Stop1("Show mask"); array2D& L = blue; // blue will be overridden anyway => we can use its buffer to store L #ifdef _OPENMP #pragma omp parallel for @@ -119,8 +404,9 @@ BENCHFUN if (plistener) { plistener->setProgress(0.1); } + array2D& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask - buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast, clipMask); if (plistener) { plistener->setProgress(0.2); } @@ -157,7 +443,6 @@ BENCHFUN array2D& YOld = YOldbuffer ? * YOldbuffer : green; array2D& YNew = YNewbuffer ? * YNewbuffer : blue; - StopWatch Stop1("rgb2YL"); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif @@ -170,19 +455,17 @@ BENCHFUN } // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); + buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast, clipMask); if (plistener) { plistener->setProgress(0.2); } conrastThreshold = contrast * 100.f; - Stop1.stop(); array2D& tmp = L; // L is not used anymore now => we can use its buffer as the needed temporary buffer - CaptureDeconvSharpening(YNew, tmp, blend, W, H, sharpeningParams.deconvradius, sharpeningParams.deconviter, plistener, 0.2, (0.9 - 0.2) / sharpeningParams.deconviter); + CaptureDeconvSharpening(YNew, tmp, blend, W, H, radius, sharpeningParams.deconviter, plistener, 0.2, (0.9 - 0.2) / sharpeningParams.deconviter); if (plistener) { plistener->setProgress(0.9); } - StopWatch Stop2("Y2RGB"); const float gamma = sharpeningParams.gamma; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) @@ -206,7 +489,7 @@ BENCHFUN blue[i][j] = blueVals[i][j] * factor; } } - Stop2.stop(); + delete Lbuffer; delete YOldbuffer; delete YNewbuffer; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index c62dfe7d8..edc1102c4 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -182,7 +182,7 @@ public: return this; } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; - virtual void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) = 0; + virtual void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) = 0; }; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index c6268576a..8b9e49124 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -122,6 +122,7 @@ ImProcCoordinator::ImProcCoordinator() : bayerAutoContrastListener(nullptr), xtransAutoContrastListener(nullptr), pdSharpenAutoContrastListener(nullptr), + pdSharpenAutoRadiusListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), @@ -346,10 +347,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((todo & (M_RAW | M_CSHARP)) && params->pdsharpening.enabled) { double pdSharpencontrastThreshold = params->pdsharpening.contrast; - imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold); + double pdSharpenRadius = params->pdsharpening.deconvradius; + imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold, pdSharpenRadius); if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) { pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold); } + if (pdSharpenAutoRadiusListener && params->pdsharpening.autoRadius) { + pdSharpenAutoRadiusListener->autoRadiusChanged(pdSharpenRadius); + } } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index df4ec8134..379a3fb20 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -162,6 +162,7 @@ protected: AutoContrastListener *bayerAutoContrastListener; AutoContrastListener *xtransAutoContrastListener; AutoContrastListener *pdSharpenAutoContrastListener; + AutoRadiusListener *pdSharpenAutoRadiusListener; FrameCountListener *frameCountListener; ImageTypeListener *imageTypeListener; @@ -364,6 +365,11 @@ public: xtransAutoContrastListener = acl; } + void setpdSharpenAutoRadiusListener (AutoRadiusListener* acl) override + { + pdSharpenAutoRadiusListener = acl; + } + void setpdSharpenAutoContrastListener (AutoContrastListener* acl) override { pdSharpenAutoContrastListener = acl; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2fcc5d358..f88220c4e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1152,6 +1152,7 @@ bool SharpeningParams::operator !=(const SharpeningParams& other) const CaptureSharpeningParams::CaptureSharpeningParams() : enabled(false), autoContrast(true), + autoRadius(true), contrast(10.0), gamma(1.00), deconvradius(0.75), @@ -1166,6 +1167,7 @@ bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) && contrast == other.contrast && gamma == other.gamma && autoContrast == other.autoContrast + && autoRadius == other.autoRadius && deconvradius == other.deconvradius && deconviter == other.deconviter; } @@ -3370,6 +3372,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->pdsharpening.enabled, "PostDemosaicSharpening", "Enabled", pdsharpening.enabled, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.contrast, "PostDemosaicSharpening", "Contrast", pdsharpening.contrast, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.autoContrast, "PostDemosaicSharpening", "AutoContrast", pdsharpening.autoContrast, keyFile); + 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.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); @@ -4458,6 +4461,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Enabled", pedited, pdsharpening.enabled, pedited->pdsharpening.enabled); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pedited, pdsharpening.contrast, pedited->pdsharpening.contrast); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoContrast", pedited, pdsharpening.autoContrast, pedited->pdsharpening.autoContrast); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pedited, pdsharpening.autoRadius, pedited->pdsharpening.autoRadius); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvGamma", pedited, pdsharpening.gamma, pedited->pdsharpening.gamma); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index e8f846a1d..ce03efc7d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -545,6 +545,7 @@ struct SharpenMicroParams { struct CaptureSharpeningParams { bool enabled; bool autoContrast; + bool autoRadius; double contrast; double gamma; double deconvradius; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index e20024f3c..e52adea18 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -311,7 +311,7 @@ protected: void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; - void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override; + void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override; }; } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index db56500b8..6917d856e 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -521,7 +521,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RGBCURVE, // EvRGBEnabled LUMINANCECURVE, // EvLEnabled DEMOSAIC, // EvPdShrEnabled - ALLNORAW // EvPdShrMaskToggled + CAPTURESHARPEN // EvPdShrMaskToggled }; diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc index 9fdb59652..4afd8ac73 100644 --- a/rtengine/rt_algo.cc +++ b/rtengine/rt_algo.cc @@ -156,7 +156,7 @@ float calcContrastThreshold(const float* const * luminance, int tileY, int tileX } } - return c / 100.f; + return (c + 1) / 100.f; } } @@ -299,7 +299,7 @@ void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& maxOut = rtengine::LIM(maxOut, minVal, maxVal); } -void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast) { +void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast, float ** clipMask) { if (autoContrast) { constexpr float minLuminance = 2000.f; @@ -424,11 +424,20 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H, for(int j = 2; j < H - 2; ++j) { int i = 2; #ifdef __SSE2__ - for(; i < W - 5; i += 4) { - vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) + - SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev; + if (clipMask) { + for(; i < W - 5; i += 4) { + vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) + + SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev; - STVFU(blend[j][i], amountv * calcBlendFactor(contrastv, contrastThresholdv)); + STVFU(blend[j][i], LVFU(clipMask[j][i]) * amountv * calcBlendFactor(contrastv, contrastThresholdv)); + } + } else { + for(; i < W - 5; i += 4) { + vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) + + SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev; + + STVFU(blend[j][i], amountv * calcBlendFactor(contrastv, contrastThresholdv)); + } } #endif for(; i < W - 2; ++i) { @@ -436,7 +445,7 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float contrast = sqrtf(rtengine::SQR(luminance[j][i+1] - luminance[j][i-1]) + rtengine::SQR(luminance[j+1][i] - luminance[j-1][i]) + rtengine::SQR(luminance[j][i+2] - luminance[j][i-2]) + rtengine::SQR(luminance[j+2][i] - luminance[j-2][i])) * scale; - blend[j][i] = amount * calcBlendFactor(contrast, contrastThreshold); + blend[j][i] = (clipMask ? clipMask[j][i] : 1.f) * amount * calcBlendFactor(contrast, contrastThreshold); } } diff --git a/rtengine/rt_algo.h b/rtengine/rt_algo.h index 0ea000a26..5485346c7 100644 --- a/rtengine/rt_algo.h +++ b/rtengine/rt_algo.h @@ -24,5 +24,5 @@ namespace rtengine { void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true); -void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false); +void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false, float ** clipmask = nullptr); } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 33cca1aba..c188622af 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -415,6 +415,13 @@ public : virtual void autoContrastChanged (double autoContrast) = 0; }; +class AutoRadiusListener +{ +public : + virtual ~AutoRadiusListener() = default; + virtual void autoRadiusChanged (double autoRadius) = 0; +}; + class WaveletListener { public: @@ -524,6 +531,7 @@ public: virtual void setBayerAutoContrastListener (AutoContrastListener* l) = 0; virtual void setXtransAutoContrastListener (AutoContrastListener* l) = 0; virtual void setpdSharpenAutoContrastListener (AutoContrastListener* l) = 0; + virtual void setpdSharpenAutoRadiusListener (AutoRadiusListener* l) = 0; virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoWBListener (AutoWBListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 2022d2d15..6dbb0e649 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -222,7 +222,7 @@ private: imgsrc->demosaic (params.raw, autoContrast, contrastThreshold, params.pdsharpening.enabled && pl); if (params.pdsharpening.enabled) { - imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast); + imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast, params.pdsharpening.deconvradius); } diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index ef1294dea..0dffe2fd0 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -102,7 +102,7 @@ public: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;} void flushRGB () override; - void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) override {}; + void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override {}; }; } #endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 84860329f..2ab5702ea 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -168,6 +168,7 @@ void ParamsEdited::set(bool v) pdsharpening.enabled = v; pdsharpening.contrast = v; pdsharpening.autoContrast = v; + pdsharpening.autoRadius = v; pdsharpening.gamma = v; pdsharpening.deconvradius = v; pdsharpening.deconviter = v; @@ -752,6 +753,7 @@ void ParamsEdited::initFrom(const std::vector& pdsharpening.enabled = pdsharpening.enabled && p.pdsharpening.enabled == other.pdsharpening.enabled; pdsharpening.contrast = pdsharpening.contrast && p.pdsharpening.contrast == other.pdsharpening.contrast; pdsharpening.autoContrast = pdsharpening.autoContrast && p.pdsharpening.autoContrast == other.pdsharpening.autoContrast; + 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.deconviter = pdsharpening.deconviter && p.pdsharpening.deconviter == other.pdsharpening.deconviter; @@ -1732,6 +1734,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.autoContrast = mods.pdsharpening.autoContrast; } + if (pdsharpening.autoRadius) { + toEdit.pdsharpening.autoRadius = mods.pdsharpening.autoRadius; + } + if (pdsharpening.gamma) { toEdit.pdsharpening.gamma = dontforceSet && options.baBehav[ADDSET_SHARP_GAMMA] ? toEdit.pdsharpening.gamma + mods.pdsharpening.gamma : mods.pdsharpening.gamma; } @@ -3289,5 +3295,5 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool CaptureSharpeningParamsEdited::isUnchanged() const { - return enabled && contrast && autoContrast && gamma && deconvradius && deconviter; + return enabled && contrast && autoContrast && autoRadius && gamma && deconvradius && deconviter; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 860ffc551..1bd7170d4 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -202,6 +202,7 @@ struct CaptureSharpeningParamsEdited { bool enabled; bool contrast; bool autoContrast; + bool autoRadius; bool gamma; bool deconvradius; bool deconviter; diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index c85b42e95..ef0ad90c2 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -35,6 +35,7 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS EvPdShrDRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS"); 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"); Gtk::HBox* hb = Gtk::manage(new Gtk::HBox()); hb->show(); @@ -51,6 +52,8 @@ 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->addAutoButton(M("TP_PDSHARPENING_AUTORADIUS_TOOLTIP")); + dradius->setAutoValue(true); diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 1, 100, 1, 20)); rld->pack_start(*gamma); rld->pack_start(*dradius); @@ -85,6 +88,7 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) if (pedited) { contrast->setEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); contrast->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoContrast); + dradius->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoRadius); gamma->setEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); diter->setEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); @@ -98,8 +102,10 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) contrast->setAutoValue(pp->pdsharpening.autoContrast); gamma->setValue(pp->pdsharpening.gamma); dradius->setValue(pp->pdsharpening.deconvradius); + dradius->setAutoValue(pp->pdsharpening.autoRadius); diter->setValue(pp->pdsharpening.deconviter); lastAutoContrast = pp->pdsharpening.autoContrast; + lastAutoRadius = pp->pdsharpening.autoRadius; enableListener(); } @@ -112,6 +118,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pp->pdsharpening.enabled = getEnabled(); pp->pdsharpening.gamma = gamma->getValue(); pp->pdsharpening.deconvradius = dradius->getValue(); + pp->pdsharpening.autoRadius = dradius->getAutoValue(); pp->pdsharpening.deconviter =(int)diter->getValue(); if (pedited) { @@ -119,6 +126,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pedited->pdsharpening.autoContrast = !contrast->getAutoInconsistent(); pedited->pdsharpening.gamma = gamma->getEditedState(); pedited->pdsharpening.deconvradius = dradius->getEditedState(); + pedited->pdsharpening.autoRadius = !dradius->getAutoInconsistent(); pedited->pdsharpening.deconviter = diter->getEditedState(); pedited->pdsharpening.enabled = !get_inconsistent(); } @@ -224,26 +232,62 @@ void PdSharpening::autoContrastChanged(double autoContrast) ); } +void PdSharpening::autoRadiusChanged(double autoRadius) +{ + idle_register.add( + [this, autoRadius]() -> bool + { + disableListener(); + dradius->setValue(autoRadius); + enableListener(); + return false; + } + ); +} + void PdSharpening::adjusterAutoToggled(Adjuster* a, bool newval) { - if (multiImage) { - if (contrast->getAutoInconsistent()) { - contrast->setAutoInconsistent(false); - contrast->setAutoValue(false); - } else if (lastAutoContrast) { - contrast->setAutoInconsistent(true); + if (a == contrast) { + if (multiImage) { + if (contrast->getAutoInconsistent()) { + contrast->setAutoInconsistent(false); + contrast->setAutoValue(false); + } else if (lastAutoContrast) { + contrast->setAutoInconsistent(true); + } + + lastAutoContrast = contrast->getAutoValue(); } - lastAutoContrast = contrast->getAutoValue(); - } + if (listener) { + if (contrast->getAutoInconsistent()) { + listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_UNCHANGED")); + } else if (contrast->getAutoValue()) { + listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_DISABLED")); + } + } + } else { // must be dradius + if (multiImage) { + if (dradius->getAutoInconsistent()) { + dradius->setAutoInconsistent(false); + dradius->setAutoValue(false); + } else if (lastAutoRadius) { + dradius->setAutoInconsistent(true); + } - if (listener) { - if (contrast->getAutoInconsistent()) { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_UNCHANGED")); - } else if (contrast->getAutoValue()) { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_DISABLED")); + lastAutoRadius = dradius->getAutoValue(); + } + + if (listener) { + if (dradius->getAutoInconsistent()) { + listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_UNCHANGED")); + } else if (dradius->getAutoValue()) { + listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_DISABLED")); + } } } } diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index b2f7b6e57..e56b4b085 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -21,7 +21,7 @@ #include "adjuster.h" #include "toolpanel.h" -class PdSharpening final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoContrastListener +class PdSharpening final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoContrastListener, public rtengine::AutoRadiusListener { protected: @@ -31,11 +31,13 @@ protected: Adjuster* diter; bool lastAutoContrast; + bool lastAutoRadius; rtengine::ProcEvent EvPdShrContrast; rtengine::ProcEvent EvPdShrDRadius; rtengine::ProcEvent EvPdSharpenGamma; rtengine::ProcEvent EvPdShrDIterations; rtengine::ProcEvent EvPdShrAutoContrast; + rtengine::ProcEvent EvPdShrAutoRadius; IdleRegister idle_register; public: @@ -53,6 +55,7 @@ public: void enabledChanged () override; void autoContrastChanged (double autoContrast) override; + void autoRadiusChanged (double autoRadius) override; void setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool iteradds); void trimValues (rtengine::procparams::ProcParams* pp) override; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index a664942a1..4fec4a18a 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -573,6 +573,7 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool ipc->setBayerAutoContrastListener (bayerprocess); ipc->setXtransAutoContrastListener (xtransprocess); ipc->setpdSharpenAutoContrastListener (pdSharpening); + ipc->setpdSharpenAutoRadiusListener (pdSharpening); ipc->setAutoWBListener (whitebalance); ipc->setAutoColorTonListener (colortoning); ipc->setAutoChromaListener (dirpyrdenoise); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 390967395..3a4ddc05f 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -242,7 +242,6 @@ public: void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false) override; -// void autoContrastChanged (double autoContrast); // profilechangelistener interface void profileChange( const rtengine::procparams::PartialProfile* nparams, From af10bf8c7c8f06c5fc2effecda4533937016ee9a Mon Sep 17 00:00:00 2001 From: "luz.paz" Date: Wed, 11 Sep 2019 17:38:55 -0400 Subject: [PATCH 179/222] Fix misc. source comment typo Found via `codespell -q 3 -I ../rawtherapy-whitelist.txt -S ./rtdata/languages -L bord,hist,fo,reall,bloc,alph,dof,thre,makro,chang,currentry,portugues,vektor,ue` --- rtengine/demosaic_algos.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 49b386b0a..51db8bb3f 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -2024,7 +2024,8 @@ void RawImageSource::refinement(int PassCount) // Refinement based on EECI demozaicing algorithm by L. Chang and Y.P. Tan // from "Lassus" : Luis Sanz Rodriguez, adapted by Jacques Desmis - JDC - and Oliver Duis for RawTherapee -// increases the signal to noise ratio (PSNR) # +1 to +2 dB : tested with Dcraw : eg: Lighthouse + AMaZE : whitout refinement:39.96dB, with refinement:41.86 dB +// increases the signal to noise ratio (PSNR) # +1 to +2 dB : tested with Dcraw : +// eg: Lighthouse + AMaZE : without refinement:39.96 dB, with refinement:41.86 dB // reduce color artifacts, improves the interpolation // but it's relatively slow // From 1e75f38dba6b95d380f1d97fb9ec61748a139ff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Thu, 12 Sep 2019 14:49:51 +0200 Subject: [PATCH 180/222] Softlight cleanups - More `const` - Removed `using namespace` - Whitespace cleanups --- rtengine/ipsoftlight.cc | 57 ++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/rtengine/ipsoftlight.cc b/rtengine/ipsoftlight.cc index 1d94a29c2..556790eb4 100644 --- a/rtengine/ipsoftlight.cc +++ b/rtengine/ipsoftlight.cc @@ -20,17 +20,17 @@ */ #include "improcfun.h" + #include "procparams.h" #define BENCHMARK #include "StopWatch.h" -namespace rtengine { namespace { inline float sl(float blend, float x) { - if (!OOG(x)) { - float v = Color::gamma_srgb(x) / MAXVALF; + if (!rtengine::OOG(x)) { + float v = rtengine::Color::gamma_srgb(x) / rtengine::MAXVALF; // using Pegtop's formula from // https://en.wikipedia.org/wiki/Blend_modes#Soft_Light // const float orig = 1.f - blend; @@ -40,7 +40,7 @@ inline float sl(float blend, float x) // return blend * Color::igamma_srgb(v * MAXVALF) + orig * x; // using optimized formula (heckflosse67@gmx.de) - return intp(blend, Color::igamma_srgb(v * v * (3.f - 2.f * v) * MAXVALF), x); + return rtengine::intp(blend, rtengine::Color::igamma_srgb(v * v * (3.f - 2.f * v) * rtengine::MAXVALF), x); } return x; } @@ -48,51 +48,46 @@ inline float sl(float blend, float x) #ifdef __SSE2__ inline vfloat sl(vfloat blend, vfloat x) { - const vfloat v = Color::gammatab_srgb[x] / F2V(MAXVALF); - return vself(vmaskf_gt(x, F2V(MAXVALF)), x, vself(vmaskf_lt(x, ZEROV), x, vintpf(blend, Color::igammatab_srgb[v * v * (F2V(3.f) - (v + v)) * MAXVALF], x))); + const vfloat v = rtengine::Color::gammatab_srgb[x] / F2V(rtengine::MAXVALF); + return vself(vmaskf_gt(x, F2V(rtengine::MAXVALF)), x, vself(vmaskf_lt(x, ZEROV), x, vintpf(blend, rtengine::Color::igammatab_srgb[v * v * (F2V(3.f) - (v + v)) * rtengine::MAXVALF], x))); } #endif } // namespace - -void ImProcFunctions::softLight(LabImage *lab) +void rtengine::ImProcFunctions::softLight(LabImage *lab) { if (!params->softlight.enabled || !params->softlight.strength) { return; } BENCHFUN - TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); const float wp[3][3] = { - {static_cast (wprof[0][0]), static_cast (wprof[0][1]), static_cast (wprof[0][2])}, - {static_cast (wprof[1][0]), static_cast (wprof[1][1]), static_cast (wprof[1][2])}, - {static_cast (wprof[2][0]), static_cast (wprof[2][1]), static_cast (wprof[2][2])} + {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} }; - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); + const TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); const float wip[3][3] = { - {static_cast (wiprof[0][0]), static_cast (wiprof[0][1]), static_cast (wiprof[0][2])}, - {static_cast (wiprof[1][0]), static_cast (wiprof[1][1]), static_cast (wiprof[1][2])}, - {static_cast (wiprof[2][0]), static_cast (wiprof[2][1]), static_cast (wiprof[2][2])} + {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} }; #ifdef __SSE2__ - vfloat wipv[3][3]; + const vfloat wpv[3][3] = { + {F2V(wprof[0][0]), F2V(wprof[0][1]), F2V(wprof[0][2])}, + {F2V(wprof[1][0]), F2V(wprof[1][1]), F2V(wprof[1][2])}, + {F2V(wprof[2][0]), F2V(wprof[2][1]), F2V(wprof[2][2])} + }; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - wipv[i][j] = F2V(wiprof[i][j]); - } - } - - vfloat wpv[3][3]; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - wpv[i][j] = F2V(wprof[i][j]); - } - } + const vfloat wipv[3][3] = { + {F2V(wiprof[0][0]), F2V(wiprof[0][1]), F2V(wiprof[0][2])}, + {F2V(wiprof[1][0]), F2V(wiprof[1][1]), F2V(wiprof[1][2])}, + {F2V(wiprof[2][0]), F2V(wiprof[2][1]), F2V(wiprof[2][2])} + }; #endif #ifdef _OPENMP @@ -137,5 +132,3 @@ void ImProcFunctions::softLight(LabImage *lab) } } } - -} // namespace rtengine From 62ec0f0fd295d6e86437953bc3254a3d32b5339e Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 14 Sep 2019 14:43:32 +0200 Subject: [PATCH 181/222] Capture sharpening: tiled deconvolution --- rtengine/capturesharpening.cc | 381 ++++++++++++++++++++++++++++++---- rtengine/rt_algo.cc | 2 +- 2 files changed, 346 insertions(+), 37 deletions(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index e741016db..ef35695f3 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -28,7 +28,7 @@ #include "color.h" #include "gauss.h" #include "rt_algo.h" -#define BENCHMARK +//#define BENCHMARK #include "StopWatch.h" #ifdef _OPENMP #include @@ -38,6 +38,257 @@ namespace { +void compute7x7kernel(float sigma, float kernel[7][7]) { + + const double temp = -2.f * rtengine::SQR(sigma); + float sum = 0.f; + for (int i = -3; i <= 3; ++i) { + for (int j = -3; j <= 3; ++j) { + if((rtengine::SQR(i) + rtengine::SQR(j)) <= rtengine::SQR(3.0 * 1.15)) { + kernel[i + 3][j + 3] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); + sum += kernel[i + 3][j + 3]; + } else { + kernel[i + 3][j + 3] = 0.f; + } + } + } + + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + kernel[i][j] /= sum; + } + } +} + +void compute5x5kernel(float sigma, float kernel[5][5]) { + + const double temp = -2.f * rtengine::SQR(sigma); + float sum = 0.f; + for (int i = -2; i <= 2; ++i) { + for (int j = -2; j <= 2; ++j) { + if((rtengine::SQR(i) + rtengine::SQR(j)) <= rtengine::SQR(3.0 * 0.84)) { + kernel[i + 2][j + 2] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); + sum += kernel[i + 2][j + 2]; + } else { + kernel[i + 2][j + 2] = 0.f; + } + } + } + + for (int i = 0; i < 5; ++i) { + for (int j = 0; j < 5; ++j) { + kernel[i][j] /= sum; + } + } +} + +void compute3x3kernel(float sigma, float kernel[3][3]) { + + const double temp = -2.f * rtengine::SQR(sigma); + float sum = 0.f; + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + if((rtengine::SQR(i) + rtengine::SQR(j)) <= rtengine::SQR(3.0 * 0.84)) { + kernel[i + 1][j + 1] = std::exp((rtengine::SQR(i) + rtengine::SQR(j)) / temp); + sum += kernel[i + 1][j + 1]; + } else { + kernel[i + 1][j + 1] = 0.f; + } + } + } + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + kernel[i][j] /= sum; + } + } +} + +inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[3][3]) +{ + + const float c11 = kernel[0][0]; + const float c10 = kernel[0][1]; + const float c00 = kernel[1][1]; + + for (int i = 1; i < H - 1; i++) { + dst[i][0] = 1.f; + for (int j = 1; j < W - 1; j++) { + const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; + dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); + } + dst[i][W - 1] = 1.f; + } + // first and last rows + { + for (int i = 0; i < 1; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + for (int i = H - 1 ; i < H; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + } +} + +inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[5][5]) +{ + + const float c21 = kernel[0][1]; + const float c20 = kernel[0][2]; + const float c11 = kernel[1][1]; + const float c10 = kernel[1][2]; + const float c00 = kernel[2][2]; + + for (int i = 2; i < H - 2; ++i) { + dst[i][0] = dst[i][1] = 1.f; + // I tried hand written SSE code but gcc vectorizes better + for (int j = 2; j < W - 2; ++j) { + const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; + + dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); + } + dst[i][W - 2] = dst[i][W - 1] = 1.f; + } + + // first and last rows + { + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + for (int i = H - 2 ; i < H; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + } +} + +inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[7][7]) +{ + + const float c31 = kernel[0][2]; + const float c30 = kernel[0][3]; + const float c22 = kernel[1][1]; + const float c21 = kernel[1][2]; + const float c20 = kernel[1][3]; + const float c11 = kernel[2][2]; + const float c10 = kernel[2][3]; + const float c00 = kernel[3][3]; + + for (int i = 3; i < H - 3; ++i) { + dst[i][0] = dst[i][1] = dst[i][2] = 1.f; + // I tried hand written SSE code but gcc vectorizes better + for (int j = 3; j < W - 3; ++j) { + const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + + c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; + + dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); + } + dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f; + } + + // first and last rows + { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + for (int i = H - 3 ; i < H; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; + } + } + } +} + +inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[3][3]) +{ + const float c11 = kernel[0][0]; + const float c10 = kernel[0][1]; + const float c00 = kernel[1][1]; + + for (int i = 1; i < H - 1; i++) { + for (int j = 1; j < W - 1; j++) { + const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; + dst[i][j] *= val; + } + } + +} + +inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[5][5]) +{ + + const float c21 = kernel[0][1]; + const float c20 = kernel[0][2]; + const float c11 = kernel[1][1]; + const float c10 = kernel[1][2]; + const float c00 = kernel[2][2]; + + for (int i = 2; i < H - 2; ++i) { + // I tried hand written SSE code but gcc vectorizes better + for (int j = 2; j < W - 2; ++j) { + const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; + + dst[i][j] *= val; + } + } +} + +inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[7][7]) +{ + + const float c31 = kernel[0][2]; + const float c30 = kernel[0][3]; + const float c22 = kernel[1][1]; + const float c21 = kernel[1][2]; + const float c20 = kernel[1][3]; + const float c11 = kernel[2][2]; + const float c10 = kernel[2][3]; + const float c00 = kernel[3][3]; + + for (int i = 3; i < H - 3; ++i) { + // I tried hand written SSE code but gcc vectorizes better + for (int j = 3; j < W - 3; ++j) { + const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + + c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + + c00 * src[i][j]; + + dst[i][j] *= val; + } + } +} + void buildClipMaskBayer(const float * const *rawData, int W, int H, float** clipMask, const float whites[2][2]) { @@ -274,47 +525,106 @@ 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** tmp, const float * const * blend, int W, int H, double sigma, int iterations, rtengine::ProgressListener* plistener, double start, double step) +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) { +BENCHFUN + const bool is5x5 = (sigma <= 0.84); + const bool is3x3 = (sigma < 0.6); + float kernel7[7][7]; + float kernel5[5][5]; + float kernel3[3][3]; + if (is3x3) { + compute3x3kernel(sigma, kernel3); + } else if (is5x5) { + compute5x5kernel(sigma, kernel5); + } else { + compute7x7kernel(sigma, kernel7); + } - rtengine::JaggedArray tmpI(W, H); + constexpr int tileSize = 194; + constexpr int border = 3; + constexpr int fullTileSize = tileSize + 2 * border; + double progress = startVal; + const double progressStep = (endVal - startVal) * rtengine::SQR(tileSize) / (W * H); #ifdef _OPENMP #pragma omp parallel #endif { + int progresscounter = 0; + rtengine::JaggedArray tmpIThr(fullTileSize, fullTileSize); + rtengine::JaggedArray tmpThr(fullTileSize, fullTileSize); + rtengine::JaggedArray lumThr(fullTileSize, fullTileSize); +#pragma omp for schedule(dynamic,2) collapse(2) + for (int i = border; i < H - border; i+= tileSize) { + for(int j = border; j < W - border; j+= tileSize) { + const bool endOfCol = (i + tileSize + border) >= H; + const bool endOfRow = (j + tileSize + border) >= W; + // fill tiles + if (endOfRow || endOfCol) { + // special handling for small tiles at end of row or column + for (int k = 0, ii = endOfCol ? H - fullTileSize : i; k < fullTileSize; ++k, ++ii) { + for (int l = 0, jj = endOfRow ? W - fullTileSize : j; l < fullTileSize; ++l, ++jj) { + tmpIThr[k][l] = oldLuminance[ii - border][jj - border]; + lumThr[k][l] = oldLuminance[ii - border][jj - border]; + } + } + } else { + for (int ii = i; ii < i + fullTileSize; ++ii) { + for (int jj = j; jj < j + fullTileSize; ++jj) { + tmpIThr[ii - i][jj - j] = oldLuminance[ii - border][jj - border]; + lumThr[ii - i][jj - j] = oldLuminance[ii - border][jj - border]; + } + } + } + if (is3x3) { + for (int k = 0; k < iterations; ++k) { + // apply 3x3 gaussian blur and divide luminance by result of gaussian blur + gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel3); + gauss3x3mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel3); + } + } else if (is5x5) { + for (int k = 0; k < iterations; ++k) { + // apply 5x5 gaussian blur and divide luminance by result of gaussian blur + gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel5); + 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 (endOfRow || endOfCol) { + // special handling for small tiles at end of row or column + for (int k = border, ii = endOfCol ? H - fullTileSize - border : i - border; k < fullTileSize - border; ++k) { + for (int l = border, jj = endOfRow ? W - fullTileSize - border : j - border; l < fullTileSize - border; ++l) { + luminance[ii + k][jj + l] = rtengine::intp(blend[ii + k][jj + l], max(tmpIThr[k][l], 0.0f), luminance[ii + k][jj + l]); + } + } + } else { + for (int ii = border; ii < fullTileSize - border; ++ii) { + for (int jj = border; jj < fullTileSize - border; ++jj) { + luminance[i + ii - border][j + jj - border] = rtengine::intp(blend[i + ii - border][j + jj - border], max(tmpIThr[ii][jj], 0.0f), luminance[i + ii - border][j + jj - border]); + } + } + } + if (plistener) { + if (++progresscounter % 16 == 0) { #ifdef _OPENMP - #pragma omp for + #pragma omp critical(csprogress) #endif - for (int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - tmpI[i][j] = max(luminance[i][j], 0.f); + { + progress += 16.0 * progressStep; + progress = rtengine::min(progress, endVal); + plistener->setProgress(progress); + } + } + } } } - - for (int k = 0; k < iterations; k++) { - // apply gaussian blur and divide luminance by result of gaussian blur - gaussianBlur(tmpI, tmp, W, H, sigma, nullptr, GAUSS_DIV, luminance); - gaussianBlur(tmp, tmpI, W, H, sigma, nullptr, GAUSS_MULT); - if (plistener) { -#ifdef _OPENMP - #pragma omp single -#endif - start += step; - plistener->setProgress(start); - } - } // end for - -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < H; ++i) { - for (int j = 0; j < W; ++j) { - luminance[i][j] = rtengine::intp(blend[i][j], max(tmpI[i][j], 0.0f), luminance[i][j]); - } - } - } // end parallel + } } } @@ -328,7 +638,7 @@ void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams plistener->setProgressStr(M("TP_PDSHARPENING_LABEL")); plistener->setProgress(0.0); } - +BENCHFUN const float xyz_rgb[3][3] = { // XYZ from RGB { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, @@ -442,13 +752,14 @@ void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams array2D& L = Lbuffer ? *Lbuffer : red; array2D& YOld = YOldbuffer ? * YOldbuffer : green; array2D& YNew = YNewbuffer ? * YNewbuffer : blue; + const float gamma = sharpeningParams.gamma; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < H; ++i) { Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); - Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], sharpeningParams.gamma, W); + Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], gamma, W); } if (plistener) { plistener->setProgress(0.1); @@ -461,12 +772,10 @@ void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams } conrastThreshold = contrast * 100.f; - array2D& tmp = L; // L is not used anymore now => we can use its buffer as the needed temporary buffer - CaptureDeconvSharpening(YNew, tmp, blend, W, H, radius, sharpeningParams.deconviter, plistener, 0.2, (0.9 - 0.2) / sharpeningParams.deconviter); + CaptureDeconvSharpening(YNew, YOld, blend, W, H, radius, sharpeningParams.deconviter, plistener, 0.2, 0.9); if (plistener) { plistener->setProgress(0.9); } - const float gamma = sharpeningParams.gamma; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc index 4afd8ac73..dd7783c1d 100644 --- a/rtengine/rt_algo.cc +++ b/rtengine/rt_algo.cc @@ -394,7 +394,7 @@ void buildBlendMask(const float* const * luminance, float **blend, int W, int H, } } - contrastThreshold = minvar <= 4.f ? calcContrastThreshold(luminance, topLeftYStart + minI, topLeftXStart + minJ, tilesize) : 0.f; + contrastThreshold = minvar <= 8.f ? calcContrastThreshold(luminance, topLeftYStart + minI, topLeftXStart + minJ, tilesize) : 0.f; } } } From aadeb539a92b1729fa8a8a2d7b4a0b2d71682dfd Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 14 Sep 2019 17:51:28 +0200 Subject: [PATCH 182/222] Capture sharpening: small speedup, also reduced memory usage by width * height * 4 byte --- rtengine/capturesharpening.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index ef35695f3..4bfe91aba 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -765,7 +765,7 @@ BENCHFUN plistener->setProgress(0.1); } // calculate contrast based blend factors to reduce sharpening in regions with low contrast - JaggedArray blend(W, H); + array2D& blend = clipMask; // we can share blend and clipMask buffer here buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast, clipMask); if (plistener) { plistener->setProgress(0.2); From 51daaf5fa1e4e75a3e225dd4b3f98ab8cfa64c89 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 14 Sep 2019 19:35:19 +0200 Subject: [PATCH 183/222] Capture Sharpening: some code cleanups --- rtengine/capturesharpening.cc | 58 ++++++++++++++--------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 4bfe91aba..8d9ee5b64 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -19,7 +19,6 @@ #include #include -#include "jaggedarray.h" #include "rtengine.h" #include "rawimagesource.h" #include "rt_math.h" @@ -121,18 +120,12 @@ inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RES } dst[i][W - 1] = 1.f; } - // first and last rows - { - for (int i = 0; i < 1; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } - } - for (int i = H - 1 ; i < H; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } - } + // first and last row + for (int j = 0; j < W; ++j) { + dst[0][j] = 1.f; + } + for (int j = 0; j < W; ++j) { + dst[H - 1][j] = 1.f; } } @@ -161,16 +154,14 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES } // first and last rows - { - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; } - for (int i = H - 2 ; i < H; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } + } + for (int i = H - 2 ; i < H; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; } } } @@ -206,16 +197,14 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST } // first and last rows - { - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; } - for (int i = H - 3 ; i < H; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } + } + for (int i = H - 3 ; i < H; ++i) { + for (int j = 0; j < W; ++j) { + dst[i][j] = 1.f; } } } @@ -300,7 +289,6 @@ void buildClipMaskBayer(const float * const *rawData, int W, int H, float** clip clipMask[row][col] = 1.f; } } - #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif @@ -552,9 +540,9 @@ BENCHFUN #endif { int progresscounter = 0; - rtengine::JaggedArray tmpIThr(fullTileSize, fullTileSize); - rtengine::JaggedArray tmpThr(fullTileSize, fullTileSize); - rtengine::JaggedArray lumThr(fullTileSize, fullTileSize); + array2D tmpIThr(fullTileSize, fullTileSize); + array2D tmpThr(fullTileSize, fullTileSize); + array2D lumThr(fullTileSize, fullTileSize); #pragma omp for schedule(dynamic,2) collapse(2) for (int i = border; i < H - border; i+= tileSize) { for(int j = border; j < W - border; j+= tileSize) { From 19e01124952069794dbfc980e4e0a315566fdd83 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 15 Sep 2019 12:55:20 +0200 Subject: [PATCH 184/222] xtrans: border artifacts when using 1-pass Markesteijn, fixes #5452 --- rtengine/xtrans_demosaic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index e84b5217e..9a3b341cc 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -959,7 +959,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, free(buffer); } - xtransborder_interpolate(8, red, green, blue); + xtransborder_interpolate(passes > 1 ? 8 : 11, red, green, blue); } #undef CLIP void RawImageSource::fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue) From a06c2714e27a7415554fc036c7749bc209f33f2a Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 15 Sep 2019 16:29:29 +0200 Subject: [PATCH 185/222] Update capturesharpening.cc Fix artifacts at radius > 0.85 --- rtengine/capturesharpening.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 8d9ee5b64..df2b1d908 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -530,7 +530,7 @@ BENCHFUN } constexpr int tileSize = 194; - constexpr int border = 3; + constexpr int border = 5; constexpr int fullTileSize = tileSize + 2 * border; double progress = startVal; From 0c1c2152622fbbc09f3fac99cf4687fdf77b0fff Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 15 Sep 2019 21:57:17 +0200 Subject: [PATCH 186/222] Improve readability of hasselblad_load_raw() code, #5434 --- rtengine/dcraw.cc | 121 +++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 51 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index e15a2bb0f..5e85b1e2e 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2417,59 +2417,78 @@ void CLASS hasselblad_correct() void CLASS hasselblad_load_raw() { - struct jhead jh; - int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; - unsigned upix, urow, ucol; - ushort *ip; + struct jhead jh; + int *back[5], diff[12]; - if (!ljpeg_start (&jh, 0)) return; - order = 0x4949; - ph1_bithuff_t ph1_bithuff(this, ifp, order); - hb_bits(-1); - back[4] = (int *) calloc (raw_width, 3*sizeof **back); - merror (back[4], "hasselblad_load_raw()"); - FORC3 back[c] = back[4] + c*raw_width; - cblack[6] >>= sh = tiff_samples > 1; - shot = LIM(shot_select, 1, tiff_samples) - 1; - for (row=0; row < raw_height; row++) { - FORC4 back[(c+3) & 3] = back[c]; - for (col=0; col < raw_width; col+=2) { - for (s=0; s < tiff_samples*2; s+=2) { - FORC(2) len[c] = ph1_huff(jh.huff[0]); - FORC(2) { - diff[s+c] = hb_bits(len[c]); - if ((diff[s+c] & (1 << (len[c]-1))) == 0) - diff[s+c] -= (1 << len[c]) - 1; - if (diff[s+c] == 65535) diff[s+c] = -32768; - } - } - for (s=col; s < col+2; s++) { - pred = 0x8000 + load_flags; - if (col) pred = back[2][s-2]; - if (col && row > 1) switch (jh.psv) { - case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; - } - f = (row & 1)*3 ^ ((col+s) & 1); - FORC (tiff_samples) { - pred += diff[(s & 1)*tiff_samples+c]; - upix = pred >> sh & 0xffff; - if (raw_image && c == shot) - RAW(row,s) = upix; - if (image) { - urow = row-top_margin + (c & 1); - ucol = col-left_margin - ((c >> 1) & 1); - ip = &image[urow*width+ucol][f]; - if (urow < height && ucol < width) - *ip = c < 4 ? upix : (*ip + upix) >> 1; - } - } - back[2][s] = pred; - } + if (!ljpeg_start (&jh, 0)) { + return; + } + order = 0x4949; + ph1_bithuff_t ph1_bithuff(this, ifp, order); + hb_bits(-1); + back[4] = (int *) calloc(raw_width, 3 * sizeof **back); + merror(back[4], "hasselblad_load_raw()"); + for (int c = 0; c < 3; ++c) { + back[c] = back[4] + c * raw_width; + } + const int sh = tiff_samples > 1; + cblack[6] >>= sh; + const int shot = LIM(shot_select, 1, tiff_samples) - 1; + for (int row = 0; row < raw_height; ++row) { + for (int c = 0; c < 4; ++c) { + back[(c + 3) & 3] = back[c]; + } + for (int col = 0; col < raw_width; col += 2) { + for (int s = 0; s < tiff_samples * 2; s += 2) { + int len[2]; + for (int c = 0; c < 2; ++c) { + len[c] = ph1_huff(jh.huff[0]); + } + for (int c = 0; c < 2; ++c) { + diff[s + c] = hb_bits(len[c]); + if ((diff[s + c] & (1 << (len[c] - 1))) == 0) { + diff[s + c] -= (1 << len[c]) - 1; + } + if (diff[s + c] == 65535) { + diff[s + c] = -32768; + } + } + } + for (int s = col; s < col + 2; ++s) { + int pred; + if (col) { + pred = back[2][s - 2]; + if (row > 1 && jh.psv == 11) { + pred += back[0][s] / 2 - back[0][s - 2] / 2; + } + } else { + pred = 0x8000 + load_flags; + } + for (int c = 0; c < tiff_samples; ++c) { + pred += diff[(s & 1) * tiff_samples + c]; + const unsigned upix = pred >> sh & 0xffff; + if (raw_image && c == shot) { + RAW(row, s) = upix; + } + if (image) { + const int f = (row & 1) * 3 ^ ((col + s) & 1); + const unsigned urow = row - top_margin + (c & 1); + const unsigned ucol = col - left_margin - ((c >> 1) & 1); + ushort* const ip = &image[urow * width + ucol][f]; + if (urow < height && ucol < width) { + *ip = c < 4 ? upix : (*ip + upix) >> 1; + } + } + } + back[2][s] = pred; + } + } + } + free(back[4]); + ljpeg_end(&jh); + if (image) { + mix_green = 1; } - } - free (back[4]); - ljpeg_end (&jh); - if (image) mix_green = 1; } void CLASS leaf_hdr_load_raw() From f55afb91c306c3449f579bff0f1f6cfdcde8c831 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 15 Sep 2019 22:30:03 +0200 Subject: [PATCH 187/222] Soft Light: remove benchmark code, closes #5447 --- rtengine/ipsoftlight.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/rtengine/ipsoftlight.cc b/rtengine/ipsoftlight.cc index 556790eb4..cd49e858f 100644 --- a/rtengine/ipsoftlight.cc +++ b/rtengine/ipsoftlight.cc @@ -22,8 +22,6 @@ #include "improcfun.h" #include "procparams.h" -#define BENCHMARK -#include "StopWatch.h" namespace { @@ -60,7 +58,6 @@ void rtengine::ImProcFunctions::softLight(LabImage *lab) if (!params->softlight.enabled || !params->softlight.strength) { return; } - BENCHFUN const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); const float wp[3][3] = { From f2cdbd0e4dabc1878f36a6b35c88132b8c561901 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 16 Sep 2019 15:09:47 +0200 Subject: [PATCH 188/222] Capture sharpening: experimental radius offset depending on distance to center --- rtdata/languages/default | 1 + rtengine/capturesharpening.cc | 30 ++++++++++++++++++++++-------- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 8 +++++++- rtgui/paramsedited.h | 1 + rtgui/pdsharpening.cc | 22 ++++++++++++++++++++-- rtgui/pdsharpening.h | 2 ++ 8 files changed, 58 insertions(+), 11 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3749a706a..be1638e8e 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2037,6 +2037,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/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/procparams.cc b/rtengine/procparams.cc index f88220c4e..639a9e3d3 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; } @@ -3375,6 +3377,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 @@ -4465,6 +4468,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 ce03efc7d..ec529ee06 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/paramsedited.cc b/rtgui/paramsedited.cc index 2ab5702ea..b2b51f38a 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; @@ -756,6 +757,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; @@ -1746,6 +1748,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; } @@ -3295,5 +3301,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 1bd7170d4..b83fbf568 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; From 7956f6f786e4ddfcc0080cf8807300da5f8068b3 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 16 Sep 2019 15:29:26 +0200 Subject: [PATCH 189/222] Enable Capture sharpening for * ISO Low.pp3, #5412 --- rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 | 3 +++ rtdata/profiles/Standard Film Curve - ISO Low.pp3 | 3 +++ 2 files changed, 6 insertions(+) diff --git a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 index 882c0130f..ee620398a 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 \ No newline at end of file diff --git a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 index c23b5b8a4..de7787827 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 \ No newline at end of file From c7400459f056125cf5072cbec2d4a697c331c85f Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 16 Sep 2019 15:51:47 +0200 Subject: [PATCH 190/222] Update Auto-Matched Curve - ISO Low.pp3 --- rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 index ee620398a..c94077b21 100644 --- a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 +++ b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 @@ -23,4 +23,4 @@ DCPIlluminant=0 CA=true [PostDemosaicSharpening] -Enabled=true \ No newline at end of file +Enabled=true From 6d9e7d58988e1c554e8f7d3450fd571477cd6124 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 16 Sep 2019 15:52:11 +0200 Subject: [PATCH 191/222] Update Standard Film Curve - ISO Low.pp3 --- rtdata/profiles/Standard Film Curve - ISO Low.pp3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 index de7787827..45fcca730 100644 --- a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 +++ b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 @@ -25,4 +25,4 @@ DCPIlluminant=0 CA=true [PostDemosaicSharpening] -Enabled=true \ No newline at end of file +Enabled=true From 796e8f02896c0506dd9c403572adabf80187e03b Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 16 Sep 2019 17:17:49 +0200 Subject: [PATCH 192/222] Removed timing code --- rtengine/iptransform.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 1e739dac6..1a38d8e2f 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -31,9 +31,6 @@ #include "rtlensfun.h" #include "sleef.c" -#define BENCHMARK -#include "StopWatch.h" - using namespace std; namespace @@ -854,7 +851,6 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat* void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap) { - BENCHFUN // set up stuff, depending on the mode we are const bool enableLCPDist = pLCPMap && params->lensProf.useDist; const bool enableCA = highQuality && needsCA(); From a0c6c1569c1f7574952341e4be4a8a0859ba811a Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 16 Sep 2019 21:43:03 +0200 Subject: [PATCH 193/222] Fix indentations --- rtengine/dcraw.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 5e85b1e2e..5275c42c1 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2441,9 +2441,9 @@ void CLASS hasselblad_load_raw() for (int col = 0; col < raw_width; col += 2) { for (int s = 0; s < tiff_samples * 2; s += 2) { int len[2]; - for (int c = 0; c < 2; ++c) { - len[c] = ph1_huff(jh.huff[0]); - } + for (int c = 0; c < 2; ++c) { + len[c] = ph1_huff(jh.huff[0]); + } for (int c = 0; c < 2; ++c) { diff[s + c] = hb_bits(len[c]); if ((diff[s + c] & (1 << (len[c] - 1))) == 0) { @@ -2455,15 +2455,15 @@ void CLASS hasselblad_load_raw() } } for (int s = col; s < col + 2; ++s) { - int pred; - if (col) { + int pred; + if (col) { pred = back[2][s - 2]; if (row > 1 && jh.psv == 11) { pred += back[0][s] / 2 - back[0][s - 2] / 2; } - } else { - pred = 0x8000 + load_flags; - } + } else { + pred = 0x8000 + load_flags; + } for (int c = 0; c < tiff_samples; ++c) { pred += diff[(s & 1) * tiff_samples + c]; const unsigned upix = pred >> sh & 0xffff; From 991fc94d89e08ce625256ca4a146d7151ae5c5fd Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 17 Sep 2019 15:11:12 +0200 Subject: [PATCH 194/222] Speedup for guided filter --- rtengine/guidedfilter.cc | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/rtengine/guidedfilter.cc b/rtengine/guidedfilter.cc index 0ebe6c172..bc7f64f05 100644 --- a/rtengine/guidedfilter.cc +++ b/rtengine/guidedfilter.cc @@ -207,9 +207,6 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 apply(SUBMUL, b, a, meanI, meanp); DEBUG_DUMP(b); - meanI.free(); // frees w * h * 4 byte - meanp.free(); // frees w * h * 4 byte - array2D &meana = a; f_mean(meana, a, r1); DEBUG_DUMP(meana); @@ -218,18 +215,25 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 f_mean(meanb, b, r1); DEBUG_DUMP(meanb); - blur_buf.resize(0); // frees w * h * 4 byte + const int Ws = meana.width(); + const int Hs = meana.height(); + const int Wd = q.width(); + const int Hd = q.height(); - array2D meanA(W, H); - f_upsample(meanA, meana); - DEBUG_DUMP(meanA); + float col_scale = float (Ws) / float (Wd); + float row_scale = float (Hs) / float (Hd); - array2D &meanB = q; - f_upsample(meanB, meanb); - DEBUG_DUMP(meanB); +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif - apply(ADDMUL, q, meanA, I, meanB); - DEBUG_DUMP(q); + for (int y = 0; y < Hd; ++y) { + float ymrs = y * row_scale; + + for (int x = 0; x < Wd; ++x) { + q[y][x] = getBilinearValue(meana, x * col_scale, ymrs) * I[y][x] + getBilinearValue(meanb, x * col_scale, ymrs); + } + } } } // namespace rtengine From c0aa982fdda7cef7edbf9ded52273a3e91936a7c Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Wed, 18 Sep 2019 21:32:35 +0200 Subject: [PATCH 195/222] Fixed sampling loop ranges in `channelsAvg`. It was effectively doubling `spotSize`, sampling an area of 64x64 instead of 32x32. --- rtengine/filmnegativeproc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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]; From 3ab379ad0a3871f4cd8b1ce933dfa7a8d37b001b Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 19 Sep 2019 20:56:33 +0200 Subject: [PATCH 196/222] Dehaze: further speedup, #5456 --- rtengine/boxblur.h | 255 +++++++++++++++++++++++++++++++++++--- rtengine/guidedfilter.cc | 187 ++++++++++------------------ rtengine/ipdehaze.cc | 260 +++++++++++++++++++++------------------ 3 files changed, 442 insertions(+), 260 deletions(-) diff --git a/rtengine/boxblur.h b/rtengine/boxblur.h index da302964b..3020278b2 100644 --- a/rtengine/boxblur.h +++ b/rtengine/boxblur.h @@ -204,15 +204,15 @@ template void boxblur (T** src, A** dst, T* buffer, int radx, tempv = tempv / lenv; temp1v = temp1v / lenv; - STVFU( dst[0][col], tempv); - STVFU( dst[0][col + 4], temp1v); + STVFU(dst[0][col], tempv); + STVFU(dst[0][col + 4], temp1v); for (int row = 1; row <= rady; row++) { lenp1v = lenv + onev; tempv = (tempv * lenv + LVFU(temp[(row + rady) * W + col])) / lenp1v; temp1v = (temp1v * lenv + LVFU(temp[(row + rady) * W + col + 4])) / lenp1v; - STVFU( dst[row][col], tempv); - STVFU( dst[row][col + 4], temp1v); + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); lenv = lenp1v; } @@ -221,16 +221,16 @@ template void boxblur (T** src, A** dst, T* buffer, int radx, for (int row = rady + 1; row < H - rady; row++) { tempv = tempv + (LVFU(temp[(row + rady) * W + col]) - LVFU(temp[(row - rady - 1) * W + col])) * rlenv ; temp1v = temp1v + (LVFU(temp[(row + rady) * W + col + 4]) - LVFU(temp[(row - rady - 1) * W + col + 4])) * rlenv ; - STVFU( dst[row][col], tempv); - STVFU( dst[row][col + 4], temp1v); + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); } for (int row = H - rady; row < H; row++) { lenm1v = lenv - onev; tempv = (tempv * lenv - LVFU(temp[(row - rady - 1) * W + col])) / lenm1v; temp1v = (temp1v * lenv - LVFU(temp[(row - rady - 1) * W + col + 4])) / lenm1v; - STVFU( dst[row][col], tempv); - STVFU( dst[row][col + 4], temp1v); + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); lenv = lenm1v; } } @@ -312,6 +312,221 @@ template void boxblur (T** src, A** dst, T* buffer, int radx, } +inline void boxblur (float** src, float** dst, int radius, int W, int H, bool multiThread) +{ + //box blur using rowbuffers and linebuffers instead of a full size buffer + + if (radius == 0) { + if (src != dst) { +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + dst[row][col] = src[row][col]; + } + } + } + return; + } + + constexpr int numCols = 8; // process numCols columns at once for better usage of L1 cpu cache +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { + float* const buffer = new float[std::max(W, 8 * H)]; + //horizontal blur + float* const lineBuffer = buffer; +#ifdef _OPENMP + #pragma omp for +#endif + for (int row = 0; row < H; row++) { + float len = radius + 1; + float tempval = src[row][0]; + lineBuffer[0] = tempval; + for (int j = 1; j <= radius; j++) { + tempval += src[row][j]; + } + + tempval /= len; + dst[row][0] = tempval; + + for (int col = 1; col <= radius; col++) { + lineBuffer[col] = src[row][col]; + dst[row][col] = tempval = (tempval * len + src[row][col + radius]) / (len + 1); + len ++; + } + + for (int col = radius + 1; col < W - radius; col++) { + lineBuffer[col] = src[row][col]; + dst[row][col] = tempval = tempval + (src[row][col + radius] - lineBuffer[col - radius - 1]) / len; + } + + for (int col = W - radius; col < W; col++) { + dst[row][col] = tempval = (tempval * len - lineBuffer[col - radius - 1]) / (len - 1); + len --; + } + } + + //vertical blur +#ifdef __SSE2__ + vfloat (* const rowBuffer)[2] = (vfloat(*)[2]) buffer; + vfloat leninitv = F2V(radius + 1); + vfloat onev = F2V(1.f); + vfloat tempv, temp1v, lenv, lenp1v, lenm1v, rlenv; + +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int col = 0; col < W - 7; col += 8) { + lenv = leninitv; + tempv = LVFU(dst[0][col]); + temp1v = LVFU(dst[0][col + 4]); + rowBuffer[0][0] = tempv; + rowBuffer[0][1] = temp1v; + + for (int i = 1; i <= radius; i++) { + tempv = tempv + LVFU(dst[i][col]); + temp1v = temp1v + LVFU(dst[i][col + 4]); + } + + tempv = tempv / lenv; + temp1v = temp1v / lenv; + STVFU(dst[0][col], tempv); + STVFU(dst[0][col + 4], temp1v); + + for (int row = 1; row <= radius; row++) { + rowBuffer[row][0] = LVFU(dst[row][col]); + rowBuffer[row][1] = LVFU(dst[row][col + 4]); + lenp1v = lenv + onev; + tempv = (tempv * lenv + LVFU(dst[row + radius][col])) / lenp1v; + temp1v = (temp1v * lenv + LVFU(dst[row + radius][col + 4])) / lenp1v; + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); + lenv = lenp1v; + } + + rlenv = onev / lenv; + + for (int row = radius + 1; row < H - radius; row++) { + rowBuffer[row][0] = LVFU(dst[row][col]); + rowBuffer[row][1] = LVFU(dst[row][col + 4]); + tempv = tempv + (LVFU(dst[row + radius][col]) - rowBuffer[row - radius - 1][0]) * rlenv ; + temp1v = temp1v + (LVFU(dst[row + radius][col + 4]) - rowBuffer[row - radius - 1][1]) * rlenv ; + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); + } + + for (int row = H - radius; row < H; row++) { + lenm1v = lenv - onev; + tempv = (tempv * lenv - rowBuffer[row - radius - 1][0]) / lenm1v; + temp1v = (temp1v * lenv - rowBuffer[row - radius - 1][1]) / lenm1v; + STVFU(dst[row][col], tempv); + STVFU(dst[row][col + 4], temp1v); + lenv = lenm1v; + } + } + +#else + float (* const rowBuffer)[8] = (float(*)[8]) buffer; +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int col = 0; col < W - numCols + 1; col += 8) { + float len = radius + 1; + + for(int k = 0; k < numCols; k++) { + rowBuffer[0][k] = dst[0][col + k]; + } + + for (int i = 1; i <= radius; i++) { + for(int k = 0; k < numCols; k++) { + dst[0][col + k] += dst[i][col + k]; + } + } + + for(int k = 0; k < numCols; k++) { + dst[0][col + k] /= len; + } + + for (int row = 1; row <= radius; row++) { + for(int k = 0; k < numCols; k++) { + rowBuffer[row][k] = dst[row][col + k]; + dst[row][col + k] = (dst[row - 1][col + k] * len + dst[row + radius][col + k]) / (len + 1); + } + + len ++; + } + + for (int row = radius + 1; row < H - radius; row++) { + for(int k = 0; k < numCols; k++) { + rowBuffer[row][k] = dst[row][col + k]; + dst[row][col + k] = dst[row - 1][col + k] + (dst[row + radius][col + k] - rowBuffer[row - radius - 1][k]) / len; + } + } + + for (int row = H - radius; row < H; row++) { + for(int k = 0; k < numCols; k++) { + dst[row][col + k] = (dst[row - 1][col + k] * len - rowBuffer[row - radius - 1][k]) / (len - 1); + } + + len --; + } + } + +#endif + //vertical blur, remaining columns +#ifdef _OPENMP + #pragma omp single +#endif + { + const int remaining = W % numCols; + if (remaining > 0) { + float (* const rowBuffer)[8] = (float(*)[8]) buffer; + const int col = W - remaining; + + float len = radius + 1; + for(int k = 0; k < remaining; k++) { + rowBuffer[0][k] = dst[0][col + k]; + } + for (int i = 1; i <= radius; i++) { + for(int k = 0; k < remaining; k++) { + dst[0][col + k] += dst[i][col + k]; + } + } + for(int k = 0; k < remaining; k++) { + dst[0][col + k] /= len; + } + for (int row = 1; row <= radius; row++) { + for(int k = 0; k < remaining; k++) { + rowBuffer[row][k] = dst[row][col + k]; + dst[row][col + k] = (dst[(row - 1)][col + k] * len + dst[row + radius][col + k]) / (len + 1); + len ++; + } + } + const float rlen = 1.f / len; + for (int row = radius + 1; row < H - radius; row++) { + for(int k = 0; k < remaining; k++) { + rowBuffer[row][k] = dst[row][col + k]; + dst[row][col + k] = dst[(row - 1)][col + k] + (dst[row + radius][col + k] - rowBuffer[row - radius - 1][k]) * rlen; + } + } + for (int row = H - radius; row < H; row++) { + for(int k = 0; k < remaining; k++) { + dst[row][col + k] = (dst[(row - 1)][col + k] * len - rowBuffer[row - radius - 1][k]) / (len - 1); + len --; + } + } + } + } + delete [] buffer; + } +} + template void boxblur (T* src, A* dst, A* buffer, int radx, int rady, int W, int H) { //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) @@ -382,15 +597,15 @@ template void boxblur (T* src, A* dst, A* buffer, int radx, in tempv = tempv / lenv; temp1v = temp1v / lenv; - STVFU( dst[0 * W + col], tempv); - STVFU( dst[0 * W + col + 4], temp1v); + STVFU(dst[0 * W + col], tempv); + STVFU(dst[0 * W + col + 4], temp1v); for (int row = 1; row <= rady; row++) { lenp1v = lenv + onev; tempv = (tempv * lenv + LVFU(temp[(row + rady) * W + col])) / lenp1v; temp1v = (temp1v * lenv + LVFU(temp[(row + rady) * W + col + 4])) / lenp1v; - STVFU( dst[row * W + col], tempv); - STVFU( dst[row * W + col + 4], temp1v); + STVFU(dst[row * W + col], tempv); + STVFU(dst[row * W + col + 4], temp1v); lenv = lenp1v; } @@ -399,16 +614,16 @@ template void boxblur (T* src, A* dst, A* buffer, int radx, in for (int row = rady + 1; row < H - rady; row++) { tempv = tempv + (LVFU(temp[(row + rady) * W + col]) - LVFU(temp[(row - rady - 1) * W + col])) * rlenv ; temp1v = temp1v + (LVFU(temp[(row + rady) * W + col + 4]) - LVFU(temp[(row - rady - 1) * W + col + 4])) * rlenv ; - STVFU( dst[row * W + col], tempv); - STVFU( dst[row * W + col + 4], temp1v); + STVFU(dst[row * W + col], tempv); + STVFU(dst[row * W + col + 4], temp1v); } for (int row = H - rady; row < H; row++) { lenm1v = lenv - onev; tempv = (tempv * lenv - LVFU(temp[(row - rady - 1) * W + col])) / lenm1v; temp1v = (temp1v * lenv - LVFU(temp[(row - rady - 1) * W + col + 4])) / lenm1v; - STVFU( dst[row * W + col], tempv); - STVFU( dst[row * W + col + 4], temp1v); + STVFU(dst[row * W + col], tempv); + STVFU(dst[row * W + col + 4], temp1v); lenv = lenm1v; } } @@ -422,12 +637,12 @@ template void boxblur (T* src, A* dst, A* buffer, int radx, in } tempv = tempv / lenv; - STVFU( dst[0 * W + col], tempv); + STVFU(dst[0 * W + col], tempv); for (int row = 1; row <= rady; row++) { lenp1v = lenv + onev; tempv = (tempv * lenv + LVFU(temp[(row + rady) * W + col])) / lenp1v; - STVFU( dst[row * W + col], tempv); + STVFU(dst[row * W + col], tempv); lenv = lenp1v; } @@ -435,13 +650,13 @@ template void boxblur (T* src, A* dst, A* buffer, int radx, in for (int row = rady + 1; row < H - rady; row++) { tempv = tempv + (LVFU(temp[(row + rady) * W + col]) - LVFU(temp[(row - rady - 1) * W + col])) * rlenv ; - STVFU( dst[row * W + col], tempv); + STVFU(dst[row * W + col], tempv); } for (int row = H - rady; row < H; row++) { lenm1v = lenv - onev; tempv = (tempv * lenv - LVFU(temp[(row - rady - 1) * W + col])) / lenm1v; - STVFU( dst[row * W + col], tempv); + STVFU(dst[row * W + col], tempv); lenv = lenm1v; } } diff --git a/rtengine/guidedfilter.cc b/rtengine/guidedfilter.cc index bc7f64f05..8d19fc7a5 100644 --- a/rtengine/guidedfilter.cc +++ b/rtengine/guidedfilter.cc @@ -3,6 +3,7 @@ * This file is part of RawTherapee. * * Copyright (c) 2018 Alberto Griggio + * Optimized 2019 Ingo Weyrich * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,9 +17,9 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ +*/ -/** +/* * This is a Fast Guided Filter implementation, derived directly from the * pseudo-code of the paper: * @@ -26,32 +27,16 @@ * by Kaiming He, Jian Sun * * available at https://arxiv.org/abs/1505.00996 - */ +*/ #include "guidedfilter.h" #include "boxblur.h" #include "rescale.h" #include "imagefloat.h" - +#define BENCHMARK +#include "StopWatch.h" namespace rtengine { -#if 0 -# define DEBUG_DUMP(arr) \ - do { \ - Imagefloat im(arr.width(), arr.height()); \ - const char *out = "/tmp/" #arr ".tif"; \ - for (int y = 0; y < im.getHeight(); ++y) { \ - for (int x = 0; x < im.getWidth(); ++x) { \ - im.r(y, x) = im.g(y, x) = im.b(y, x) = arr[y][x] * 65535.f; \ - } \ - } \ - im.saveTIFF(out, 16); \ - } while (false) -#else -# define DEBUG_DUMP(arr) -#endif - - namespace { int calculate_subsampling(int w, int h, int r) @@ -78,15 +63,7 @@ int calculate_subsampling(int w, int h, int r) void guidedFilter(const array2D &guide, const array2D &src, array2D &dst, int r, float epsilon, bool multithread, int subsampling) { - - const int W = src.width(); - const int H = src.height(); - - if (subsampling <= 0) { - subsampling = calculate_subsampling(W, H, r); - } - - enum Op { MUL, DIVEPSILON, ADD, SUB, ADDMUL, SUBMUL }; + enum Op {MUL, DIVEPSILON, SUBMUL}; const auto apply = [=](Op op, array2D &res, const array2D &a, const array2D &b, const array2D &c=array2D()) -> void @@ -99,139 +76,107 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 #endif for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { - float r; - float aa = a[y][x]; - float bb = b[y][x]; switch (op) { - case MUL: - r = aa * bb; - break; - case DIVEPSILON: - r = aa / (bb + epsilon); - break; - case ADD: - r = aa + bb; - break; - case SUB: - r = aa - bb; - break; - case ADDMUL: - r = aa * bb + c[y][x]; - break; - case SUBMUL: - r = c[y][x] - (aa * bb); - break; - default: - assert(false); - r = 0; - break; + case MUL: + res[y][x] = a[y][x] * b[y][x]; + break; + case DIVEPSILON: + res[y][x] = a[y][x] / (b[y][x] + epsilon); // note: the value of epsilon intentionally has an impact on the result. It is not only to avoid divisions by zero + break; + case SUBMUL: + res[y][x] = c[y][x] - (a[y][x] * b[y][x]); + break; + default: + assert(false); + res[y][x] = 0; + break; } - res[y][x] = r; } } }; - // use the terminology of the paper (Algorithm 2) - const array2D &I = guide; - const array2D &p = src; - array2D &q = dst; - const auto f_subsample = [=](array2D &d, const array2D &s) -> void { rescaleBilinear(s, d, multithread); }; - const auto f_upsample = f_subsample; - - const size_t w = W / subsampling; - const size_t h = H / subsampling; - - AlignedBuffer blur_buf(w * h); const auto f_mean = [&](array2D &d, array2D &s, int rad) -> void { rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1); - float **src = s; - float **dst = d; -#ifdef _OPENMP - #pragma omp parallel if (multithread) -#endif - boxblur(src, dst, blur_buf.data, rad, rad, s.width(), s.height()); + boxblur(s, d, rad, s.width(), s.height(), multithread); }; + const int W = src.width(); + const int H = src.height(); + + if (subsampling <= 0) { + subsampling = calculate_subsampling(W, H, r); + } + + const size_t w = W / subsampling; + const size_t h = H / subsampling; + const float r1 = float(r) / subsampling; + array2D I1(w, h); array2D p1(w, h); - f_subsample(I1, I); - f_subsample(p1, p); + f_subsample(I1, guide); - DEBUG_DUMP(I); - DEBUG_DUMP(p); - DEBUG_DUMP(I1); - DEBUG_DUMP(p1); + if (&guide == &src) { + f_mean(p1, I1, r1); - float r1 = float(r) / subsampling; + apply(MUL, I1, I1, I1); // I1 = I1 * I1 - array2D meanI(w, h); - f_mean(meanI, I1, r1); - DEBUG_DUMP(meanI); + f_mean(I1, I1, r1); - array2D meanp(w, h); - f_mean(meanp, p1, r1); - DEBUG_DUMP(meanp); + apply(SUBMUL, I1, p1, p1, I1); // I1 = I1 - p1 * p1 + apply(DIVEPSILON, I1, I1, I1); // I1 = I1 / (I1 + epsilon) + apply(SUBMUL, p1, I1, p1, p1); // p1 = p1 - I1 * p1 - array2D &corrIp = p1; - apply(MUL, corrIp, I1, p1); - f_mean(corrIp, corrIp, r1); - DEBUG_DUMP(corrIp); + } else { + f_subsample(p1, src); - array2D &corrI = I1; - apply(MUL, corrI, I1, I1); - f_mean(corrI, corrI, r1); - DEBUG_DUMP(corrI); + array2D meanI(w, h); + f_mean(meanI, I1, r1); - array2D &varI = corrI; - apply(SUBMUL, varI, meanI, meanI, corrI); - DEBUG_DUMP(varI); + array2D meanp(w, h); + f_mean(meanp, p1, r1); - array2D &covIp = corrIp; - apply(SUBMUL, covIp, meanI, meanp, corrIp); - DEBUG_DUMP(covIp); + apply(MUL, p1, I1, p1); - array2D &a = varI; - apply(DIVEPSILON, a, covIp, varI); - DEBUG_DUMP(a); + f_mean(p1, p1, r1); - array2D &b = covIp; - apply(SUBMUL, b, a, meanI, meanp); - DEBUG_DUMP(b); + apply(MUL, I1, I1, I1); - array2D &meana = a; - f_mean(meana, a, r1); - DEBUG_DUMP(meana); + f_mean(I1, I1, r1); - array2D &meanb = b; - f_mean(meanb, b, r1); - DEBUG_DUMP(meanb); + apply(SUBMUL, I1, meanI, meanI, I1); + apply(SUBMUL, p1, meanI, meanp, p1); + apply(DIVEPSILON, I1, p1, I1); + apply(SUBMUL, p1, I1, meanI, meanp); + } - const int Ws = meana.width(); - const int Hs = meana.height(); - const int Wd = q.width(); - const int Hd = q.height(); + f_mean(I1, I1, r1); + f_mean(p1, p1, r1); - float col_scale = float (Ws) / float (Wd); - float row_scale = float (Hs) / float (Hd); + const int Ws = I1.width(); + const int Hs = I1.height(); + const int Wd = dst.width(); + const int Hd = dst.height(); + + const float col_scale = static_cast(Ws) / static_cast(Wd); + const float row_scale = static_cast(Hs) / static_cast(Hd); #ifdef _OPENMP #pragma omp parallel for if (multithread) #endif for (int y = 0; y < Hd; ++y) { - float ymrs = y * row_scale; - + const float ymrs = y * row_scale; for (int x = 0; x < Wd; ++x) { - q[y][x] = getBilinearValue(meana, x * col_scale, ymrs) * I[y][x] + getBilinearValue(meanb, x * col_scale, ymrs); + dst[y][x] = getBilinearValue(I1, x * col_scale, ymrs) * guide[y][x] + getBilinearValue(p1, x * col_scale, ymrs); } } } diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 60d4cb9ff..68af84970 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -35,7 +35,10 @@ #include "improcfun.h" #include "procparams.h" #include "rt_algo.h" +#include "rt_algo.h" #include "rt_math.h" +#define BENCHMARK +#include "StopWatch.h" extern Options options; @@ -43,24 +46,7 @@ namespace rtengine { namespace { -#if 0 -# define DEBUG_DUMP(arr) \ - do { \ - Imagefloat im(arr.width(), arr.height()); \ - const char *out = "/tmp/" #arr ".tif"; \ - for (int y = 0; y < im.getHeight(); ++y) { \ - for (int x = 0; x < im.getWidth(); ++x) { \ - im.r(y, x) = im.g(y, x) = im.b(y, x) = arr[y][x] * 65535.f; \ - } \ - } \ - im.saveTIFF(out, 16); \ - } while (false) -#else -# define DEBUG_DUMP(arr) -#endif - - -int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread) +int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength) { const int W = R.width(); const int H = R.height(); @@ -73,22 +59,12 @@ int get_dark_channel(const array2D &R, const array2D &G, const arr for (int x = 0; x < W; x += patchsize) { float val = RT_INFINITY_F; const int pW = min(x + patchsize, W); - for (int yy = y; yy < pH; ++yy) { - for (int xx = x; xx < pW; ++xx) { - float r = R[yy][xx]; - float g = G[yy][xx]; - float b = B[yy][xx]; - if (ambient) { - r /= ambient[0]; - g /= ambient[1]; - b /= ambient[2]; - } - val = min(val, r, g, b); + for (int xx = x; xx < pW; ++xx) { + for (int yy = y; yy < pH; ++yy) { + val = min(val, R[yy][xx] / ambient[0], G[yy][xx] / ambient[1], B[yy][xx] / ambient[2]); } } - if (clip) { - val = LIM01(val); - } + val = 1.f - strength * LIM01(val); for (int yy = y; yy < pH; ++yy) { std::fill(dst[yy] + x, dst[yy] + pW, val); } @@ -98,41 +74,59 @@ int get_dark_channel(const array2D &R, const array2D &G, const arr return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0)); } +int get_dark_channel_downsized(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, bool multithread) +{ + const int W = R.width(); + const int H = R.height(); + +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; y += patchsize) { + int yy = y / patchsize; + const int pH = min(y + patchsize, H); + for (int x = 0, xx = 0; x < W; x += patchsize, ++xx) { + float val = RT_INFINITY_F; + const int pW = min(x + patchsize, W); + for (int xp = x; xp < pW; ++xp) { + for (int yp = y; yp < pH; ++yp) { + val = min(val, R[yp][xp], G[yp][xp], B[yp][xp]); + } + } + dst[yy][xx] = val; + } + } + + return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0)); +} + float estimate_ambient_light(const array2D &R, const array2D &G, const array2D &B, const array2D &dark, int patchsize, int npatches, float ambient[3]) { const int W = R.width(); const int H = R.height(); - const auto get_percentile = - [](std::priority_queue &q, float prcnt) -> float - { - size_t n = LIM(q.size() * prcnt, 1, q.size()); - while (q.size() > n) { - q.pop(); - } - return q.top(); - }; - float darklim = RT_INFINITY_F; { - std::priority_queue p; - for (int y = 0; y < H; y += patchsize) { - for (int x = 0; x < W; x += patchsize) { - if (!OOG(dark[y][x], 1.f - 1e-5f)) { - p.push(dark[y][x]); + std::vector p; + for (int y = 0, yy = 0; y < H; y += patchsize, ++yy) { + for (int x = 0, xx = 0; x < W; x += patchsize, ++xx) { + if (!OOG(dark[yy][xx], 1.f - 1e-5f)) { + p.push_back(dark[yy][xx]); } } } - darklim = get_percentile(p, 0.95); + const int pos = p.size() * 0.95; + std::nth_element(p.begin(), p.begin() + pos, p.end()); + darklim = p[pos]; } std::vector> patches; patches.reserve(npatches); - for (int y = 0; y < H; y += patchsize) { - for (int x = 0; x < W; x += patchsize) { - if (dark[y][x] >= darklim && !OOG(dark[y][x], 1.f)) { + for (int y = 0, yy = 0; y < H; y += patchsize, ++yy) { + for (int x = 0, xx = 0; x < W; x += patchsize, ++xx) { + if (dark[yy][xx] >= darklim && !OOG(dark[yy][xx], 1.f)) { patches.push_back(std::make_pair(x, y)); } } @@ -145,33 +139,38 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c float bright_lim = RT_INFINITY_F; { - std::priority_queue l; + std::vector l; + l.reserve(patches.size() * patchsize * patchsize); - for (auto &p : patches) { - const int pW = min(p.first+patchsize, W); - const int pH = min(p.second+patchsize, H); + for (const auto &p : patches) { + const int pW = min(p.first + patchsize, W); + const int pH = min(p.second + patchsize, H); for (int y = p.second; y < pH; ++y) { for (int x = p.first; x < pW; ++x) { - l.push(R[y][x] + G[y][x] + B[y][x]); + l.push_back(R[y][x] + G[y][x] + B[y][x]); } } } - - bright_lim = get_percentile(l, 0.95); + const int pos = l.size() * 0.95; + std::nth_element(l.begin(), l.begin() + pos, l.end()); + bright_lim = l[pos]; } double rr = 0, gg = 0, bb = 0; int n = 0; - for (auto &p : patches) { - const int pW = min(p.first+patchsize, W); - const int pH = min(p.second+patchsize, H); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic) reduction(+:rr,gg,bb,n) +#endif + for (const auto &p : patches) { + const int pW = min(p.first + patchsize, W); + const int pH = min(p.second + patchsize, H); for (int y = p.second; y < pH; ++y) { for (int x = p.first; x < pW; ++x) { - float r = R[y][x]; - float g = G[y][x]; - float b = B[y][x]; + const float r = R[y][x]; + const float g = G[y][x]; + const float b = B[y][x]; if (r + g + b >= bright_lim) { rr += r; gg += g; @@ -181,6 +180,7 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c } } } + n = std::max(n, 1); ambient[0] = rr / n; ambient[1] = gg / n; @@ -211,12 +211,12 @@ void extract_channels(Imagefloat *img, array2D &r, array2D &g, arr void ImProcFunctions::dehaze(Imagefloat *img) { - if (!params->dehaze.enabled) { + if (!params->dehaze.enabled || params->dehaze.strength == 0.0) { return; } - +BENCHFUN img->normalizeFloatTo1(); - + const int W = img->getWidth(); const int H = img->getHeight(); const float strength = LIM01(float(params->dehaze.strength) / 100.f * 0.9f); @@ -229,21 +229,19 @@ void ImProcFunctions::dehaze(Imagefloat *img) int patchsize = max(int(5 / scale), 2); float ambient[3]; - array2D &t_tilde = dark; float max_t = 0.f; { - int npatches = 0; array2D R(W, H); array2D G(W, H); array2D B(W, H); extract_channels(img, R, G, B, patchsize, 1e-1, multiThread); - - patchsize = max(max(W, H) / 600, 2); - npatches = get_dark_channel(R, G, B, dark, patchsize, nullptr, false, multiThread); - DEBUG_DUMP(dark); - max_t = estimate_ambient_light(R, G, B, dark, patchsize, npatches, ambient); + patchsize = max(max(W, H) / 600, 2); + array2D darkDownsized(W / patchsize + 1, H / patchsize + 1); + const int npatches = get_dark_channel_downsized(R, G, B, darkDownsized, patchsize, multiThread); + + max_t = estimate_ambient_light(R, G, B, darkDownsized, patchsize, npatches, ambient); if (options.rtSettings.verbose) { std::cout << "dehaze: ambient light is " @@ -251,78 +249,102 @@ void ImProcFunctions::dehaze(Imagefloat *img) << std::endl; } - get_dark_channel(R, G, B, dark, patchsize, ambient, true, multiThread); - } - - if (min(ambient[0], ambient[1], ambient[2]) < 0.01f) { - if (options.rtSettings.verbose) { - std::cout << "dehaze: no haze detected" << std::endl; + if (min(ambient[0], ambient[1], ambient[2]) < 0.01f) { + if (options.rtSettings.verbose) { + std::cout << "dehaze: no haze detected" << std::endl; + } + img->normalizeFloatTo65535(); + return; // probably no haze at all } - img->normalizeFloatTo65535(); - return; // probably no haze at all - } - DEBUG_DUMP(t_tilde); - -#ifdef _OPENMP - #pragma omp parallel for if (multiThread) -#endif - for (int y = 0; y < H; ++y) { - for (int x = 0; x < W; ++x) { - dark[y][x] = 1.f - strength * dark[y][x]; - } + get_dark_channel(R, G, B, dark, patchsize, ambient, true, multiThread, strength); } const int radius = patchsize * 4; - const float epsilon = 1e-5; - array2D &t = t_tilde; + constexpr float epsilon = 1e-5f; { array2D guideB(W, H, img->b.ptrs, ARRAY2D_BYREFERENCE); - guidedFilter(guideB, t_tilde, t, radius, epsilon, multiThread); + guidedFilter(guideB, dark, dark, radius, epsilon, multiThread); } - DEBUG_DUMP(t); - if (options.rtSettings.verbose) { std::cout << "dehaze: max distance is " << max_t << std::endl; } - float depth = -float(params->dehaze.depth) / 100.f; + const float depth = -float(params->dehaze.depth) / 100.f; const float t0 = max(1e-3f, std::exp(depth * max_t)); const float teps = 1e-3f; #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif for (int y = 0; y < H; ++y) { - for (int x = 0; x < W; ++x) { + int x = 0; +#ifdef __SSE2__ + const vfloat onev = F2V(1.f); + const vfloat ambient0v = F2V(ambient[0]); + const vfloat ambient1v = F2V(ambient[1]); + const vfloat ambient2v = F2V(ambient[2]); + const vfloat t0v = F2V(t0); + const vfloat tepsv = F2V(teps); + const vfloat c65535v = F2V(65535.f); + for (; x < W - 3; x += 4) { // ensure that the transmission is such that to avoid clipping... - float rgb[3] = { img->r(y, x), img->g(y, x), img->b(y, x) }; + vfloat r = LVFU(img->r(y, x)); + vfloat g = LVFU(img->g(y, x)); + vfloat b = LVFU(img->b(y, x)); // ... t >= tl to avoid negative values - float tl = 1.f - min(rgb[0]/ambient[0], rgb[1]/ambient[1], rgb[2]/ambient[2]); + const vfloat tlv = onev - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v)); // ... t >= tu to avoid values > 1 - float tu = t0 - teps; - for (int c = 0; c < 3; ++c) { - if (ambient[c] < 1) { - tu = max(tu, (rgb[c] - ambient[c])/(1.f - ambient[c])); - } - } - float mt = max(t[y][x], t0, tl + teps, tu + teps); - if (params->dehaze.showDepthMap) { - img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt); - } else { - float r = (rgb[0] - ambient[0]) / mt + ambient[0]; - float g = (rgb[1] - ambient[1]) / mt + ambient[1]; - float b = (rgb[2] - ambient[2]) / mt + ambient[2]; + r -= ambient0v; + g -= ambient1v; + b -= ambient2v; - img->r(y, x) = r; - img->g(y, x) = g; - img->b(y, x) = b; + vfloat tuv = t0v - tepsv; + tuv = vself(vmaskf_lt(ambient0v, onev), vmaxf(tuv, r / (onev - ambient0v)), tuv); + tuv = vself(vmaskf_lt(ambient1v, onev), vmaxf(tuv, g / (onev - ambient1v)), tuv); + tuv = vself(vmaskf_lt(ambient2v, onev), vmaxf(tuv, b / (onev - ambient2v)), tuv); + + const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv, tuv) + tepsv); + if (params->dehaze.showDepthMap) { + const vfloat valv = vclampf(onev - mtv, ZEROV, onev) * c65535v; + STVFU(img->r(y, x), valv); + STVFU(img->g(y, x), valv); + STVFU(img->b(y, x), valv); + } else { + STVFU(img->r(y, x), (r / mtv + ambient0v) * c65535v); + STVFU(img->g(y, x), (g / mtv + ambient1v) * c65535v); + STVFU(img->b(y, x), (b / mtv + ambient2v) * c65535v); + } + } +#endif + for (; x < W; ++x) { + // ensure that the transmission is such that to avoid clipping... + float r = img->r(y, x); + float g = img->g(y, x); + float b = img->b(y, x); + // ... t >= tl to avoid negative values + const float tl = 1.f - min(r / ambient[0], g / ambient[1], b / ambient[2]); + // ... t >= tu to avoid values > 1 + r -= ambient[0]; + g -= ambient[1]; + b -= ambient[2]; + + float tu = t0 - teps; + tu = ambient[0] < 1.f ? max(tu, r / (1.f - ambient[0])) : tu; + tu = ambient[1] < 1.f ? max(tu, g / (1.f - ambient[1])) : tu; + tu = ambient[2] < 1.f ? max(tu, b / (1.f - ambient[2])) : tu; + + const float mt = max(dark[y][x], tl + teps, tu + teps); + if (params->dehaze.showDepthMap) { + img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * 65535.f; + } else { + img->r(y, x) = (r / mt + ambient[0]) * 65535.f; + img->g(y, x) = (g / mt + ambient[1]) * 65535.f; + img->b(y, x) = (b / mt + ambient[2]) * 65535.f; } } } - - img->normalizeFloatTo65535(); } From 3981e285b9bda62d3126ad9704f58bf232ba67e0 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 19 Sep 2019 22:06:41 +0200 Subject: [PATCH 197/222] dehaze: fix broken build on gcc < 9.x, #5456 --- rtengine/ipdehaze.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 68af84970..cf333a5d5 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -162,7 +162,8 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) reduction(+:rr,gg,bb,n) #endif - for (const auto &p : patches) { + for (size_t i = 0; i < patches.size(); ++i) { + const auto &p = patches[i]; const int pW = min(p.first + patchsize, W); const int pH = min(p.second + patchsize, H); From 7d5ec6c0678f5a5d8a0eabccc197b51128949e3b Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 19 Sep 2019 22:21:45 +0200 Subject: [PATCH 198/222] Fix bug at right border in new boxblur function, #5456 --- rtengine/boxblur.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/rtengine/boxblur.h b/rtengine/boxblur.h index 3020278b2..5cc7430e2 100644 --- a/rtengine/boxblur.h +++ b/rtengine/boxblur.h @@ -26,6 +26,7 @@ #include "alignedbuffer.h" #include "rt_math.h" #include "opthelper.h" +#include "StopWatch.h" namespace rtengine @@ -485,41 +486,42 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu #endif { const int remaining = W % numCols; + if (remaining > 0) { float (* const rowBuffer)[8] = (float(*)[8]) buffer; const int col = W - remaining; float len = radius + 1; - for(int k = 0; k < remaining; k++) { + for(int k = 0; k < remaining; ++k) { rowBuffer[0][k] = dst[0][col + k]; } - for (int i = 1; i <= radius; i++) { - for(int k = 0; k < remaining; k++) { - dst[0][col + k] += dst[i][col + k]; + for (int row = 1; row <= radius; ++row) { + for(int k = 0; k < remaining; ++k) { + dst[0][col + k] += dst[row][col + k]; } } - for(int k = 0; k < remaining; k++) { + for(int k = 0; k < remaining; ++k) { dst[0][col + k] /= len; } - for (int row = 1; row <= radius; row++) { - for(int k = 0; k < remaining; k++) { + for (int row = 1; row <= radius; ++row) { + for(int k = 0; k < remaining; ++k) { rowBuffer[row][k] = dst[row][col + k]; - dst[row][col + k] = (dst[(row - 1)][col + k] * len + dst[row + radius][col + k]) / (len + 1); - len ++; + dst[row][col + k] = (dst[row - 1][col + k] * len + dst[row + radius][col + k]) / (len + 1); } + len ++; } const float rlen = 1.f / len; - for (int row = radius + 1; row < H - radius; row++) { - for(int k = 0; k < remaining; k++) { + for (int row = radius + 1; row < H - radius; ++row) { + for(int k = 0; k < remaining; ++k) { rowBuffer[row][k] = dst[row][col + k]; - dst[row][col + k] = dst[(row - 1)][col + k] + (dst[row + radius][col + k] - rowBuffer[row - radius - 1][k]) * rlen; + dst[row][col + k] = dst[row - 1][col + k] + (dst[row + radius][col + k] - rowBuffer[row - radius - 1][k]) * rlen; } } - for (int row = H - radius; row < H; row++) { - for(int k = 0; k < remaining; k++) { + for (int row = H - radius; row < H; ++row) { + for(int k = 0; k < remaining; ++k) { dst[row][col + k] = (dst[(row - 1)][col + k] * len - rowBuffer[row - radius - 1][k]) / (len - 1); - len --; } + len --; } } } From e33bee7ceab5e5f8bfbd01c3d26c60f463cc0088 Mon Sep 17 00:00:00 2001 From: scx Date: Thu, 19 Sep 2019 23:40:49 +0200 Subject: [PATCH 199/222] Update desktop file - Update Version entry (Keyword key was introduced in 1.1) - Fix GenericName - Add TryExec entry - Update Keywords --- rtdata/rawtherapee.desktop.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rtdata/rawtherapee.desktop.in b/rtdata/rawtherapee.desktop.in index 233a737b6..9356c5a2d 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; +Keywords=raw;photo;photography;develop;pp3;graphics; StartupWMClass=rawtherapee From 633eab24c288b2a8933af23b88d057f7df2ed0f3 Mon Sep 17 00:00:00 2001 From: scx Date: Thu, 19 Sep 2019 23:44:17 +0200 Subject: [PATCH 200/222] Update AppData file - Fix description (

tag) - Remove keywords (should be obtained from desktop file) - Fix URLs - Fix screenshot caption (too long) --- com.rawtherapee.RawTherapee.appdata.xml | 28 +++++++------------------ 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index 0e5dfef50..564821cb4 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,7 +34,7 @@ - Color-correcting a drosera rotundifolia in RawTherapee 5.7. + Color-correcting a drosera rotundifolia https://rawtherapee.com/images/screenshots/rt570_1.jpg From 2415511b7011434b6f088fb46df8f4737b9e717b Mon Sep 17 00:00:00 2001 From: scx Date: Thu, 19 Sep 2019 23:55:31 +0200 Subject: [PATCH 201/222] Update desktop file - Change order of categories (Main Category before Additional Categories) --- rtdata/rawtherapee.desktop.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/rawtherapee.desktop.in b/rtdata/rawtherapee.desktop.in index 9356c5a2d..c6c675c4d 100644 --- a/rtdata/rawtherapee.desktop.in +++ b/rtdata/rawtherapee.desktop.in @@ -15,6 +15,6 @@ 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; +Categories=Graphics;Photography;2DGraphics;RasterGraphics;GTK; Keywords=raw;photo;photography;develop;pp3;graphics; StartupWMClass=rawtherapee From 581e46c7b053b69ebc488011f43e7290870fa287 Mon Sep 17 00:00:00 2001 From: scx Date: Thu, 19 Sep 2019 23:59:00 +0200 Subject: [PATCH 202/222] Fix AppData file - Remove unreachable screenshot URL --- com.rawtherapee.RawTherapee.appdata.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index 564821cb4..41a669532 100644 --- a/com.rawtherapee.RawTherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -33,10 +33,6 @@ rawtherapee-cli - - Color-correcting a drosera rotundifolia - https://rawtherapee.com/images/screenshots/rt570_1.jpg - HDR DNG of a misty morning in the countryside https://rawtherapee.com/images/screenshots/rt540_1.jpg From 7ff3192cc96d7f9339775a3469e52715ddf3e08a Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 20 Sep 2019 14:03:09 +0200 Subject: [PATCH 203/222] dehaze: added lumimance mode from ART, #5456, thanks to @agriggio --- rtdata/languages/default | 2 ++ rtengine/color.h | 5 +++++ rtengine/ipdehaze.cc | 43 +++++++++++++++++++++++++++++++--------- rtengine/procparams.cc | 9 ++++++--- rtengine/procparams.h | 2 +- rtgui/dehaze.cc | 16 +++++++++++++++ rtgui/dehaze.h | 5 ++++- rtgui/paramsedited.cc | 6 ++++++ rtgui/paramsedited.h | 1 + 9 files changed, 75 insertions(+), 14 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3749a706a..49dabe9b9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -744,6 +744,7 @@ HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth HISTORY_MSG_DEHAZE_ENABLED;Haze Removal +HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold @@ -1538,6 +1539,7 @@ TP_DEFRINGE_RADIUS;Radius TP_DEFRINGE_THRESHOLD;Threshold TP_DEHAZE_DEPTH;Depth TP_DEHAZE_LABEL;Haze Removal +TP_DEHAZE_LUMINANCE;Luminance only TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map TP_DEHAZE_STRENGTH;Strength TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones diff --git a/rtengine/color.h b/rtengine/color.h index b859fb0cf..1031ca150 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -210,6 +210,11 @@ public: return r * workingspace[1][0] + g * workingspace[1][1] + b * workingspace[1][2]; } + static vfloat rgbLuminance(vfloat r, vfloat g, vfloat b, const vfloat workingspace[3]) + { + return r * workingspace[0] + g * workingspace[1] + b * workingspace[2]; + } + /** * @brief Convert red/green/blue to L*a*b * @brief Convert red/green/blue to hue/saturation/luminance diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index cf333a5d5..4eb5ed8e9 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -276,6 +276,13 @@ BENCHFUN const float depth = -float(params->dehaze.depth) / 100.f; const float t0 = max(1e-3f, std::exp(depth * max_t)); const float teps = 1e-3f; + + const bool luminance = params->dehaze.luminance; + TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); +#ifdef __SSE2__ + const vfloat wsv[3] = {F2V(ws[1][0]), F2V(ws[1][1]),F2V(ws[1][2])}; +#endif + const float ambientY = Color::rgbLuminance(ambient[0], ambient[1], ambient[2], ws); #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif @@ -286,6 +293,8 @@ BENCHFUN const vfloat ambient0v = F2V(ambient[0]); const vfloat ambient1v = F2V(ambient[1]); const vfloat ambient2v = F2V(ambient[2]); + const vfloat ambientYv = F2V(ambientY); + const vfloat epsYv = F2V(1e-5f); const vfloat t0v = F2V(t0); const vfloat tepsv = F2V(teps); const vfloat c65535v = F2V(65535.f); @@ -297,14 +306,14 @@ BENCHFUN // ... t >= tl to avoid negative values const vfloat tlv = onev - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v)); // ... t >= tu to avoid values > 1 - r -= ambient0v; - g -= ambient1v; - b -= ambient2v; +// r -= ambient0v; +// g -= ambient1v; +// b -= ambient2v; vfloat tuv = t0v - tepsv; - tuv = vself(vmaskf_lt(ambient0v, onev), vmaxf(tuv, r / (onev - ambient0v)), tuv); - tuv = vself(vmaskf_lt(ambient1v, onev), vmaxf(tuv, g / (onev - ambient1v)), tuv); - tuv = vself(vmaskf_lt(ambient2v, onev), vmaxf(tuv, b / (onev - ambient2v)), tuv); + tuv = vself(vmaskf_lt(ambient0v, onev), vmaxf(tuv, (r - ambient0v) / (onev - ambient0v)), tuv); + tuv = vself(vmaskf_lt(ambient1v, onev), vmaxf(tuv, (g - ambient1v) / (onev - ambient1v)), tuv); + tuv = vself(vmaskf_lt(ambient2v, onev), vmaxf(tuv, (b - ambient2v) / (onev - ambient2v)), tuv); const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv, tuv) + tepsv); if (params->dehaze.showDepthMap) { @@ -312,10 +321,17 @@ BENCHFUN STVFU(img->r(y, x), valv); STVFU(img->g(y, x), valv); STVFU(img->b(y, x), valv); + } else if (luminance) { + const vfloat Yv = Color::rgbLuminance(r, g, b, wsv); + const vfloat YYv = (Yv - ambientYv) / mtv + ambientYv; + const vfloat fv = vself(vmaskf_gt(Yv, epsYv), c65535v * YYv / Yv, c65535v); + STVFU(img->r(y, x), r * fv); + STVFU(img->g(y, x), g * fv); + STVFU(img->b(y, x), b * fv); } else { - STVFU(img->r(y, x), (r / mtv + ambient0v) * c65535v); - STVFU(img->g(y, x), (g / mtv + ambient1v) * c65535v); - STVFU(img->b(y, x), (b / mtv + ambient2v) * c65535v); + STVFU(img->r(y, x), ((r - ambient0v) / mtv + ambient0v) * c65535v); + STVFU(img->g(y, x), ((g - ambient1v) / mtv + ambient1v) * c65535v); + STVFU(img->b(y, x), ((b - ambient2v) / mtv + ambient2v) * c65535v); } } #endif @@ -339,6 +355,15 @@ BENCHFUN const float mt = max(dark[y][x], tl + teps, tu + teps); if (params->dehaze.showDepthMap) { img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * 65535.f; + } else if (luminance) { + const float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws); + const float YY = (Y - ambientY) / mt + ambientY; + if (Y > 1e-5f) { + const float f = 65535.f * YY / Y; + img->r(y, x) *= f; + img->g(y, x) *= f; + img->b(y, x) *= f; + } } else { img->r(y, x) = (r / mt + ambient[0]) * 65535.f; img->g(y, x) = (g / mt + ambient[1]) * 65535.f; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f88220c4e..fcf6dd4db 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2517,7 +2517,8 @@ DehazeParams::DehazeParams() : enabled(false), strength(50), showDepthMap(false), - depth(25) + depth(25), + luminance(false) { } @@ -2527,7 +2528,8 @@ bool DehazeParams::operator ==(const DehazeParams& other) const enabled == other.enabled && strength == other.strength && showDepthMap == other.showDepthMap - && depth == other.depth; + && depth == other.depth + && luminance == other.luminance; } bool DehazeParams::operator !=(const DehazeParams& other) const @@ -3238,7 +3240,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->dehaze.strength, "Dehaze", "Strength", dehaze.strength, keyFile); saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); - + saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Luminance", dehaze.luminance, keyFile); // Directional pyramid denoising saveToKeyfile(!pedited || pedited->dirpyrDenoise.enabled, "Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.enhance, "Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance, keyFile); @@ -4878,6 +4880,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Dehaze", "Strength", pedited, dehaze.strength, pedited->dehaze.strength); assignFromKeyfile(keyFile, "Dehaze", "ShowDepthMap", pedited, dehaze.showDepthMap, pedited->dehaze.showDepthMap); assignFromKeyfile(keyFile, "Dehaze", "Depth", pedited, dehaze.depth, pedited->dehaze.depth); + assignFromKeyfile(keyFile, "Dehaze", "Luminance", pedited, dehaze.luminance, pedited->dehaze.luminance); } if (keyFile.has_group("Film Simulation")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index ce03efc7d..a60c497bc 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1342,7 +1342,7 @@ struct DehazeParams { int strength; bool showDepthMap; int depth; - + bool luminance; DehazeParams(); bool operator==(const DehazeParams &other) const; diff --git a/rtgui/dehaze.cc b/rtgui/dehaze.cc index 6f60d08d6..6b7fcd64f 100644 --- a/rtgui/dehaze.cc +++ b/rtgui/dehaze.cc @@ -36,6 +36,7 @@ Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, EvDehazeStrength = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_STRENGTH"); EvDehazeShowDepthMap = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP"); EvDehazeDepth = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_DEPTH"); + EvDehazeLuminance = m->newEvent(HDR, "HISTORY_MSG_DEHAZE_LUMINANCE"); strength = Gtk::manage(new Adjuster(M("TP_DEHAZE_STRENGTH"), 0., 100., 1., 50.)); strength->setAdjusterListener(this); @@ -45,12 +46,17 @@ Dehaze::Dehaze(): FoldableToolPanel(this, "dehaze", M("TP_DEHAZE_LABEL"), false, depth->setAdjusterListener(this); depth->show(); + luminance = Gtk::manage(new Gtk::CheckButton(M("TP_DEHAZE_LUMINANCE"))); + luminance->signal_toggled().connect(sigc::mem_fun(*this, &Dehaze::luminanceChanged)); + luminance->show(); + showDepthMap = Gtk::manage(new Gtk::CheckButton(M("TP_DEHAZE_SHOW_DEPTH_MAP"))); showDepthMap->signal_toggled().connect(sigc::mem_fun(*this, &Dehaze::showDepthMapChanged)); showDepthMap->show(); pack_start(*strength); pack_start(*depth); + pack_start(*luminance); pack_start(*showDepthMap); } @@ -64,12 +70,14 @@ void Dehaze::read(const ProcParams *pp, const ParamsEdited *pedited) depth->setEditedState(pedited->dehaze.depth ? Edited : UnEdited); set_inconsistent(multiImage && !pedited->dehaze.enabled); showDepthMap->set_inconsistent(!pedited->dehaze.showDepthMap); + luminance->set_inconsistent(!pedited->dehaze.luminance); } setEnabled(pp->dehaze.enabled); strength->setValue(pp->dehaze.strength); depth->setValue(pp->dehaze.depth); showDepthMap->set_active(pp->dehaze.showDepthMap); + luminance->set_active(pp->dehaze.luminance); enableListener(); } @@ -81,12 +89,14 @@ void Dehaze::write(ProcParams *pp, ParamsEdited *pedited) pp->dehaze.depth = depth->getValue(); pp->dehaze.enabled = getEnabled(); pp->dehaze.showDepthMap = showDepthMap->get_active(); + pp->dehaze.luminance = luminance->get_active(); if (pedited) { pedited->dehaze.strength = strength->getEditedState(); pedited->dehaze.depth = depth->getEditedState(); pedited->dehaze.enabled = !get_inconsistent(); pedited->dehaze.showDepthMap = !showDepthMap->get_inconsistent(); + pedited->dehaze.luminance = !luminance->get_inconsistent(); } } @@ -138,6 +148,12 @@ void Dehaze::showDepthMapChanged() } } +void Dehaze::luminanceChanged() +{ + if (listener) { + listener->panelChanged(EvDehazeLuminance, luminance->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } +} void Dehaze::setBatchMode(bool batchMode) { diff --git a/rtgui/dehaze.h b/rtgui/dehaze.h index 3120dfc91..6a9d31cd1 100644 --- a/rtgui/dehaze.h +++ b/rtgui/dehaze.h @@ -28,12 +28,14 @@ class Dehaze: public ToolParamBlock, public AdjusterListener, public FoldableToo private: Adjuster *strength; Adjuster *depth; - Gtk::CheckButton *showDepthMap; + Gtk::CheckButton *showDepthMap; + Gtk::CheckButton *luminance; rtengine::ProcEvent EvDehazeEnabled; rtengine::ProcEvent EvDehazeStrength; rtengine::ProcEvent EvDehazeDepth; rtengine::ProcEvent EvDehazeShowDepthMap; + rtengine::ProcEvent EvDehazeLuminance; public: @@ -47,6 +49,7 @@ public: void adjusterChanged(Adjuster *a, double newval) override; void enabledChanged() override; void showDepthMapChanged(); + void luminanceChanged(); void setAdjusterBehavior(bool strengthAdd); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 2ab5702ea..9ea89f267 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -587,6 +587,7 @@ void ParamsEdited::set(bool v) dehaze.strength = v; dehaze.showDepthMap = v; dehaze.depth = v; + dehaze.luminance = v; metadata.mode = v; filmNegative.enabled = v; filmNegative.redRatio = v; @@ -1158,6 +1159,7 @@ void ParamsEdited::initFrom(const std::vector& dehaze.strength = dehaze.strength && p.dehaze.strength == other.dehaze.strength; dehaze.showDepthMap = dehaze.showDepthMap && p.dehaze.showDepthMap == other.dehaze.showDepthMap; dehaze.depth = dehaze.depth && p.dehaze.depth == other.dehaze.depth; + dehaze.luminance = dehaze.luminance && p.dehaze.luminance == other.dehaze.luminance; metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode; filmNegative.enabled = filmNegative.enabled && p.filmNegative.enabled == other.filmNegative.enabled; filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; @@ -3224,6 +3226,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.dehaze.showDepthMap = mods.dehaze.showDepthMap; } + if (dehaze.luminance) { + toEdit.dehaze.luminance = mods.dehaze.luminance; + } + if (metadata.mode) { toEdit.metadata.mode = mods.metadata.mode; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 1bd7170d4..41af0510d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -596,6 +596,7 @@ struct DehazeParamsEdited { bool strength; bool showDepthMap; bool depth; + bool luminance; }; struct RAWParamsEdited { From 83a8ca8ef52a03b600610a40720149bee30c5bec Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 20 Sep 2019 15:29:35 +0200 Subject: [PATCH 204/222] dehaze: Fix artifacts when blue channel is clipped, #5456, thanks to @agriggio --- rtengine/ipdehaze.cc | 50 +++++++++++++------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 4eb5ed8e9..81074a15b 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -264,10 +264,8 @@ BENCHFUN const int radius = patchsize * 4; constexpr float epsilon = 1e-5f; - { - array2D guideB(W, H, img->b.ptrs, ARRAY2D_BYREFERENCE); - guidedFilter(guideB, dark, dark, radius, epsilon, multiThread); - } + array2D guideB(W, H, img->b.ptrs, ARRAY2D_BYREFERENCE); + guidedFilter(guideB, dark, dark, radius, epsilon, multiThread); if (options.rtSettings.verbose) { std::cout << "dehaze: max distance is " << max_t << std::endl; @@ -300,22 +298,12 @@ BENCHFUN const vfloat c65535v = F2V(65535.f); for (; x < W - 3; x += 4) { // ensure that the transmission is such that to avoid clipping... - vfloat r = LVFU(img->r(y, x)); - vfloat g = LVFU(img->g(y, x)); - vfloat b = LVFU(img->b(y, x)); + const vfloat r = LVFU(img->r(y, x)); + const vfloat g = LVFU(img->g(y, x)); + const vfloat b = LVFU(img->b(y, x)); // ... t >= tl to avoid negative values const vfloat tlv = onev - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v)); - // ... t >= tu to avoid values > 1 -// r -= ambient0v; -// g -= ambient1v; -// b -= ambient2v; - - vfloat tuv = t0v - tepsv; - tuv = vself(vmaskf_lt(ambient0v, onev), vmaxf(tuv, (r - ambient0v) / (onev - ambient0v)), tuv); - tuv = vself(vmaskf_lt(ambient1v, onev), vmaxf(tuv, (g - ambient1v) / (onev - ambient1v)), tuv); - tuv = vself(vmaskf_lt(ambient2v, onev), vmaxf(tuv, (b - ambient2v) / (onev - ambient2v)), tuv); - - const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv, tuv) + tepsv); + const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv + tepsv, t0v)); if (params->dehaze.showDepthMap) { const vfloat valv = vclampf(onev - mtv, ZEROV, onev) * c65535v; STVFU(img->r(y, x), valv); @@ -337,37 +325,27 @@ BENCHFUN #endif for (; x < W; ++x) { // ensure that the transmission is such that to avoid clipping... - float r = img->r(y, x); - float g = img->g(y, x); - float b = img->b(y, x); + const float r = img->r(y, x); + const float g = img->g(y, x); + const float b = img->b(y, x); // ... t >= tl to avoid negative values const float tl = 1.f - min(r / ambient[0], g / ambient[1], b / ambient[2]); - // ... t >= tu to avoid values > 1 - r -= ambient[0]; - g -= ambient[1]; - b -= ambient[2]; - - float tu = t0 - teps; - tu = ambient[0] < 1.f ? max(tu, r / (1.f - ambient[0])) : tu; - tu = ambient[1] < 1.f ? max(tu, g / (1.f - ambient[1])) : tu; - tu = ambient[2] < 1.f ? max(tu, b / (1.f - ambient[2])) : tu; - - const float mt = max(dark[y][x], tl + teps, tu + teps); + const float mt = max(dark[y][x], t0, tl + teps); if (params->dehaze.showDepthMap) { img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * 65535.f; } else if (luminance) { const float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws); - const float YY = (Y - ambientY) / mt + ambientY; if (Y > 1e-5f) { + const float YY = (Y - ambientY) / mt + ambientY; const float f = 65535.f * YY / Y; img->r(y, x) *= f; img->g(y, x) *= f; img->b(y, x) *= f; } } else { - img->r(y, x) = (r / mt + ambient[0]) * 65535.f; - img->g(y, x) = (g / mt + ambient[1]) * 65535.f; - img->b(y, x) = (b / mt + ambient[2]) * 65535.f; + img->r(y, x) = ((r - ambient[0]) / mt + ambient[0]) * 65535.f; + img->g(y, x) = ((g - ambient[1]) / mt + ambient[1]) * 65535.f; + img->b(y, x) = ((b - ambient[2]) / mt + ambient[2]) * 65535.f; } } } From 706c16510fef47d87e69bfe980906c199bdfee05 Mon Sep 17 00:00:00 2001 From: Franz Trischberger Date: Sat, 21 Sep 2019 08:44:53 +0300 Subject: [PATCH 205/222] Add option to link against libtcmalloc.so Implementation done by Alberto Griggio (agriggio) for his fork at https://bitbucket.org/agriggio/art libtcmalloc.so comes with google's perftools: https://github.com/gperftools/gperftools This should fix issues where glibc won't give memory back to the OS. Related issue: #4416 --- CMakeLists.txt | 20 ++++++++++++++++++++ rtgui/CMakeLists.txt | 2 ++ 2 files changed, 22 insertions(+) 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/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 From a7cc59c91dc2b715203e63bfcf8f5423103a18e6 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 21 Sep 2019 21:33:05 +0200 Subject: [PATCH 206/222] dehaze: further speedup, stolen from ART, thanks @agriggio, #5456 --- rtengine/ipdehaze.cc | 91 ++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 81074a15b..6f516d95b 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -39,7 +39,7 @@ #include "rt_math.h" #define BENCHMARK #include "StopWatch.h" - +#include "rescale.h" extern Options options; namespace rtengine { @@ -83,24 +83,24 @@ int get_dark_channel_downsized(const array2D &R, const array2D &G, #pragma omp parallel for if (multithread) #endif for (int y = 0; y < H; y += patchsize) { - int yy = y / patchsize; const int pH = min(y + patchsize, H); - for (int x = 0, xx = 0; x < W; x += patchsize, ++xx) { + for (int x = 0; x < W; x += patchsize) { float val = RT_INFINITY_F; const int pW = min(x + patchsize, W); - for (int xp = x; xp < pW; ++xp) { - for (int yp = y; yp < pH; ++yp) { - val = min(val, R[yp][xp], G[yp][xp], B[yp][xp]); + for (int xx = x; xx < pW; ++xx) { + for (int yy = y; yy < pH; ++yy) { + val = min(val, R[yy][xx], G[yy][xx], B[yy][xx]); } } - dst[yy][xx] = val; + for (int yy = y; yy < pH; ++yy) { + std::fill(dst[yy] + x, dst[yy] + pW, val); + } } } return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0)); } - float estimate_ambient_light(const array2D &R, const array2D &G, const array2D &B, const array2D &dark, int patchsize, int npatches, float ambient[3]) { const int W = R.width(); @@ -109,10 +109,10 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c float darklim = RT_INFINITY_F; { std::vector p; - for (int y = 0, yy = 0; y < H; y += patchsize, ++yy) { - for (int x = 0, xx = 0; x < W; x += patchsize, ++xx) { - if (!OOG(dark[yy][xx], 1.f - 1e-5f)) { - p.push_back(dark[yy][xx]); + for (int y = 0; y < H; y += patchsize) { + for (int x = 0; x < W; x += patchsize) { + if (!OOG(dark[y][x], 1.f - 1e-5f)) { + p.push_back(dark[y][x]); } } } @@ -124,9 +124,9 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c std::vector> patches; patches.reserve(npatches); - for (int y = 0, yy = 0; y < H; y += patchsize, ++yy) { - for (int x = 0, xx = 0; x < W; x += patchsize, ++xx) { - if (dark[yy][xx] >= darklim && !OOG(dark[yy][xx], 1.f)) { + for (int y = 0; y < H; y += patchsize) { + for (int x = 0; x < W; x += patchsize) { + if (dark[y][x] >= darklim && !OOG(dark[y][x], 1.f)) { patches.push_back(std::make_pair(x, y)); } } @@ -142,9 +142,9 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c std::vector l; l.reserve(patches.size() * patchsize * patchsize); - for (const auto &p : patches) { - const int pW = min(p.first + patchsize, W); - const int pH = min(p.second + patchsize, H); + for (auto &p : patches) { + const int pW = min(p.first+patchsize, W); + const int pH = min(p.second+patchsize, H); for (int y = p.second; y < pH; ++y) { for (int x = p.first; x < pW; ++x) { @@ -159,19 +159,15 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c double rr = 0, gg = 0, bb = 0; int n = 0; -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic) reduction(+:rr,gg,bb,n) -#endif - for (size_t i = 0; i < patches.size(); ++i) { - const auto &p = patches[i]; - const int pW = min(p.first + patchsize, W); - const int pH = min(p.second + patchsize, H); + for (auto &p : patches) { + const int pW = min(p.first+patchsize, W); + const int pH = min(p.second+patchsize, H); for (int y = p.second; y < pH; ++y) { for (int x = p.first; x < pW; ++x) { - const float r = R[y][x]; - const float g = G[y][x]; - const float b = B[y][x]; + float r = R[y][x]; + float g = G[y][x]; + float b = B[y][x]; if (r + g + b >= bright_lim) { rr += r; gg += g; @@ -181,7 +177,6 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c } } } - n = std::max(n, 1); ambient[0] = rr / n; ambient[1] = gg / n; @@ -191,7 +186,6 @@ float estimate_ambient_light(const array2D &R, const array2D &G, c return darklim > 0 ? -1.125f * std::log(darklim) : std::log(std::numeric_limits::max()) / 2; } - void extract_channels(Imagefloat *img, array2D &r, array2D &g, array2D &b, int radius, float epsilon, bool multithread) { const int W = img->getWidth(); @@ -238,11 +232,32 @@ BENCHFUN array2D B(W, H); extract_channels(img, R, G, B, patchsize, 1e-1, multiThread); - patchsize = max(max(W, H) / 600, 2); - array2D darkDownsized(W / patchsize + 1, H / patchsize + 1); - const int npatches = get_dark_channel_downsized(R, G, B, darkDownsized, patchsize, multiThread); + { + constexpr int sizecap = 200; + float r = float(W)/float(H); + const int hh = r >= 1.f ? sizecap : sizecap / r; + const int ww = r >= 1.f ? sizecap * r : sizecap; - max_t = estimate_ambient_light(R, G, B, darkDownsized, patchsize, npatches, ambient); + if (W <= ww && H <= hh) { + // don't rescale small thumbs + array2D D(W, H); + int npatches = get_dark_channel_downsized(R, G, B, D, 2, multiThread); + max_t = estimate_ambient_light(R, G, B, D, patchsize, npatches, ambient); + } else { + array2D RR(ww, hh); + array2D GG(ww, hh); + array2D BB(ww, hh); + rescaleNearest(R, RR, multiThread); + rescaleNearest(G, GG, multiThread); + rescaleNearest(B, BB, multiThread); + array2D D(ww, hh); + + int npatches = get_dark_channel_downsized(RR, GG, BB, D, 2, multiThread); + max_t = estimate_ambient_light(RR, GG, BB, D, patchsize, npatches, ambient); + } + } + + patchsize = max(max(W, H) / 600, 2); if (options.rtSettings.verbose) { std::cout << "dehaze: ambient light is " @@ -250,14 +265,6 @@ BENCHFUN << std::endl; } - if (min(ambient[0], ambient[1], ambient[2]) < 0.01f) { - if (options.rtSettings.verbose) { - std::cout << "dehaze: no haze detected" << std::endl; - } - img->normalizeFloatTo65535(); - return; // probably no haze at all - } - get_dark_channel(R, G, B, dark, patchsize, ambient, true, multiThread, strength); } From cab84aed38456964f34f1bbe68b4ca3104753cd7 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 22 Sep 2019 13:21:34 +0200 Subject: [PATCH 207/222] dehaze: fix bug in luminance mode, #5456 --- rtengine/ipdehaze.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 6f516d95b..125fa4d60 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -283,7 +283,7 @@ BENCHFUN const float teps = 1e-3f; const bool luminance = params->dehaze.luminance; - TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + const TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); #ifdef __SSE2__ const vfloat wsv[3] = {F2V(ws[1][0]), F2V(ws[1][1]),F2V(ws[1][2])}; #endif @@ -342,13 +342,11 @@ BENCHFUN img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * 65535.f; } else if (luminance) { const float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws); - if (Y > 1e-5f) { - const float YY = (Y - ambientY) / mt + ambientY; - const float f = 65535.f * YY / Y; - img->r(y, x) *= f; - img->g(y, x) *= f; - img->b(y, x) *= f; - } + const float YY = (Y - ambientY) / mt + ambientY; + const float f = Y > 1e-5f ? 65535.f * YY / Y : 65535.f; + img->r(y, x) *= f; + img->g(y, x) *= f; + img->b(y, x) *= f; } else { img->r(y, x) = ((r - ambient[0]) / mt + ambient[0]) * 65535.f; img->g(y, x) = ((g - ambient[1]) / mt + ambient[1]) * 65535.f; From 189f474e033c908ed06bfcb32580ab63427b9ad0 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 22 Sep 2019 20:53:03 +0200 Subject: [PATCH 208/222] dehaze: add accidently removed early exit in case there is no haze detected, #5456 --- rtengine/ipdehaze.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 125fa4d60..00236d1de 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -257,6 +257,13 @@ BENCHFUN } } + if (min(ambient[0], ambient[1], ambient[2]) < 0.01f) { + if (options.rtSettings.verbose) { + std::cout << "dehaze: no haze detected" << std::endl; + } + img->normalizeFloatTo65535(); + return; // probably no haze at all + } patchsize = max(max(W, H) / 600, 2); if (options.rtSettings.verbose) { From ca162e8ffc7ecd1ad924a0735c9e364c0aff3779 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 22 Sep 2019 23:45:19 +0200 Subject: [PATCH 209/222] dehaze: (experimental) input normalization to improve handling of overexposed pictures, thanks @agriggio, #5456 --- rtengine/ipdehaze.cc | 79 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 00236d1de..8ba1b935a 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -28,24 +28,69 @@ * */ +#include #include -#include +#include #include "guidedfilter.h" #include "improcfun.h" #include "procparams.h" -#include "rt_algo.h" -#include "rt_algo.h" +#include "rescale.h" #include "rt_math.h" #define BENCHMARK #include "StopWatch.h" -#include "rescale.h" + extern Options options; namespace rtengine { namespace { +float normalize(Imagefloat *rgb, bool multithread) +{ + float maxval = 0.f; + const int W = rgb->getWidth(); + const int H = rgb->getHeight(); +#ifdef _OPENMP +# pragma omp parallel for reduction(max:maxval) if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + maxval = max(maxval, rgb->r(y, x), rgb->g(y, x), rgb->b(y, x)); + } + } + maxval = max(maxval * 2.f, 65535.f); +#ifdef _OPENMP +# pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + rgb->r(y, x) /= maxval; + rgb->g(y, x) /= maxval; + rgb->b(y, x) /= maxval; + } + } + return maxval; +} + +void restore(Imagefloat *rgb, float maxval, bool multithread) +{ + const int W = rgb->getWidth(); + const int H = rgb->getHeight(); + if (maxval > 0.f && maxval != 1.f) { +#ifdef _OPENMP +# pragma omp parallel for if (multithread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + rgb->r(y, x) *= maxval; + rgb->g(y, x) *= maxval; + rgb->b(y, x) *= maxval; + } + } + } +} + int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength) { const int W = R.width(); @@ -210,7 +255,7 @@ void ImProcFunctions::dehaze(Imagefloat *img) return; } BENCHFUN - img->normalizeFloatTo1(); + const float maxChannel = normalize(img, multiThread); const int W = img->getWidth(); const int H = img->getHeight(); @@ -261,7 +306,7 @@ BENCHFUN if (options.rtSettings.verbose) { std::cout << "dehaze: no haze detected" << std::endl; } - img->normalizeFloatTo65535(); + restore(img, maxChannel, multiThread); return; // probably no haze at all } patchsize = max(max(W, H) / 600, 2); @@ -309,7 +354,7 @@ BENCHFUN const vfloat epsYv = F2V(1e-5f); const vfloat t0v = F2V(t0); const vfloat tepsv = F2V(teps); - const vfloat c65535v = F2V(65535.f); + const vfloat cmaxChannelv = F2V(maxChannel); for (; x < W - 3; x += 4) { // ensure that the transmission is such that to avoid clipping... const vfloat r = LVFU(img->r(y, x)); @@ -319,21 +364,21 @@ BENCHFUN const vfloat tlv = onev - vminf(r / ambient0v, vminf(g / ambient1v, b / ambient2v)); const vfloat mtv = vmaxf(LVFU(dark[y][x]), vmaxf(tlv + tepsv, t0v)); if (params->dehaze.showDepthMap) { - const vfloat valv = vclampf(onev - mtv, ZEROV, onev) * c65535v; + const vfloat valv = vclampf(onev - mtv, ZEROV, onev) * cmaxChannelv; STVFU(img->r(y, x), valv); STVFU(img->g(y, x), valv); STVFU(img->b(y, x), valv); } else if (luminance) { const vfloat Yv = Color::rgbLuminance(r, g, b, wsv); const vfloat YYv = (Yv - ambientYv) / mtv + ambientYv; - const vfloat fv = vself(vmaskf_gt(Yv, epsYv), c65535v * YYv / Yv, c65535v); + const vfloat fv = vself(vmaskf_gt(Yv, epsYv), cmaxChannelv * YYv / Yv, cmaxChannelv); STVFU(img->r(y, x), r * fv); STVFU(img->g(y, x), g * fv); STVFU(img->b(y, x), b * fv); } else { - STVFU(img->r(y, x), ((r - ambient0v) / mtv + ambient0v) * c65535v); - STVFU(img->g(y, x), ((g - ambient1v) / mtv + ambient1v) * c65535v); - STVFU(img->b(y, x), ((b - ambient2v) / mtv + ambient2v) * c65535v); + STVFU(img->r(y, x), ((r - ambient0v) / mtv + ambient0v) * cmaxChannelv); + STVFU(img->g(y, x), ((g - ambient1v) / mtv + ambient1v) * cmaxChannelv); + STVFU(img->b(y, x), ((b - ambient2v) / mtv + ambient2v) * cmaxChannelv); } } #endif @@ -346,18 +391,18 @@ BENCHFUN const float tl = 1.f - min(r / ambient[0], g / ambient[1], b / ambient[2]); const float mt = max(dark[y][x], t0, tl + teps); if (params->dehaze.showDepthMap) { - img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * 65535.f; + img->r(y, x) = img->g(y, x) = img->b(y, x) = LIM01(1.f - mt) * maxChannel; } else if (luminance) { const float Y = Color::rgbLuminance(img->r(y, x), img->g(y, x), img->b(y, x), ws); const float YY = (Y - ambientY) / mt + ambientY; - const float f = Y > 1e-5f ? 65535.f * YY / Y : 65535.f; + const float f = Y > 1e-5f ? maxChannel * YY / Y : maxChannel; img->r(y, x) *= f; img->g(y, x) *= f; img->b(y, x) *= f; } else { - img->r(y, x) = ((r - ambient[0]) / mt + ambient[0]) * 65535.f; - img->g(y, x) = ((g - ambient[1]) / mt + ambient[1]) * 65535.f; - img->b(y, x) = ((b - ambient[2]) / mt + ambient[2]) * 65535.f; + img->r(y, x) = ((r - ambient[0]) / mt + ambient[0]) * maxChannel; + img->g(y, x) = ((g - ambient[1]) / mt + ambient[1]) * maxChannel; + img->b(y, x) = ((b - ambient[2]) / mt + ambient[2]) * maxChannel; } } } From c656fa0fc768c8fb8a82ca48e9a68b138bab370b Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Mon, 23 Sep 2019 01:21:52 +0200 Subject: [PATCH 210/222] Update screenshots in appdata file --- com.rawtherapee.RawTherapee.appdata.xml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index 41a669532..3a55109ba 100644 --- a/com.rawtherapee.RawTherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -33,17 +33,21 @@ rawtherapee-cli - - HDR DNG of a misty morning in the countryside - https://rawtherapee.com/images/screenshots/rt540_1.jpg + + Color correction + https://rawtherapee.com/images/screenshots/rt57_drosera_rotundifolia.png - Straight-out-of-camera vs RawTherapee - https://rawtherapee.com/images/screenshots/rt540_2.jpg + File browser + https://rawtherapee.com/images/screenshots/rt57_file_browser.png - - RawTherapee using the Auto-Matched Tone Curve tool - https://rawtherapee.com/images/screenshots/rt540_3.jpg + + High dynamic range compression + https://rawtherapee.com/images/screenshots/rt57_field_sunset.png + + + Developing a film negative + https://rawtherapee.com/images/screenshots/rt57_film_negative.png contactus@rawtherapee.com From f03605b73526235c27832f5815359943f4e0441e Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 13:39:21 +0200 Subject: [PATCH 211/222] boxblur: apply changes requested by @Floessie in code review --- rtengine/boxblur.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/rtengine/boxblur.h b/rtengine/boxblur.h index 5cc7430e2..27aa9d2fc 100644 --- a/rtengine/boxblur.h +++ b/rtengine/boxblur.h @@ -20,6 +20,7 @@ #define _BOXBLUR_H_ #include +#include #include #include #include @@ -337,9 +338,10 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu #pragma omp parallel if (multiThread) #endif { - float* const buffer = new float[std::max(W, 8 * H)]; + std::unique_ptr buffer(new float[std::max(W, 8 * H)]); + //horizontal blur - float* const lineBuffer = buffer; + float* const lineBuffer = buffer.get(); #ifdef _OPENMP #pragma omp for #endif @@ -356,8 +358,9 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu for (int col = 1; col <= radius; col++) { lineBuffer[col] = src[row][col]; - dst[row][col] = tempval = (tempval * len + src[row][col + radius]) / (len + 1); - len ++; + tempval = (tempval * len + src[row][col + radius]) / (len + 1); + dst[row][col] = tempval; + ++len; } for (int col = radius + 1; col < W - radius; col++) { @@ -367,15 +370,15 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu for (int col = W - radius; col < W; col++) { dst[row][col] = tempval = (tempval * len - lineBuffer[col - radius - 1]) / (len - 1); - len --; + --len; } } //vertical blur #ifdef __SSE2__ - vfloat (* const rowBuffer)[2] = (vfloat(*)[2]) buffer; - vfloat leninitv = F2V(radius + 1); - vfloat onev = F2V(1.f); + vfloat (* const rowBuffer)[2] = (vfloat(*)[2]) buffer.get(); + const vfloat leninitv = F2V(radius + 1); + const vfloat onev = F2V(1.f); vfloat tempv, temp1v, lenv, lenp1v, lenm1v, rlenv; #ifdef _OPENMP @@ -432,7 +435,7 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu } #else - float (* const rowBuffer)[8] = (float(*)[8]) buffer; + float (* const rowBuffer)[8] = (float(*)[8]) buffer.get(); #ifdef _OPENMP #pragma omp for nowait #endif @@ -440,12 +443,12 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu for (int col = 0; col < W - numCols + 1; col += 8) { float len = radius + 1; - for(int k = 0; k < numCols; k++) { + for (int k = 0; k < numCols; k++) { rowBuffer[0][k] = dst[0][col + k]; } for (int i = 1; i <= radius; i++) { - for(int k = 0; k < numCols; k++) { + for (int k = 0; k < numCols; k++) { dst[0][col + k] += dst[i][col + k]; } } @@ -488,7 +491,7 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu const int remaining = W % numCols; if (remaining > 0) { - float (* const rowBuffer)[8] = (float(*)[8]) buffer; + float (* const rowBuffer)[8] = (float(*)[8]) buffer.get(); const int col = W - remaining; float len = radius + 1; @@ -525,7 +528,6 @@ inline void boxblur (float** src, float** dst, int radius, int W, int H, bool mu } } } - delete [] buffer; } } From 3ca7f09655e0c703a7d23c74414723d8f0d7b8a4 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 13:39:50 +0200 Subject: [PATCH 212/222] guidedfilter: apply changes requested by @Floessie in code review --- rtengine/guidedfilter.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/guidedfilter.cc b/rtengine/guidedfilter.cc index 8d19fc7a5..159e89504 100644 --- a/rtengine/guidedfilter.cc +++ b/rtengine/guidedfilter.cc @@ -66,7 +66,7 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 enum Op {MUL, DIVEPSILON, SUBMUL}; const auto apply = - [=](Op op, array2D &res, const array2D &a, const array2D &b, const array2D &c=array2D()) -> void + [multithread, epsilon](Op op, array2D &res, const array2D &a, const array2D &b, const array2D &c=array2D()) -> void { const int w = res.width(); const int h = res.height(); @@ -96,13 +96,13 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 }; const auto f_subsample = - [=](array2D &d, const array2D &s) -> void + [multithread](array2D &d, const array2D &s) -> void { rescaleBilinear(s, d, multithread); }; const auto f_mean = - [&](array2D &d, array2D &s, int rad) -> void + [multithread](array2D &d, array2D &s, int rad) -> void { rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1); boxblur(s, d, rad, s.width(), s.height(), multithread); From 7a8225d2745ef86eb71b537a2a852cbdf9882f26 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 13:40:19 +0200 Subject: [PATCH 213/222] procparams: apply changes requested by @Floessie in code review --- rtengine/procparams.cc | 1 + rtengine/procparams.h | 1 + 2 files changed, 2 insertions(+) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 734796cd8..8de7e2b55 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3243,6 +3243,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->dehaze.showDepthMap, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, keyFile); saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Depth", dehaze.depth, keyFile); saveToKeyfile(!pedited || pedited->dehaze.depth, "Dehaze", "Luminance", dehaze.luminance, keyFile); + // Directional pyramid denoising saveToKeyfile(!pedited || pedited->dirpyrDenoise.enabled, "Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.enhance, "Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance, keyFile); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0ef0f045b..734ca7556 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1344,6 +1344,7 @@ struct DehazeParams { bool showDepthMap; int depth; bool luminance; + DehazeParams(); bool operator==(const DehazeParams &other) const; From 204475dd05576f9e2d4b8b8d8e443603f1f3d9aa Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 13:42:23 +0200 Subject: [PATCH 214/222] sleefsseavx: added horizontal min and max --- rtengine/sleefsseavx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rtengine/sleefsseavx.c b/rtengine/sleefsseavx.c index 3000c1c10..cce88df5d 100644 --- a/rtengine/sleefsseavx.c +++ b/rtengine/sleefsseavx.c @@ -1390,6 +1390,18 @@ static inline float vhadd( vfloat a ) { return _mm_cvtss_f32(_mm_add_ss(a, _mm_shuffle_ps(a, a, 1))); } +static inline float vhmin(vfloat a) { + // returns min(a[0], a[1], a[2], a[3]) + a = vminf(a, _mm_movehl_ps(a, a)); + return _mm_cvtss_f32(vminf(a, _mm_shuffle_ps(a, a, 1))); +} + +static inline float vhmax(vfloat a) { + // returns max(a[0], a[1], a[2], a[3]) + a = vmaxf(a, _mm_movehl_ps(a, a)); + return _mm_cvtss_f32(vmaxf(a, _mm_shuffle_ps(a, a, 1))); +} + static INLINE vfloat vmul2f(vfloat a){ // fastest way to multiply by 2 return a + a; From 9cff2bca486e36b8bedc2612d26587d938df5c6a Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 13:43:43 +0200 Subject: [PATCH 215/222] dehaze: speedup and changes requested by @Floessie in code review, #5456 --- rtengine/ipdehaze.cc | 57 +++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 8ba1b935a..fb4f73903 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - */ +*/ /* * Haze removal using the algorithm described in the paper: @@ -26,7 +26,7 @@ * * using a guided filter for the "soft matting" of the transmission map * - */ +*/ #include #include @@ -52,7 +52,7 @@ float normalize(Imagefloat *rgb, bool multithread) const int W = rgb->getWidth(); const int H = rgb->getHeight(); #ifdef _OPENMP -# pragma omp parallel for reduction(max:maxval) if (multithread) + #pragma omp parallel for reduction(max:maxval) schedule(dynamic, 16) if (multithread) #endif for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { @@ -61,7 +61,7 @@ float normalize(Imagefloat *rgb, bool multithread) } maxval = max(maxval * 2.f, 65535.f); #ifdef _OPENMP -# pragma omp parallel for if (multithread) + #pragma omp parallel for schedule(dynamic, 16) if (multithread) #endif for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { @@ -102,13 +102,36 @@ int get_dark_channel(const array2D &R, const array2D &G, const arr for (int y = 0; y < H; y += patchsize) { const int pH = min(y + patchsize, H); for (int x = 0; x < W; x += patchsize) { - float val = RT_INFINITY_F; + float minR = RT_INFINITY_F; + float minG = RT_INFINITY_F; + float minB = RT_INFINITY_F; +#ifdef __SSE2__ + vfloat minRv = F2V(minR); + vfloat minGv = F2V(minG); + vfloat minBv = F2V(minB); +#endif const int pW = min(x + patchsize, W); - for (int xx = x; xx < pW; ++xx) { - for (int yy = y; yy < pH; ++yy) { - val = min(val, R[yy][xx] / ambient[0], G[yy][xx] / ambient[1], B[yy][xx] / ambient[2]); + for (int yy = y; yy < pH; ++yy) { + int xx = x; +#ifdef __SSE2__ + for (; xx < pW - 3; xx += 4) { + minRv = vminf(minRv, LVFU(R[yy][xx])); + minGv = vminf(minGv, LVFU(G[yy][xx])); + minBv = vminf(minBv, LVFU(B[yy][xx])); + } +#endif + for (; xx < pW; ++xx) { + minR = min(minR, R[yy][xx]); + minG = min(minG, G[yy][xx]); + minB = min(minB, B[yy][xx]); } } +#ifdef __SSE2__ + minR = min(minR, vhmin(minRv)); + minG = min(minG, vhmin(minGv)); + minB = min(minB, vhmin(minBv)); +#endif + float val = min(minR / ambient[0], minG / ambient[1], minB / ambient[2]); val = 1.f - strength * LIM01(val); for (int yy = y; yy < pH; ++yy) { std::fill(dst[yy] + x, dst[yy] + pW, val); @@ -269,25 +292,25 @@ BENCHFUN int patchsize = max(int(5 / scale), 2); float ambient[3]; - float max_t = 0.f; + float maxDistance = 0.f; { - array2D R(W, H); + array2D& R = dark; // R and dark can safely use the same buffer, which is faster and reduces memory allocations/deallocations array2D G(W, H); array2D B(W, H); extract_channels(img, R, G, B, patchsize, 1e-1, multiThread); { constexpr int sizecap = 200; - float r = float(W)/float(H); + const float r = static_cast(W) / static_cast(H); const int hh = r >= 1.f ? sizecap : sizecap / r; const int ww = r >= 1.f ? sizecap * r : sizecap; if (W <= ww && H <= hh) { // don't rescale small thumbs array2D D(W, H); - int npatches = get_dark_channel_downsized(R, G, B, D, 2, multiThread); - max_t = estimate_ambient_light(R, G, B, D, patchsize, npatches, ambient); + const int npatches = get_dark_channel_downsized(R, G, B, D, 2, multiThread); + maxDistance = estimate_ambient_light(R, G, B, D, patchsize, npatches, ambient); } else { array2D RR(ww, hh); array2D GG(ww, hh); @@ -297,8 +320,8 @@ BENCHFUN rescaleNearest(B, BB, multiThread); array2D D(ww, hh); - int npatches = get_dark_channel_downsized(RR, GG, BB, D, 2, multiThread); - max_t = estimate_ambient_light(RR, GG, BB, D, patchsize, npatches, ambient); + const int npatches = get_dark_channel_downsized(RR, GG, BB, D, 2, multiThread); + maxDistance = estimate_ambient_light(RR, GG, BB, D, patchsize, npatches, ambient); } } @@ -327,11 +350,11 @@ BENCHFUN guidedFilter(guideB, dark, dark, radius, epsilon, multiThread); if (options.rtSettings.verbose) { - std::cout << "dehaze: max distance is " << max_t << std::endl; + std::cout << "dehaze: max distance is " << maxDistance << std::endl; } const float depth = -float(params->dehaze.depth) / 100.f; - const float t0 = max(1e-3f, std::exp(depth * max_t)); + const float t0 = max(1e-3f, std::exp(depth * maxDistance)); const float teps = 1e-3f; const bool luminance = params->dehaze.luminance; From c83b577dc7b06a8d092c27f60f2e47911e5caba8 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 14:22:14 +0200 Subject: [PATCH 216/222] hasselblad_load_raw: apply changes requested by @Floessie in code review --- rtengine/dcraw.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 5275c42c1..c9c66a8fb 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2440,10 +2440,10 @@ void CLASS hasselblad_load_raw() } for (int col = 0; col < raw_width; col += 2) { for (int s = 0; s < tiff_samples * 2; s += 2) { - int len[2]; - for (int c = 0; c < 2; ++c) { - len[c] = ph1_huff(jh.huff[0]); - } + const int len[2]= { + ph1_huff(jh.huff[0]), + ph1_huff(jh.huff[0]) + }; for (int c = 0; c < 2; ++c) { diff[s + c] = hb_bits(len[c]); if ((diff[s + c] & (1 << (len[c] - 1))) == 0) { From 1e41ee62650fc27129a1b602539536434949372d Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 15:54:11 +0200 Subject: [PATCH 217/222] dehaze: fix two cppcheck style warnings, #5456 --- rtengine/ipdehaze.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index fb4f73903..d36c876c2 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -91,7 +91,7 @@ void restore(Imagefloat *rgb, float maxval, bool multithread) } } -int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength) +int get_dark_channel(const array2D &R, const array2D &G, const array2D &B, const array2D &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength) { const int W = R.width(); const int H = R.height(); @@ -142,7 +142,7 @@ int get_dark_channel(const array2D &R, const array2D &G, const arr return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0)); } -int get_dark_channel_downsized(const array2D &R, const array2D &G, const array2D &B, array2D &dst, int patchsize, bool multithread) +int get_dark_channel_downsized(const array2D &R, const array2D &G, const array2D &B, const array2D &dst, int patchsize, bool multithread) { const int W = R.width(); const int H = R.height(); From d1ccf27780d8825eadab1effc5fb38af96707497 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 16:32:23 +0200 Subject: [PATCH 218/222] Capture sharpening: add missing history message --- rtdata/languages/default | 1 + 1 file changed, 1 insertion(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index be1638e8e..d54536603 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -770,6 +770,7 @@ HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CAS - Auto radius HISTORY_MSG_PDSHARPEN_GAMMA;CAS - Gamma HISTORY_MSG_PDSHARPEN_ITERATIONS;CAS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CAS - Radius +HISTORY_MSG_PDSHARPEN_RADIUS_OFFSET;CAS - Radius offset HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter From 8d5c999ad84946f127815416f39cfc389f6d30da Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 16:44:55 +0200 Subject: [PATCH 219/222] hasselblad_load_raw: fix warning --- rtengine/dcraw.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index ad634c1e3..ef209118b 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2441,8 +2441,8 @@ void CLASS hasselblad_load_raw() for (int col = 0; col < raw_width; col += 2) { for (int s = 0; s < tiff_samples * 2; s += 2) { const int len[2]= { - ph1_huff(jh.huff[0]), - ph1_huff(jh.huff[0]) + static_cast(ph1_huff(jh.huff[0])), + static_cast(ph1_huff(jh.huff[0])) }; for (int c = 0; c < 2; ++c) { diff[s + c] = hb_bits(len[c]); From 57466be795ee871cc04bbbce9b399e1ee05db814 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 20:33:32 +0200 Subject: [PATCH 220/222] Capture sharpening: Label and tooltip changes, also renamed key for favorite tab to capturesharpening --- rtdata/languages/default | 5 ++--- rtgui/pdsharpening.cc | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index d54536603..aabff4bbe 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -770,7 +770,7 @@ HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CAS - Auto radius HISTORY_MSG_PDSHARPEN_GAMMA;CAS - Gamma HISTORY_MSG_PDSHARPEN_ITERATIONS;CAS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CAS - Radius -HISTORY_MSG_PDSHARPEN_RADIUS_OFFSET;CAS - Radius offset +HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CAS - Corner radius boost HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -1802,7 +1802,6 @@ TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse, TP_PCVIGNETTE_STRENGTH;Strength TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). TP_PDSHARPENING_LABEL;Capture Sharpening -TP_PDSHARPENING_AUTORADIUS_TOOLTIP;If the checkbox is checked, RawTherapee calculates a value based on the raw data of the image. TP_PERSPECTIVE_HORIZONTAL;Horizontal TP_PERSPECTIVE_LABEL;Perspective TP_PERSPECTIVE_VERTICAL;Vertical @@ -2038,7 +2037,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_RADIUS_BOOST;Corner radius boost TP_SHARPENING_RLD;RL Deconvolution TP_SHARPENING_RLD_AMOUNT;Amount TP_SHARPENING_RLD_DAMPING;Damping diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index f25e44e69..cd34a466e 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -26,14 +26,14 @@ using namespace rtengine; using namespace rtengine::procparams; -PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDSHARPENING_LABEL"), false, true) +PdSharpening::PdSharpening() : FoldableToolPanel(this, "capturesharpening", M("TP_PDSHARPENING_LABEL"), false, true) { auto m = ProcEventMapper::getInstance(); 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"); + EvPdShrDRadiusOffset = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS_BOOST"); 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"); @@ -42,7 +42,7 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS hb->show(); contrast = Gtk::manage(new Adjuster(M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 10)); contrast->setAdjusterListener(this); - contrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP")); + contrast->addAutoButton(); contrast->setAutoValue(true); pack_start(*contrast); @@ -53,9 +53,9 @@ 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_RADIUS"), 0.4, 1.15, 0.01, 0.75)); - dradius->addAutoButton(M("TP_PDSHARPENING_AUTORADIUS_TOOLTIP")); + dradius->addAutoButton(); dradius->setAutoValue(true); - dradiusOffset = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS_OFFSET"), 0.0, 0.5, 0.01, 0.0)); + dradiusOffset = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS_BOOST"), 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); From e62b004434e72c042bd8d05dabae74417482feee Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 23 Sep 2019 22:14:52 +0200 Subject: [PATCH 221/222] dehaze: removed benchmark code --- rtengine/ipdehaze.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index d36c876c2..e7bf71ba6 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -37,8 +37,6 @@ #include "procparams.h" #include "rescale.h" #include "rt_math.h" -#define BENCHMARK -#include "StopWatch.h" extern Options options; @@ -277,7 +275,7 @@ void ImProcFunctions::dehaze(Imagefloat *img) if (!params->dehaze.enabled || params->dehaze.strength == 0.0) { return; } -BENCHFUN + const float maxChannel = normalize(img, multiThread); const int W = img->getWidth(); From 5b72cc0dd3ce0288408ee0a1b0785f7c603a059e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Tue, 24 Sep 2019 09:59:31 +0200 Subject: [PATCH 222/222] Quote parameters correctly for Linux when spawning (#5463) --- rtgui/extprog.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc index a6a9050c0..95c1c937d 100644 --- a/rtgui/extprog.cc +++ b/rtgui/extprog.cc @@ -58,7 +58,7 @@ bool ExtProgAction::execute (const std::vector& fileNames) const } for (const auto& fileName : fileNames) { - cmdLine += " \"" + fileName + "\""; + cmdLine += " " + Glib::shell_quote(fileName); } return ExtProgStore::spawnCommandAsync (cmdLine); @@ -256,7 +256,7 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) #else - auto cmdLine = Glib::ustring("gimp \"") + fileName + Glib::ustring("\""); + auto cmdLine = Glib::ustring("gimp ") + Glib::shell_quote(fileName); auto success = spawnCommandAsync (cmdLine); #endif @@ -291,7 +291,7 @@ bool ExtProgStore::openInGimp (const Glib::ustring& fileName) #else - cmdLine = Glib::ustring("gimp-remote \"") + fileName + Glib::ustring("\""); + cmdLine = Glib::ustring("gimp-remote ") + Glib::shell_quote(fileName); success = ExtProgStore::spawnCommandAsync (cmdLine); #endif @@ -312,7 +312,7 @@ bool ExtProgStore::openInPhotoshop (const Glib::ustring& fileName) #else - const auto cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir, "Photoshop.exe") + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + const auto cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir, "Photoshop.exe") + "\" " + Glib::shell_quote(fileName); #endif @@ -334,7 +334,7 @@ bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName) #else - const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + fileName + Glib::ustring("\""); + const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + "\" " + Glib::shell_quote(fileName); return spawnCommandAsync (cmdLine); #endif