From c6c9ad5eef43586e219b1fa8239fb4f594c6a9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Mon, 2 Oct 2017 07:49:12 +0200 Subject: [PATCH 1/6] Sort HaldCLUT directories (fixes #4123) --- rtgui/filmsimulation.cc | 90 +++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/rtgui/filmsimulation.cc b/rtgui/filmsimulation.cc index a1471f970..716b686e9 100644 --- a/rtgui/filmsimulation.cc +++ b/rtgui/filmsimulation.cc @@ -1,3 +1,6 @@ +#include +#include + #include "filmsimulation.h" #include @@ -56,8 +59,6 @@ bool notifySlowParseDir (const std::chrono::system_clock::time_point& startedAt) } -typedef std::vector Strings; - FilmSimulation::FilmSimulation() : FoldableToolPanel( this, "filmsimulation", M("TP_FILMSIMULATION_LABEL"), false, true ) { @@ -216,13 +217,28 @@ int ClutComboBox::fillFromDir (const Glib::ustring& path) return result; } -int ClutComboBox::parseDir (const Glib::ustring& path) +int ClutComboBox::parseDir(const Glib::ustring& path) { - if (path.empty () || !Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) { + if (path.empty() || !Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) { return 0; } - const auto startedAt = std::chrono::system_clock::now (); + const auto sorted_dir_dirs = [](const Glib::ustring& path) -> std::map + { + std::map res; + + for (const auto& dir : Glib::Dir(path)) { + const std::string full_path = Glib::build_filename(path, dir); + + if (Glib::file_test(full_path, Glib::FILE_TEST_IS_DIR)) { + res.emplace(dir, full_path); + } + } + + return res; + }; + + const auto startedAt = std::chrono::system_clock::now(); // Build menu of limited directory structure using breadth-first search using Dirs = std::vector>; @@ -232,89 +248,77 @@ int ClutComboBox::parseDir (const Glib::ustring& path) Dirs currDirs; Dirs nextDirs; - currDirs.emplace_back (path, Gtk::TreeModel::Row ()); - - while (!currDirs.empty ()) { + currDirs.emplace_back(path, Gtk::TreeModel::Row()); + while (!currDirs.empty()) { for (auto& dir : currDirs) { - const auto& path = dir.first; const auto& row = dir.second; try { - for (const auto& entry : Glib::Dir (path)) { + for (const auto& entry : sorted_dir_dirs(path)) { + auto newRow = row ? *m_model->append(row.children()) : *m_model->append(); + newRow[m_columns.label] = entry.first; - const auto entryPath = Glib::build_filename (path, entry); - - if (!Glib::file_test (entryPath, Glib::FILE_TEST_IS_DIR)) { - continue; - } - - auto newRow = row ? *m_model->append (row.children ()) : *m_model->append (); - newRow[m_columns.label] = entry; - - nextDirs.emplace_back (entryPath, newRow); + nextDirs.emplace_back(entry.second, newRow); } } catch (Glib::Exception&) {} - dirs.push_back (std::move (dir)); + dirs.push_back(std::move(dir)); - if (!notifySlowParseDir (startedAt)) { - m_model->clear (); + if (!notifySlowParseDir(startedAt)) { + m_model->clear(); return 0; } } - currDirs.clear (); - currDirs.swap (nextDirs); + currDirs.clear(); + currDirs.swap(nextDirs); } } // Fill menu structure with CLUT files - Strings entries; + std::set entries; - auto fileCount = 0; + unsigned long fileCount = 0; for (const auto& dir : dirs) { - const auto& path = dir.first; const auto& row = dir.second; - entries.clear (); + entries.clear(); try { - for (const auto& entry : Glib::Dir (path)) { + for (const auto& entry : Glib::Dir(path)) { + const auto entryPath = Glib::build_filename(path, entry); - const auto entryPath = Glib::build_filename (path, entry); - - if (!Glib::file_test (entryPath, Glib::FILE_TEST_IS_REGULAR)) { + if (!Glib::file_test(entryPath, Glib::FILE_TEST_IS_REGULAR)) { continue; } - entries.push_back (entryPath); + entries.insert(entryPath); } } catch (Glib::Exception&) {} - std::sort (entries.begin (), entries.end ()); - for (const auto& entry : entries) { - - Glib::ustring name, extension, profileName; + Glib::ustring name; + Glib::ustring extension; + Glib::ustring profileName; HaldCLUT::splitClutFilename (entry, name, extension, profileName); - extension = extension.casefold (); - if (extension.compare ("tif") != 0 && extension.compare ("png") != 0) { + extension = extension.casefold(); + if (extension.compare("tif") != 0 && extension.compare("png") != 0) { continue; } - auto newRow = row ? *m_model->append (row.children ()) : *m_model->append (); + auto newRow = row ? *m_model->append(row.children()) : *m_model->append(); newRow[m_columns.label] = name; newRow[m_columns.clutFilename] = entry; ++fileCount; - if (!notifySlowParseDir (startedAt)) { - m_model->clear (); + if (!notifySlowParseDir(startedAt)) { + m_model->clear(); return 0; } } From da2b09925f40e35bd53add672f6584cd78916e68 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Tue, 3 Oct 2017 14:38:30 -0700 Subject: [PATCH 2/6] AppleLocale / executable loader fix Ref: https://github.com/Beep6581/RawTherapee/issues/4128 https://discuss.pixls.us/t/error-processing-queue-invalid-byte-sequence-in-conversion-input/1188/18 --- tools/osx/executable_loader.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/osx/executable_loader.in b/tools/osx/executable_loader.in index c36695d9e..b6025fe59 100644 --- a/tools/osx/executable_loader.in +++ b/tools/osx/executable_loader.in @@ -48,4 +48,7 @@ esac #fi #ln -sf "${app}" /tmp +AppleLocale=`defaults read -g AppleLocale` +export LANG=${AppleLocale%@*}.UTF-8 + exec "${cwd}/rawtherapee-bin" "$@" From e4f24fff9c0bb48c260d23c4fa435a7f1970d817 Mon Sep 17 00:00:00 2001 From: PkmX Date: Wed, 4 Oct 2017 19:36:25 +0800 Subject: [PATCH 3/6] Fix missing filename after closing save-as dialog Currently, if you open the save as dialog, press ESC to close the dialog and then re-open it, the filename is cleared to `"."`. This patch sets `SaveAsDlg::fname` so RT always gets the original filename back even if the dialog is dismissed. --- rtgui/saveasdlg.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc index 865373b60..1818d748a 100644 --- a/rtgui/saveasdlg.cc +++ b/rtgui/saveasdlg.cc @@ -299,7 +299,7 @@ void SaveAsDialog::formatChanged (Glib::ustring f) void SaveAsDialog::setInitialFileName (Glib::ustring fname) { - + this->fname = fname; fchooser->set_current_name(fname); } From 2f32afa841631b5774316c004828bcacdd6b422e Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 8 Oct 2017 15:36:31 +0200 Subject: [PATCH 4/6] Raw CA correction created an artifact, fixes #4116 --- rtengine/CA_correct_RT.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index ec598b6ca..59fd804f1 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -824,7 +824,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const } if (rrmax < rr1) { - for (int rr = 0; rr < border; rr++) + for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) for (int cc = ccmin; cc < ccmax; cc++) { int c = FC(rr, cc); rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][left + cc]) / 65535.f; @@ -845,7 +845,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const if (ccmax < cc1) { for (int rr = rrmin; rr < rrmax; rr++) - for (int cc = 0; cc < border; cc++) { + for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { int c = FC(rr, cc); rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(top + rr)][(width - cc - 2)]) / 65535.f; if ((c & 1) == 0) { @@ -867,8 +867,8 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const } if (rrmax < rr1 && ccmax < cc1) { - for (int rr = 0; rr < border; rr++) - for (int cc = 0; cc < border; cc++) { + for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) + for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { int c = FC(rr, cc); rgb[c][((rrmax + rr)*ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][(width - cc - 2)]) / 65535.f; if ((c & 1) == 0) { @@ -879,7 +879,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const if (rrmin > 0 && ccmax < cc1) { for (int rr = 0; rr < border; rr++) - for (int cc = 0; cc < border; cc++) { + for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { int c = FC(rr, cc); rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(border2 - rr)][(width - cc - 2)]) / 65535.f; if ((c & 1) == 0) { @@ -889,7 +889,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const } if (rrmax < rr1 && ccmin > 0) { - for (int rr = 0; rr < border; rr++) + for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][(border2 - cc)]) / 65535.f; From d84a3fd40ae5bf8af0bb4801e862f6e177fe8e5b Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 8 Oct 2017 17:27:39 +0200 Subject: [PATCH 5/6] Improve start time of rawtherapee when Dark-frames and Flat-fileds directories are set at default (windows), fixes #4103 --- rtengine/dfmanager.cc | 51 +++++++++++++++++++----------------------- rtengine/ffmanager.cc | 52 +++++++++++++++++++------------------------ 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index bc35b3c71..b9841c86b 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -334,41 +334,36 @@ void DFManager::init( Glib::ustring pathname ) dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool) { - auto file = Gio::File::create_for_path (filename); + auto ext = getFileExtension(filename); + + if (ext.empty() || !options.is_extention_enabled(ext)) { + return nullptr; + } + + auto file = Gio::File::create_for_path(filename); if (!file) { return nullptr; } - if (!file->query_exists ()) { + if (!file->query_exists()) { return nullptr; } try { - auto info = file->query_info (); + auto info = file->query_info("standard::name,standard::type,standard::is-hidden"); - if (!info && info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) { + if (!info && info->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { return nullptr; } - if (!options.fbShowHidden && info->is_hidden ()) { + if (!options.fbShowHidden && info->is_hidden()) { return nullptr; } - Glib::ustring ext; - - 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 nullptr; - } - - RawImage ri (filename); - int res = ri.loadRaw (false); // Read informations about shot + RawImage ri(filename); + int res = ri.loadRaw(false); // Read informations about shot if (res != 0) { return nullptr; @@ -378,7 +373,7 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool) if(!pool) { dfInfo n(filename, "", "", 0, 0, 0); - iter = dfList.insert(std::pair< std::string, dfInfo>( "", n ) ); + iter = dfList.emplace("", n); return &(iter->second); } @@ -388,22 +383,22 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool) rml.ciffLength = ri.get_ciffLen(); ImageData idata(filename, &rml); /* Files are added in the map, divided by same maker/model,ISO and shutter*/ - std::string key( dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed()) ); - iter = dfList.find( key ); + std::string key(dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed())); + iter = dfList.find(key); - if( iter == dfList.end() ) { - dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS() ); - iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) ); + if(iter == dfList.end()) { + dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS()); + iter = dfList.emplace(key, n); } else { - while( iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6 ) { // 6 hour difference + while(iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6) { // 6 hour difference ++iter; } - if( iter != dfList.end() ) { - iter->second.pathNames.push_back( filename ); + if(iter != dfList.end()) { + iter->second.pathNames.push_back(filename); } else { dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS()); - iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) ); + iter = dfList.emplace(key, n); } } diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 87ae98905..d0edffb17 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -21,6 +21,7 @@ #include "rawimage.h" #include "imagedata.h" #include "median.h" +#include "utils.h" namespace rtengine { @@ -288,43 +289,36 @@ void FFManager::init( Glib::ustring pathname ) ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) { - auto file = Gio::File::create_for_path (filename); + auto ext = getFileExtension(filename); + + if (ext.empty() || !options.is_extention_enabled(ext)) { + return nullptr; + } + + auto file = Gio::File::create_for_path(filename); if (!file ) { return nullptr; } - if (!file->query_exists ()) { + if (!file->query_exists()) { return nullptr; } try { - auto info = file->query_info (); + auto info = file->query_info("standard::name,standard::type,standard::is-hidden"); - if (!info || info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) { + if (!info || info->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { return nullptr; } - if (!options.fbShowHidden && info->is_hidden ()) { + if (!options.fbShowHidden && info->is_hidden()) { return nullptr; } - Glib::ustring ext; - - 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 nullptr; - } - - - RawImage ri (filename); - int res = ri.loadRaw (false); // Read informations about shot + RawImage ri(filename); + int res = ri.loadRaw(false); // Read informations about shot if (res != 0) { return nullptr; @@ -334,7 +328,7 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) if(!pool) { ffInfo n(filename, "", "", "", 0, 0, 0); - iter = ffList.insert(std::pair< std::string, ffInfo>( "", n ) ); + iter = ffList.emplace("", n); return &(iter->second); } @@ -344,22 +338,22 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) rml.ciffLength = ri.get_ciffLen(); ImageData idata(filename, &rml); /* Files are added in the map, divided by same maker/model,lens and aperture*/ - std::string key( ffInfo::key(idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber()) ); - iter = ffList.find( key ); + std::string key(ffInfo::key(idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber())); + iter = ffList.find(key); - if( iter == ffList.end() ) { + if(iter == ffList.end()) { ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS()); - iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) ); + iter = ffList.emplace(key, n); } else { - while( iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) > 60 * 60 * 6 ) { // 6 hour difference + while(iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) > 60 * 60 * 6) { // 6 hour difference ++iter; } - if( iter != ffList.end() ) { - iter->second.pathNames.push_back( filename ); + if(iter != ffList.end()) { + iter->second.pathNames.push_back(filename); } else { ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS()); - iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) ); + iter = ffList.emplace(key, n); } } From 1fdc2d7b49327c9e08ca037d04a51a7c22e159cd Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 9 Oct 2017 09:46:00 +0200 Subject: [PATCH 6/6] dcraw: do not use CameraCalibration matrices when loading DNG files This is to make sure that DNG-converted and original raw files are processed in the same way Fixes #4129 --- rtengine/dcraw.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index f8918896b..f59f5b2fe 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6244,6 +6244,16 @@ guess_cfa_pc: free (buf); } + /* RT -- do not use CameraCalibration matrices for DNGs - see #4129 */ + for (j=0; j < 4; j++) { + ab[j] = 1; + for (i=0; i < 4; i++) { + cc[0][j][i] = i == j; + cc[1][j][i] = i == j; + } + } + /* RT end */ + for (i=0; i < colors; i++) FORCC cc[cm_D65][i][c] *= ab[i]; if (use_cm) {