From 594b4f9b6e344434436c448ac282323b42da8f3a Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 29 Nov 2015 10:25:12 +0100 Subject: [PATCH 01/16] Reenable the colorimetric intent selector on the color management tab, but display it below the monitor profile to indicate that this is the only place where it is used. --- rtengine/improcfun.cc | 4 ++-- rtgui/preferences.cc | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 8180c353f..337b5935f 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -223,7 +223,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par if (monitor) { lcmsMutex->lock (); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; @@ -236,7 +236,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } } diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index f6feef35f..5c85ea18f 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -687,14 +687,12 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_border_width (4); - /* Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":", Gtk::ALIGN_LEFT)); intent = Gtk::manage (new Gtk::ComboBoxText ()); intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); intent->append_text (M("PREFERENCES_INTENT_SATURATION")); intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); - */ iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_LEFT)); @@ -720,17 +718,21 @@ Gtk::Widget* Preferences::getColorManagementPanel () #endif Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2)); - //colt->attach (*intlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); - //colt->attach (*intent, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); - colt->attach (*pdlabel, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*iccDir, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + int row = 0; + colt->attach (*pdlabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*iccDir, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #if !defined(__APPLE__) // monitor profile not supported on apple - colt->attach (*mplabel, 0, 1, 2, 3, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*monProfile, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + ++row; + colt->attach (*mplabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*monProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #if defined(WIN32) - colt->attach (*cbAutoMonProfile, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + ++row; + colt->attach (*cbAutoMonProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #endif #endif + ++row; + colt->attach (*intlab, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*intent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); #if defined(WIN32) @@ -1438,7 +1440,7 @@ void Preferences::storePreferences () moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif moptions.rtSettings.iccDirectory = iccDir->get_filename (); - //moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); + moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); moptions.rtSettings.viewingdevice = view->get_active_row_number (); moptions.rtSettings.viewingdevicegrey = grey->get_active_row_number (); moptions.rtSettings.viewinggreySc = greySc->get_active_row_number (); @@ -1567,7 +1569,7 @@ void Preferences::fillPreferences () iccDir->set_current_folder (moptions.rtSettings.iccDirectory); } - //intent->set_active (moptions.rtSettings.colorimetricIntent); + intent->set_active (moptions.rtSettings.colorimetricIntent); view->set_active (moptions.rtSettings.viewingdevice); grey->set_active (moptions.rtSettings.viewingdevicegrey); greySc->set_active (moptions.rtSettings.viewinggreySc); From 35919bddc9947f81850efcb0e7c773eff44f2993 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Mon, 30 Nov 2015 21:23:22 +0100 Subject: [PATCH 02/16] Copy-edit the ICC store for better performance and maintainability and add a method to load profile lists from arbitrary directories. --- rtengine/iccstore.cc | 382 ++++++++++++++++++++------------------ rtengine/iccstore.h | 137 ++++++++++---- rtengine/improcfun.cc | 2 +- rtengine/simpleprocess.cc | 2 +- rtgui/icmpanel.cc | 2 +- 5 files changed, 300 insertions(+), 225 deletions(-) diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index bad4e8dfa..24f2bb936 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -29,9 +29,90 @@ #include -namespace rtengine +namespace { +void loadProfiles (const Glib::ustring& dirName, + std::map* profiles, + std::map* profileContents, + std::map* profileNames, + bool nameUpper, bool onlyRgb) +{ + if (dirName.empty ()) + return; + + try { + + Glib::Dir dir (dirName); + + for (Glib::DirIterator entry = dir.begin (); entry != dir.end (); ++entry) { + + const Glib::ustring fileName = *entry; + + if (fileName.size () < 4) + continue; + + const Glib::ustring extension = fileName.substr (fileName.size () - 4).casefold (); + + if (extension.compare(".icc") == 0 && extension.compare(".icm") == 0) + continue; + + const Glib::ustring filePath = Glib::build_filename (dirName, fileName); + + if (!safe_file_test (filePath, Glib::FILE_TEST_IS_REGULAR)) + continue; + + Glib::ustring name = fileName.substr (0, fileName.size() - 4); + + if (nameUpper) + name = name.uppercase (); + + if (profiles) { + const rtengine::ProfileContent content (filePath); + const cmsHPROFILE profile = content.toProfile (); + + if (profile && (!onlyRgb || cmsGetColorSpace (profile) == cmsSigRgbData)) { + profiles->insert (std::make_pair (name, profile)); + + if (profileContents) + profileContents->insert (std::make_pair (name, content)); + } + } + + if (profileNames) + profileNames->insert (std::make_pair (name, filePath)); + } + } + catch (Glib::Exception&) {} +} + +inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, std::uint8_t& result) +{ + if (cmsIsIntentSupported (profile, intent, direction)) + result |= 1 << intent; +} + +inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction) +{ + if (!profile) + return 0; + + std::uint8_t result = 0; + + getSupportedIntent (profile, INTENT_PERCEPTUAL, direction, result); + getSupportedIntent (profile, INTENT_RELATIVE_COLORIMETRIC, direction, result); + getSupportedIntent (profile, INTENT_SATURATION, direction, result); + getSupportedIntent (profile, INTENT_ABSOLUTE_COLORIMETRIC, direction, result); + + return result; +} + +inline cmsHPROFILE createXYZProfile () +{ + double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0} }; + return rtengine::ICCStore::createFromMatrix (mat, false, "XYZ"); +} + const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best}; const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz}; const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; @@ -43,8 +124,12 @@ const char* wpgamma[] = {"default", "BT709_g2.2_s4.5", "sRGB_g2.4_s12.92", "line // high g=1.3 s=3.35 for high dynamic images //low g=2.6 s=6.9 for low contrast images +} -std::vector getGamma () //return gamma +namespace rtengine +{ + +std::vector getGamma () { std::vector res; @@ -56,7 +141,6 @@ std::vector getGamma () //return gamma return res; } - std::vector getWorkingProfiles () { @@ -69,32 +153,38 @@ std::vector getWorkingProfiles () return res; } -std::vector ICCStore::getOutputProfiles () +std::vector ICCStore::getProfiles () const { MyMutex::MyLock lock(mutex_); std::vector res; - for (std::map::iterator i = fileProfiles.begin(); i != fileProfiles.end(); i++) { - Glib::ustring name(i->first); - std::string::size_type i2 = name.find_last_of('/'); - - if( i2 == std::string::npos ) { - i2 = name.find_last_of('\\'); - } - - if( i2 == std::string::npos ) { - res.push_back ( name ); // list only profiles inside selected profiles directory - } - } + for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) + res.push_back (profile->first); return res; } +std::vector ICCStore::getProfilesFromDir (const Glib::ustring& dirName) const +{ -cmsHPROFILE -ICCStore::makeStdGammaProfile(cmsHPROFILE iprof) + MyMutex::MyLock lock(mutex_); + + std::vector res; + + ProfileMap profiles; + + loadProfiles (profilesDir, &profiles, NULL, NULL, false, true); + loadProfiles (dirName, &profiles, NULL, NULL, false, true); + + for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + res.push_back (profile->first); + + return res; +} + +cmsHPROFILE ICCStore::makeStdGammaProfile (cmsHPROFILE iprof) { // forgive me for the messy code, quick hack to change gamma of an ICC profile to the RT standard gamma if (!iprof) { @@ -189,14 +279,15 @@ ICCStore::makeStdGammaProfile(cmsHPROFILE iprof) return oprof; } -ICCStore* -ICCStore::getInstance(void) +ICCStore* ICCStore::getInstance () { static ICCStore instance_; return &instance_; } -ICCStore::ICCStore () +ICCStore::ICCStore () : + xyz (createXYZProfile ()), + srgb (cmsCreate_sRGBProfile ()) { //cmsErrorAction (LCMS_ERROR_SHOW); @@ -208,234 +299,172 @@ ICCStore::ICCStore () wMatrices[wpnames[i]] = wprofiles[i]; iwMatrices[wpnames[i]] = iwprofiles[i]; } - - double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}}; - xyz = createFromMatrix (mat, false, "XYZ"); - srgb = cmsCreate_sRGBProfile (); } -int ICCStore::numOfWProfiles () +TMatrix ICCStore::workingSpaceMatrix (const Glib::ustring& name) const { - return sizeof(wpnames) / sizeof(wpnames[0]); -} - -TMatrix ICCStore::workingSpaceMatrix (Glib::ustring name) -{ - - std::map::iterator r = wMatrices.find (name); + const MatrixMap::const_iterator r = wMatrices.find (name); if (r != wMatrices.end()) { return r->second; } else { - return wMatrices["sRGB"]; + return wMatrices.find ("sRGB")->second; } } -TMatrix ICCStore::workingSpaceInverseMatrix (Glib::ustring name) +TMatrix ICCStore::workingSpaceInverseMatrix (const Glib::ustring& name) const { - std::map::iterator r = iwMatrices.find (name); + const MatrixMap::const_iterator r = iwMatrices.find (name); if (r != iwMatrices.end()) { return r->second; } else { - return iwMatrices["sRGB"]; + return iwMatrices.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::workingSpace (Glib::ustring name) +cmsHPROFILE ICCStore::workingSpace (const Glib::ustring& name) const { - std::map::iterator r = wProfiles.find (name); + const ProfileMap::const_iterator r = wProfiles.find (name); if (r != wProfiles.end()) { return r->second; } else { - return wProfiles["sRGB"]; + return wProfiles.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::workingSpaceGamma (Glib::ustring name) +cmsHPROFILE ICCStore::workingSpaceGamma (const Glib::ustring& name) const { - std::map::iterator r = wProfilesGamma.find (name); + const ProfileMap::const_iterator r = wProfilesGamma.find (name); if (r != wProfilesGamma.end()) { return r->second; } else { - return wProfilesGamma["sRGB"]; + return wProfilesGamma.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::getProfile (Glib::ustring name) +cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const { MyMutex::MyLock lock(mutex_); - std::map::iterator r = fileProfiles.find (name); + const ProfileMap::const_iterator r = fileProfiles.find (name); - if (r != fileProfiles.end()) { + if (r != fileProfiles.end ()) return r->second; - } else { - if (!name.compare (0, 5, "file:") && safe_file_test (name.substr(5), Glib::FILE_TEST_EXISTS) && !safe_file_test (name.substr(5), Glib::FILE_TEST_IS_DIR)) { - ProfileContent pc (name.substr(5)); - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); + if (name.compare (0, 5, "file:") == 0) { + const ProfileContent content (name.substr (5)); + const cmsHPROFILE profile = content.toProfile (); - if (profile) { - fileProfiles[name] = profile; - fileProfileContents[name] = pc; - return profile; - } - } + if (profile) { + const_cast(fileProfiles).insert(std::make_pair(name, profile)); + const_cast(fileProfileContents).insert(std::make_pair(name, content)); + + return profile; } } return NULL; } -cmsHPROFILE ICCStore::getStdProfile (Glib::ustring name) +cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const { + const Glib::ustring nameUpper = name.uppercase (); + MyMutex::MyLock lock(mutex_); - std::map::iterator r = fileStdProfiles.find (name.uppercase()); + const ProfileMap::const_iterator r = fileStdProfiles.find (nameUpper); - if (r == fileStdProfiles.end()) { - // profile is not yet in store - std::map::iterator f = fileStdProfilesFileNames.find (name.uppercase()); - - if(f != fileStdProfilesFileNames.end()) { - // but there exists one => load it - ProfileContent pc (f->second); - - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); - - if (profile) { - fileStdProfiles[name.uppercase()] = profile; - } - - // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames - fileStdProfilesFileNames.erase(f); - return profile; - } else { - // profile not valid => remove entry from fileStdProfilesFileNames - fileStdProfilesFileNames.erase(f); - return NULL; - } - } else { - // profile does not exist - return NULL; - } - } else { - // return profile from store + // return profile from store + if (r != fileStdProfiles.end ()) return r->second; - } + + // profile is not yet in store + const NameMap::const_iterator f = fileStdProfilesFileNames.find (nameUpper); + + // profile does not exist + if (f == fileStdProfilesFileNames.end ()) + return NULL; + + // but there exists one => load it + const ProfileContent content (f->second); + const cmsHPROFILE profile = content.toProfile (); + + if (profile) + const_cast(fileStdProfiles).insert (std::make_pair (f->first, profile)); + + // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames + const_cast(fileStdProfilesFileNames).erase (f); + return profile; } -ProfileContent ICCStore::getContent (Glib::ustring name) +ProfileContent ICCStore::getContent (const Glib::ustring& name) const { MyMutex::MyLock lock(mutex_); - return fileProfileContents[name]; + const ContentMap::const_iterator r = fileProfileContents.find (name); + + return r != fileProfileContents.end () ? r->second : ProfileContent(); +} + +std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_INPUT); +} + +std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT); +} + +std::uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_PROOF); } // Reads all profiles from the given profiles dir -void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) +void ICCStore::init (const Glib::ustring& usrICCDir, const Glib::ustring& rtICCDir) { MyMutex::MyLock lock(mutex_); - // + // RawTherapee's profiles take precedence if a user's profile of the same name exists + profilesDir = Glib::build_filename (rtICCDir, "output"); fileProfiles.clear(); fileProfileContents.clear(); - // RawTherapee's profiles take precedence if a user's profile of the same name exists - loadICCs(Glib::build_filename(rtICCDir, "output"), false, fileProfiles, &fileProfileContents, true, true); - loadICCs(usrICCDir, false, fileProfiles, &fileProfileContents, true, true); + loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, NULL, false, true); + loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, NULL, false, true); // Input profiles // Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir) + stdProfilesDir = Glib::build_filename (rtICCDir, "input"); fileStdProfiles.clear(); fileStdProfilesFileNames.clear(); - loadICCs(Glib::build_filename(rtICCDir, "input"), true, fileStdProfiles, NULL); -} - -void ICCStore::loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch, bool onlyRgb) -{ - if (rootDirName != "") { - std::deque qDirs; - - qDirs.push_front(rootDirName); - - while (!qDirs.empty()) { - // process directory - Glib::ustring dirname = qDirs.back(); - qDirs.pop_back(); - - Glib::Dir* dir = NULL; - - try { - if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) { - return; - } - - dir = new Glib::Dir (dirname); - } catch (Glib::Exception& fe) { - return; - } - - dirname = dirname + "/"; - - for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) { - Glib::ustring fname = dirname + *i; - Glib::ustring sname = *i; - - // ignore directories - if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { - size_t lastdot = sname.find_last_of ('.'); - - if (lastdot != Glib::ustring::npos && lastdot <= sname.size() - 4 && (!sname.casefold().compare (lastdot, 4, ".icm") || !sname.casefold().compare (lastdot, 4, ".icc"))) { - Glib::ustring name = nameUpper ? sname.substr(0, lastdot).uppercase() : sname.substr(0, lastdot); - - if(!prefetch) { - fileStdProfilesFileNames[name] = fname; - } else { - ProfileContent pc (fname); - - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); - - if (profile && (!onlyRgb || cmsGetColorSpace(profile) == cmsSigRgbData)) { - resultProfiles[name] = profile; - - if(resultProfileContents) { - (*resultProfileContents)[name] = pc; - } - } - } - } - } - } - - // Removed recursive scanning, see issue #1730. - // To revert to the recursive method, just uncomment the next line. - - //else qDirs.push_front(fname); // for later scanning - } - - delete dir; - } - } + loadProfiles (stdProfilesDir, NULL, NULL, &fileStdProfilesFileNames, true, false); } // Determine the first monitor default profile of operating system, if selected -void ICCStore::findDefaultMonitorProfile() +void ICCStore::findDefaultMonitorProfile () { - defaultMonitorProfile = ""; + defaultMonitorProfile.clear (); #ifdef WIN32 // Get current main monitor. Could be fine tuned to get the current windows monitor (multi monitor setup), @@ -466,7 +495,7 @@ void ICCStore::findDefaultMonitorProfile() } } -ProfileContent::ProfileContent (Glib::ustring fileName) : data(NULL), length(0) +ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(NULL), length(0) { FILE* f = safe_g_fopen (fileName, "rb"); @@ -518,9 +547,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other) length = other.length; - if (data) { - delete [] data; - } + delete [] data; if (other.data) { data = new char[length + 1]; @@ -532,15 +559,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other) return *this; } -ProfileContent::~ProfileContent () -{ - - if (data) { - delete [] data; - } -} - -cmsHPROFILE ProfileContent::toProfile () +cmsHPROFILE ProfileContent::toProfile () const { if (data) { @@ -550,7 +569,7 @@ cmsHPROFILE ProfileContent::toProfile () } } -cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, Glib::ustring name) +cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, const Glib::ustring& name) { static const unsigned phead[] = { @@ -644,4 +663,5 @@ cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, G delete [] oprof; return p; } + } diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index acb31e4cf..524db9cd2 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -37,74 +37,129 @@ public: char* data; int length; - ProfileContent (): data(NULL), length(0) {} - ProfileContent (Glib::ustring fileName); - ProfileContent (const ProfileContent& other); - ProfileContent (cmsHPROFILE hProfile); + ProfileContent (); ~ProfileContent (); + + ProfileContent (const ProfileContent& other); ProfileContent& operator= (const rtengine::ProfileContent& other); - cmsHPROFILE toProfile (); + + ProfileContent (const Glib::ustring& fileName); + ProfileContent (cmsHPROFILE hProfile); + cmsHPROFILE toProfile () const; }; class ICCStore { + typedef std::map ProfileMap; + typedef std::map MatrixMap; + typedef std::map ContentMap; + typedef std::map NameMap; - std::map wProfiles; - std::map wProfilesGamma; - std::map wMatrices; - std::map iwMatrices; + ProfileMap wProfiles; + ProfileMap wProfilesGamma; + MatrixMap wMatrices; + MatrixMap iwMatrices; // these contain profiles from user/system directory (supplied on init) - std::map fileProfiles; - std::map fileProfileContents; + Glib::ustring profilesDir; + ProfileMap fileProfiles; + ContentMap fileProfileContents; // these contain standard profiles from RT. keys are all in uppercase - std::map fileStdProfilesFileNames; - std::map fileStdProfiles; + Glib::ustring stdProfilesDir; + NameMap fileStdProfilesFileNames; + ProfileMap fileStdProfiles; - cmsHPROFILE xyz; - cmsHPROFILE srgb; + Glib::ustring defaultMonitorProfile; - MyMutex mutex_; + const cmsHPROFILE xyz; + const cmsHPROFILE srgb; + + mutable MyMutex mutex_; ICCStore (); - void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch = false, bool onlyRgb = false); public: - static ICCStore* getInstance(void); - static cmsHPROFILE makeStdGammaProfile(cmsHPROFILE iprof); + static ICCStore* getInstance (); - Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS - void findDefaultMonitorProfile(); + void init (const Glib::ustring& usrICCDir, const Glib::ustring& stdICCDir); - int numOfWProfiles (); - cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, Glib::ustring name = ""); - cmsHPROFILE workingSpace (Glib::ustring name); - cmsHPROFILE workingSpaceGamma (Glib::ustring name); - TMatrix workingSpaceMatrix (Glib::ustring name); - TMatrix workingSpaceInverseMatrix (Glib::ustring name); + static cmsHPROFILE makeStdGammaProfile (cmsHPROFILE iprof); + static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring()); - cmsHPROFILE getProfile (Glib::ustring name); - cmsHPROFILE getStdProfile(Glib::ustring name); + // Main monitors standard profile name, from OS + const Glib::ustring& getDefaultMonitorProfile () const; + void findDefaultMonitorProfile (); - void init (Glib::ustring usrICCDir, Glib::ustring stdICCDir); - ProfileContent getContent (Glib::ustring name); + cmsHPROFILE workingSpace (const Glib::ustring& name) const; + cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; + TMatrix workingSpaceMatrix (const Glib::ustring& name) const; + TMatrix workingSpaceInverseMatrix (const Glib::ustring& name) const; - cmsHPROFILE getXYZProfile () - { - return xyz; - } - cmsHPROFILE getsRGBProfile () - { - return srgb; - } - std::vector getOutputProfiles (); + cmsHPROFILE getProfile (const Glib::ustring& name) const; + cmsHPROFILE getStdProfile (const Glib::ustring& name) const; + ProfileContent getContent (const Glib::ustring& name) const; + + cmsHPROFILE getXYZProfile () const; + cmsHPROFILE getsRGBProfile () const; + + std::vector getProfiles () const; + std::vector getProfilesFromDir (const Glib::ustring& dirName) const; + + std::uint8_t getInputIntents (cmsHPROFILE profile) const; + std::uint8_t getOutputIntents (cmsHPROFILE profile) const; + std::uint8_t getProofIntents (cmsHPROFILE profile) const; + + std::uint8_t getInputIntents (const Glib::ustring& name) const; + std::uint8_t getOutputIntents (const Glib::ustring& name) const; + std::uint8_t getProofIntents (const Glib::ustring& name) const; }; #define iccStore ICCStore::getInstance() -//extern const char* wpnames[]; +inline ProfileContent::ProfileContent () : + data(NULL), + length(0) +{ } + +inline ProfileContent::~ProfileContent () +{ + delete [] data; +} + +inline const Glib::ustring& ICCStore::getDefaultMonitorProfile () const +{ + return defaultMonitorProfile; +} + +inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const +{ + return getInputIntents (getProfile (name)); +} + +inline std::uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const +{ + return getOutputIntents (getProfile (name)); +} + +inline std::uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const +{ + return getProofIntents (getProfile (name)); +} + +inline cmsHPROFILE ICCStore::getXYZProfile () const +{ + return xyz; +} + +inline cmsHPROFILE ICCStore::getsRGBProfile () const +{ + return srgb; +} + +} + #endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 337b5935f..62255cd39 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -213,7 +213,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par #if defined(WIN32) if (settings->autoMonitorProfile) { - monitorProfile = iccStore->defaultMonitorProfile; + monitorProfile = iccStore->getDefaultMonitorProfile (); } #endif diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 91b7df178..5ea834b2d 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1159,7 +1159,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p bool pro = false; Glib::ustring chpro, outProfile; bool present_space[9] = {false, false, false, false, false, false, false, false, false}; - std::vector opnames = iccStore->getOutputProfiles (); + std::vector opnames = iccStore->getProfiles (); //test if files are in system for (int j = 0; j < 9; j++) { diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index e9e4e05ff..51ee408a2 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -185,7 +185,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->append_text (M("TP_ICM_NOICM")); onames->set_active (0); - std::vector opnames = iccStore->getOutputProfiles (); + std::vector opnames = iccStore->getProfiles (); for (size_t i = 0; i < opnames.size(); i++) { onames->append_text (opnames[i]); From 22bffabe7fed331fa913c605490a79b471fa9a1b Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Mon, 30 Nov 2015 21:24:26 +0100 Subject: [PATCH 03/16] Extend the editor panel to support selection of a monitor profile and rendering intent and extend the preferences to provide a default profile and intent for the editor panel. --- rtdata/languages/default | 5 ++- rtengine/improcfun.cc | 21 ++++----- rtengine/procparams.cc | 2 + rtengine/procparams.h | 2 + rtengine/settings.h | 4 +- rtgui/editorpanel.cc | 97 +++++++++++++++++++++++++++++++++++++++- rtgui/editorpanel.h | 4 ++ rtgui/guiutils.h | 7 +++ rtgui/options.cc | 8 ++-- rtgui/preferences.cc | 77 +++++++++++++++++-------------- rtgui/preferences.h | 7 +-- 11 files changed, 178 insertions(+), 56 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 84586340e..9c703954a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -886,7 +886,7 @@ PREFERENCES_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs PREFERENCES_CLUTSDIR;HaldCLUT directory -PREFERENCES_CMETRICINTENT;Colorimetric intent +PREFERENCES_MONINTENT;Default monitor intent PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons PREFERENCES_CURVEBBOXPOS_ABOVE;Above PREFERENCES_CURVEBBOXPOS_BELOW;Below @@ -981,7 +981,7 @@ PREFERENCES_MENUGROUPRANK;Group "Rank" PREFERENCES_MENUOPTIONS;Context Menu Options PREFERENCES_METADATA;Metadata PREFERENCES_MIN;Mini (100x115) -PREFERENCES_MONITORICC;Monitor color profile +PREFERENCES_MONPROFILE;Default monitor profile PREFERENCES_MULTITAB;Multiple Editor Tabs Mode PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode PREFERENCES_NAVGUIDEBRUSH;Navigator guide color @@ -1010,6 +1010,7 @@ PREFERENCES_PROFILEPRCACHE;Profile in cache PREFERENCES_PROFILEPRFILE;Profile next to the input file PREFERENCES_PROFILESAVECACHE;Save processing profile to the cache PREFERENCES_PROFILESAVEINPUT;Save processing profile next to the input file +PREFERENCES_PROFILE_NONE;None PREFERENCES_PROPERTY;Property PREFERENCES_PSPATH;Adobe Photoshop installation directory PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 62255cd39..4306d4a6e 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -209,21 +209,23 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par lab2outputTransform = NULL; #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB - Glib::ustring monitorProfile = settings->monitorProfile; + #if defined(WIN32) - if (settings->autoMonitorProfile) { - monitorProfile = iccStore->getDefaultMonitorProfile (); - } + cmsHPROFILE monitor = iccStore->getProfile (settings->autoMonitorProfile + ? iccStore->getDefaultMonitorProfile () + : params->icm.monitorProfile); + +#else + + cmsHPROFILE monitor = iccStore->getProfile (params->icm.monitorProfile); #endif - cmsHPROFILE monitor = iccStore->getProfile ("file:" + monitorProfile); - if (monitor) { - lcmsMutex->lock (); + MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; @@ -236,13 +238,12 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } } cmsCloseProfile(iprof); - lcmsMutex->unlock (); } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index becd8932e..44c02a531 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -894,6 +894,8 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; + monitorProfile = Glib::ustring (); + monitorIntent = 1; gamma = "default"; gampos = 2.22; slpos = 4.5; diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d46fd4181..77c1004e8 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -941,6 +941,8 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; + Glib::ustring monitorProfile; // Not stored persistently as it is just an optional settings override. + int monitorIntent; // Not store persistently as it is just an optional settings override. static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/settings.h b/rtengine/settings.h index 373103d07..bd37faaf2 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -27,7 +27,6 @@ class Settings { public: Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles - int colorimetricIntent; ///< Colorimetric intent used at color space conversions int viewingdevice; // white of output device (D50...D65..) int viewingdevicegrey; // level of grey output device int viewinggreySc; // level of grey Scene @@ -37,7 +36,8 @@ public: int leveldnliss; // level of auto multi zone int leveldnautsimpl; // STD or EXPERT - Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) + Glib::ustring monitorProfile; ///< ICC profile name used for the monitor + int monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 82e8d9fcf..c6d2804c1 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -25,12 +25,102 @@ #include "procparamchangers.h" #include "../rtengine/safegtk.h" #include "../rtengine/imagesource.h" +#include "../rtengine/iccstore.h" #include "soundman.h" #include "rtimage.h" #include using namespace rtengine::procparams; +class MonitorProfileSelector +{ +private: + Gtk::ComboBoxText profileBox; + Gtk::ComboBoxText intentBox; + + rtengine::StagedImageProcessor* const& processor; + +private: + MonitorProfileSelector(const MonitorProfileSelector&); + MonitorProfileSelector& operator=(const MonitorProfileSelector&); + + void prepareProfileBox () + { + profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); + profileBox.set_active (0); + + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); + for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) + profileBox.append_text (*iterator); + } + + void prepareIntentBox () + { + intentBox.append_text (M("PREFERENCES_INTENT_RELATIVE")); + intentBox.append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox.set_active (0); + } + + void updateParameters () + { + const Glib::ustring profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring(); + + std::uint8_t supportedIntents = rtengine::ICCStore::getInstance ()->getProofIntents (profile); + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + + if (supportsPerceptual && supportsRelativeColorimetric) { + intentBox.set_sensitive (true); + } + else { + intentBox.set_sensitive (false); + intentBox.set_active (supportsPerceptual ? 1 : 0); + } + + const int intent = intentBox.get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + + if (!processor) + return; + + rtengine::ProcParams* parameters = processor->beginUpdateParams (); + + parameters->icm.monitorProfile = profile; + parameters->icm.monitorIntent = intent; + + processor->endUpdateParams (rtengine::EvOProfile); + } + +public: + MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : + profileBox (), + intentBox (), + processor (ipc) + { + prepareProfileBox (); + prepareIntentBox (); + + reset (); + + profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); + intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); + } + + void pack_end (Gtk::Box* box) + { + box->pack_end (intentBox, Gtk::PACK_SHRINK, 0); + box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); + } + + void reset () + { + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); + intentBox.set_active (options.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); + + updateParameters (); + } + +}; + EditorPanel::EditorPanel (FilePanel* filePanel) : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { @@ -256,12 +346,15 @@ EditorPanel::EditorPanel (FilePanel* filePanel) navSync->set_relief(Gtk::RELIEF_NONE); navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP")); - iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0); iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0); iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); } + monitorProfile.reset(new MonitorProfileSelector (ipc)); + monitorProfile->pack_end (iops); + editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0); editbox->show_all (); @@ -568,6 +661,8 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) } history->resetSnapShotNumber(); + + monitorProfile->reset (); } void EditorPanel::close () diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index cf446da97..ffb8a93a4 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -42,6 +42,8 @@ struct EditorPanelIdleHelper { int pending; }; +class MonitorProfileSelector; + class RTWindow; class EditorPanel : public Gtk::VBox, public PParamsChangeListener, @@ -84,6 +86,8 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; + std::auto_ptr monitorProfile; + ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; PreviewHandler* beforePreviewHandler; // for the before-after view diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 1e65f2753..80729b96b 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -496,5 +496,12 @@ public: } }; +inline void setActiveTextOrIndex (Gtk::ComboBoxText& comboBox, const Glib::ustring& text, int index) +{ + comboBox.set_active_text (text); + + if (comboBox.get_active_row_number () < 0) + comboBox.set_active (index); +} #endif diff --git a/rtgui/options.cc b/rtgui/options.cc index 6d0b6a0d0..ce85acc09 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -626,7 +626,6 @@ void Options::setDefaults () #else rtSettings.iccDirectory = "/usr/share/color/icc"; #endif - rtSettings.colorimetricIntent = 1; rtSettings.viewingdevice = 0; rtSettings.viewingdevicegrey = 3; rtSettings.viewinggreySc = 1; @@ -636,7 +635,8 @@ void Options::setDefaults () rtSettings.leveldnliss = 0; rtSettings.leveldnautsimpl = 0; - rtSettings.monitorProfile = ""; + rtSettings.monitorProfile = Glib::ustring(); + rtSettings.monitorIntent = 1; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" @@ -1461,7 +1461,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); + rtSettings.monitorIntent = keyFile.get_integer("Color Management", "Intent"); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -2008,7 +2008,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); - keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); + keyFile.set_integer ("Color Management", "Intent", rtSettings.monitorIntent); keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 5c85ea18f..4aa1d2427 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -687,30 +687,27 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_border_width (4); - Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":", Gtk::ALIGN_LEFT)); - intent = Gtk::manage (new Gtk::ComboBoxText ()); - intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); - intent->append_text (M("PREFERENCES_INTENT_SATURATION")); - intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); - iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_LEFT)); - Gtk::FileFilter monProfileFilter_colprof; - monProfileFilter_colprof.set_name(M("FILECHOOSER_FILTER_COLPROF")); - monProfileFilter_colprof.add_pattern("*.icc"); - monProfileFilter_colprof.add_pattern("*.ICC"); - monProfileFilter_colprof.add_pattern("*.icm"); - monProfileFilter_colprof.add_pattern("*.ICM"); - Gtk::FileFilter monProfileFilter_any; - monProfileFilter_any.set_name(M("FILECHOOSER_FILTER_ANY")); - monProfileFilter_any.add_pattern("*"); + monProfile = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONPROFILE") + ":", Gtk::ALIGN_LEFT)); - monProfile = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_MONITORICC"), Gtk::FILE_CHOOSER_ACTION_OPEN)); - monProfile->add_filter (monProfileFilter_colprof); - monProfile->add_filter (monProfileFilter_any); - Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONITORICC") + ":", Gtk::ALIGN_LEFT)); + monIntent = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Label* milabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONINTENT")+":", Gtk::ALIGN_LEFT)); + + monProfile->append_text (M("PREFERENCES_PROFILE_NONE")); + monProfile->set_active (0); + + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); + for (std::vector::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + monProfile->append_text (*profile); + + monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + monIntent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + monIntent->set_active (0); + + iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged)); #if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851 cbAutoMonProfile = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_AUTOMONPROFILE"))); @@ -731,8 +728,8 @@ Gtk::Widget* Preferences::getColorManagementPanel () #endif #endif ++row; - colt->attach (*intlab, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*intent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colt->attach (*milabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*monIntent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); #if defined(WIN32) @@ -1435,12 +1432,15 @@ void Preferences::storePreferences () moptions.CPBPath = txtCustProfBuilderPath->get_text(); moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number()); - moptions.rtSettings.monitorProfile = monProfile->get_filename (); +#if !defined(__APPLE__) // monitor profile not supported on apple + moptions.rtSettings.monitorProfile = monProfile->get_active_text (); + moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif +#endif + moptions.rtSettings.iccDirectory = iccDir->get_filename (); - moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); moptions.rtSettings.viewingdevice = view->get_active_row_number (); moptions.rtSettings.viewingdevicegrey = grey->get_active_row_number (); moptions.rtSettings.viewinggreySc = greySc->get_active_row_number (); @@ -1550,16 +1550,10 @@ void Preferences::fillPreferences () panFactor->set_value (moptions.panAccelFactor); rememberZoomPanCheckbutton->set_active (moptions.rememberZoomAndPan); ctiffserialize->set_active(moptions.serializeTiffRead); + #if !defined(__APPLE__) // monitor profile not supported on apple - - if (safe_file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) { - monProfile->set_filename (moptions.rtSettings.monitorProfile); - } - - if (moptions.rtSettings.monitorProfile.empty()) { - monProfile->set_current_folder (moptions.rtSettings.iccDirectory); - } - + setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); + monIntent->set_active (moptions.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); #if defined(WIN32) cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); #endif @@ -1569,7 +1563,6 @@ void Preferences::fillPreferences () iccDir->set_current_folder (moptions.rtSettings.iccDirectory); } - intent->set_active (moptions.rtSettings.colorimetricIntent); view->set_active (moptions.rtSettings.viewingdevice); grey->set_active (moptions.rtSettings.viewingdevicegrey); greySc->set_active (moptions.rtSettings.viewinggreySc); @@ -1921,6 +1914,22 @@ void Preferences::bundledProfilesChanged () rpconn.block (false); } +void Preferences::iccDirChanged () +{ + const Glib::ustring currentSelection = monProfile->get_active_text (); + + monProfile->clear(); + + monProfile->append_text (M("PREFERENCES_PROFILE_NONE")); + monProfile->set_active (0); + + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfilesFromDir (iccDir->get_filename ()); + for (std::vector::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + monProfile->append_text (*profile); + + monProfile->set_active_text (currentSelection); +} + void Preferences::storeCurrentValue() { // TODO: Find a way to get and restore the current selection; the following line can't work anymore diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 76abd0a19..2bf118459 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -95,7 +95,8 @@ protected: Gtk::CheckButton* showExpComp; Gtk::FileChooserButton* iccDir; - Gtk::FileChooserButton* monProfile; + Gtk::ComboBoxText* monProfile; + Gtk::ComboBoxText* monIntent; Gtk::CheckButton* cbAutoMonProfile; //Gtk::CheckButton* cbAutocielab; Gtk::CheckButton* cbciecamfloat; @@ -106,7 +107,6 @@ protected: Gtk::SpinButton* panFactor; Gtk::CheckButton* rememberZoomPanCheckbutton; - Gtk::ComboBoxText* intent; Gtk::ComboBoxText* view; Gtk::ComboBoxText* grey; Gtk::ComboBoxText* greySc; @@ -210,7 +210,8 @@ protected: void forRAWComboChanged (); void forImageComboChanged (); void layoutComboChanged (); - void bundledProfilesChanged(); + void bundledProfilesChanged (); + void iccDirChanged (); void switchThemeTo (Glib::ustring newTheme, bool slimInterface); void switchFontTo (Glib::ustring newFont); bool splashClosed(GdkEventAny* event); From 5f59156bb0377ff20a70b0a8d89d5e0665d9259f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 6 Dec 2015 02:30:18 +0100 Subject: [PATCH 04/16] Simplify querying the default monitor profile as suggested by Hombre57. --- rtengine/iccstore.h | 6 +++--- rtengine/improcfun.cc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 524db9cd2..ed9fbb424 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -89,8 +89,8 @@ public: static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring()); // Main monitors standard profile name, from OS - const Glib::ustring& getDefaultMonitorProfile () const; void findDefaultMonitorProfile (); + cmsHPROFILE getDefaultMonitorProfile () const; cmsHPROFILE workingSpace (const Glib::ustring& name) const; cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; @@ -129,9 +129,9 @@ inline ProfileContent::~ProfileContent () delete [] data; } -inline const Glib::ustring& ICCStore::getDefaultMonitorProfile () const +inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const { - return defaultMonitorProfile; + return getProfile (defaultMonitorProfile); } inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 4306d4a6e..c9fa3c6c8 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -212,9 +212,9 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par #if defined(WIN32) - cmsHPROFILE monitor = iccStore->getProfile (settings->autoMonitorProfile - ? iccStore->getDefaultMonitorProfile () - : params->icm.monitorProfile); + cmsHPROFILE monitor = settings->autoMonitorProfile + ? iccStore->getDefaultMonitorProfile () + : iccStore->getProfile (params->icm.monitorProfile); #else From 8f733776014d3535f897905cb0bafe66cccb49c1 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 8 Dec 2015 18:00:14 +0100 Subject: [PATCH 05/16] Add method to explicitly handle menu item sensitivy for the pop-up button. --- rtgui/popupcommon.cc | 9 +++++++++ rtgui/popupcommon.h | 1 + 2 files changed, 10 insertions(+) diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 881994589..2a1387d3f 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -19,6 +19,7 @@ * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ +#include #include "multilangmgr.h" #include "popupcommon.h" #include "../rtengine/safegtk.h" @@ -135,6 +136,14 @@ void PopUpCommon::entrySelected (int i) } } +void PopUpCommon::setItemSensitivity (int i, bool isSensitive) { + Gtk::Menu_Helpers::MenuList items = menu->items(); + if (i < items.size()) { + items[i].set_sensitive(isSensitive); + } +} + + /* * Set the button image with the selected item */ diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 872beb434..7b05a08e9 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -68,6 +68,7 @@ private: void showMenu(GdkEventButton* event); void entrySelected (int i); + void setItemSensitivity (int i, bool isSensitive); }; From 32eb6b996c73708d5dc30c75cf7f4fe4a8061028 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 15 Dec 2015 01:06:38 +0100 Subject: [PATCH 06/16] Adding softproofing. Now the output profile and the new rendering intent profile for the output profile will only be shown when the new softproof toggle button (bottom of the preview in the Editor panel) will be on. --- .../images/Dark/actions/intent-absolute.png | Bin 0 -> 464 bytes .../images/Dark/actions/intent-perceptual.png | Bin 0 -> 666 bytes .../images/Dark/actions/intent-relative.png | Bin 0 -> 944 bytes .../images/Dark/actions/intent-saturation.png | Bin 0 -> 809 bytes rtdata/images/Dark/actions/softProof.png | Bin 0 -> 827 bytes .../images/Light/actions/intent-absolute.png | Bin 0 -> 445 bytes .../Light/actions/intent-perceptual.png | Bin 0 -> 638 bytes .../images/Light/actions/intent-relative.png | Bin 0 -> 882 bytes .../Light/actions/intent-saturation.png | Bin 0 -> 779 bytes rtdata/images/Light/actions/softProof.png | Bin 0 -> 868 bytes rtdata/languages/default | 2 + rtengine/dcrop.cc | 8 +- rtengine/dcrop.h | 5 + rtengine/iccstore.h | 6 + rtengine/improccoordinator.cc | 45 +- rtengine/improccoordinator.h | 11 + rtengine/improcfun.cc | 44 +- rtengine/improcfun.h | 9 +- rtengine/iplab2rgb.cc | 16 +- rtengine/procevents.h | 3 + rtengine/procparams.cc | 34 +- rtengine/procparams.h | 12 +- rtengine/refreshmap.cc | 24 +- rtengine/refreshmap.h | 56 +- rtengine/rtengine.h | 8 +- rtengine/settings.h | 4 +- rtengine/simpleprocess.cc | 4 +- rtgui/editorpanel.cc | 171 +- rtgui/editorpanel.h | 2 +- rtgui/filecatalog.cc | 1 + rtgui/history.cc | 5 +- rtgui/icmpanel.cc | 29 +- rtgui/icmpanel.h | 1 + rtgui/options.cc | 10 +- rtgui/options.h | 1 + rtgui/paramsedited.cc | 5 + rtgui/paramsedited.h | 1 + rtgui/preferences.cc | 2 +- .../scalable/intent-absolute.file | 1 + .../source_icons/scalable/intent-absolute.svg | 1378 ++++++++++++++++ .../scalable/intent-perceptual.file | 1 + .../scalable/intent-perceptual.svg | 1366 ++++++++++++++++ .../scalable/intent-relative.file | 1 + .../source_icons/scalable/intent-relative.svg | 1374 ++++++++++++++++ .../scalable/intent-saturation.file | 1 + .../scalable/intent-saturation.svg | 1366 ++++++++++++++++ tools/source_icons/scalable/softProof.file | 1 + tools/source_icons/scalable/softProof.svg | 1389 +++++++++++++++++ 48 files changed, 7255 insertions(+), 142 deletions(-) create mode 100644 rtdata/images/Dark/actions/intent-absolute.png create mode 100644 rtdata/images/Dark/actions/intent-perceptual.png create mode 100644 rtdata/images/Dark/actions/intent-relative.png create mode 100644 rtdata/images/Dark/actions/intent-saturation.png create mode 100644 rtdata/images/Dark/actions/softProof.png create mode 100644 rtdata/images/Light/actions/intent-absolute.png create mode 100644 rtdata/images/Light/actions/intent-perceptual.png create mode 100644 rtdata/images/Light/actions/intent-relative.png create mode 100644 rtdata/images/Light/actions/intent-saturation.png create mode 100644 rtdata/images/Light/actions/softProof.png create mode 100644 tools/source_icons/scalable/intent-absolute.file create mode 100644 tools/source_icons/scalable/intent-absolute.svg create mode 100644 tools/source_icons/scalable/intent-perceptual.file create mode 100644 tools/source_icons/scalable/intent-perceptual.svg create mode 100644 tools/source_icons/scalable/intent-relative.file create mode 100644 tools/source_icons/scalable/intent-relative.svg create mode 100644 tools/source_icons/scalable/intent-saturation.file create mode 100644 tools/source_icons/scalable/intent-saturation.svg create mode 100644 tools/source_icons/scalable/softProof.file create mode 100644 tools/source_icons/scalable/softProof.svg diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7e1a85d0cf0b4a131e3dc02ef8e74161a5f367 GIT binary patch literal 464 zcmV;>0WbcEP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdu*o9?cT=WR@DbA6 zO0c!hJ7}41leM!+At|&`v9i*1F|r7|_gbiBU@nY!>cjWJW#-Nh0AyL#VrCCTX0zGT za5&_Ut^)w)+<=)6G?GrIa{}N!SW;EhB@tyBNu$vyLc0zC>h=1=VzF=P000&U1^@s6HNQ8u00004b3#c}2nYxW zdPNB7i*4H_JLPvshJcg%IvI z=MvzN_Z|@$1EW08->Iq<<>q;Q02MXa+1aV5X?h!Ih)4ri0(3^oUZ>O9s6hEtg7ncvd&fYJMj5bGnS1NRb4Z)1v8s9R;rt^-|sh6b=}NvQguL{ zhI1M97rnHi<3bOdb2Ha(9LHx~zf<8~T;xaMANVyY-gCezlK=n!07*qoM6N<$g0=S` AF8}}l literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/intent-relative.png b/rtdata/images/Dark/actions/intent-relative.png new file mode 100644 index 0000000000000000000000000000000000000000..c1fb040a9ddabae8f9ebdd03367c2bacbba0978c GIT binary patch literal 944 zcmV;h15f;kP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zd z86-(Excq7v6hy(x@ z0Ki(CkUSQVeUd&S$&-IOIX^$YS1cB@=z@p zD*#g477;HZCrOfYYPDLgUayeLylW#=MplTvboPF#Md8s!&z#?(V*oBuQY5 zSpl%5s)h0P8GsXG%qXM4$6*+LNdRax8uyGbw=?oMRn3pTp8`0t*0wJ$F51;fYYo3#z)@Y&L5EUe5|HB9F@D@)r~70)YMf{Tsbr z?~aJ97-NC}4m9ueoxAOV?JEPGkl@V+0p8(Dr02B&^&$6U`eturd^A(Z5fUC=R z7eFdqBtddS@@EnG&N9o+Ty!fdc?z%>5)uZloGGC&S_Jw`m`!H2e+50fabx S=)Ix<0000P000&U1^@s6HNQ8u00004b3#c}2nYxW zdk)ELp(-tYN- z?m6Fkf&Wkf0L5Z)gyfEYZZ0x6Ffec}0Dzf&^4@3vHAGcE0rg4#wu;4KPF35RoyQm} z`Fy?<)@tg#?Jh>Vg<%n|^+_s;-42z8S_ zl8H~zIoA$gkff2k9b>$ss=cauh2&BQ;X<`qT}tYWF;*Irh{zrhNesSzJ`3R1%*@Q^ zo}QkAB=?bgCnAr{>{tlN3o)}-0Dk`XwzjrQ3kwTANtny!I5ad=o}Hb|c6WE5Cb^sB z{Sd-SRXt*6Z@u>)l6py&fEIuJ`1tr1@BKLu*#=r~{Yb4=`&}lV&FoA%oleyQ z|B}sS&kqg`{t?iCkQ^uZFiGH?V+i5i^78TqGrM4BWs+xmdwajN0sz*Q$yES8l}erJ z>+73u6#%sG8K0*|5aVxLlBlgKm=J>Z;E^NU?Mm+bW6O5 zhZZ~tiXQgv$3-#XO}vRlK@fF8Z{iA*kC)g)Q1IZAfF4A=8c5724w7`w>sKB!BjY$T z$$)<-cwJQex<2TBKtmG~6MxOk&HahrBxxRe-#?w_xdU(!0466VcYB_9n3*TSF#Nw? zFav-wX1}WL1h6Yj(-8m=kqZEhJLeu6W5%bZrndG2rZi2ZD2j1a-PZ6eW?6Q=R4Tmy z;57qP^^50uXTvajzNw1yJTE!tZm8-EfN52|31C|*6aa{5&^dR@7;|h>;5d%IMNu?Q zM2pV3#VCsAMTEP=djKvOW6o>{?&Kt*VuQTXv$M13Rh9Yz2SM;@ql%n!Cyg|5n&Nw zW~R3IJxfbV_tP{T>yY-hwf0`6Qu*VTp|`+ZTWbsFoQen&k*aDF zincuhfW`U;c5ifa^lMjexm^AXRf%R)6WZ7nqr!*6a0uYPH%95urTK z3nF@16vcxmic%uduDQLy<#O3F^A+dZ*LuDFukZT@!!SG%$MLgP==AjTsrF0a#|Dfs z2{Y@;%F2@t?+5_o-3k~Q8oKP9+penfs(L$)<8Q6tBSdthR|nmss#~x=R>#aAnE71S zzf(Ul##{w3NJMkhYV}c)Bt_5V^`RF70|U=SMn-B)$9E!tHa;dGDfa*X002ovPDHLk FV1jU2Y!3hc literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/intent-absolute.png b/rtdata/images/Light/actions/intent-absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..1396e378553270124944c886d2536016f879e622 GIT binary patch literal 445 zcmV;u0Yd(XP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdZHp_>f})Ds;LOx90%L6aId8JZ-Jlhg9G^!15gyjz*@UQL`0+p+K{dV z==FNzwrvk%B+j`r5qS@msOq(<-o{A!{r;zj1a%ESp66+nWj014A|HSTOUkmmRMn_+ zB}o!@F5nJ$iji1rzhe4Zj{z8sM(3(pb`CeDs_Xj7t{xVu8ugw8N)}x+H_HHq!{Hbx zw!nXx&1REi3*i5W0dUTpsOq3|xG}FHa$^C!_xnkb9CR)5-e+AiH)g$EN2P000&U1^@s6HNQ8u00004b3#c}2nYxW zd9p#k(uphS(a}t5{BU&0N3jX&bccjACgq( z+=tn0_GUVrp0pNOhkn0*&CH&XybIujjIxQXI$k%xnih2f$YVW!+hl$7z}#cmSZP&zcHvW>8f` zQIwM$nb~MQpMNTf;$x@Nd17X_8#5630{|WXR8@7*lnH=~BGNarTLA8>>LXQ!@B6u# zjhu7uM1&2Q`~q6mq}%OYQq_T~4oMD4Mk1msG8rdHve!zaPSo?f8zgJvsA`cU$qx?z zq9}S!GTK&5r2bn;egp8zTaroSkp0Am1q9hnOyw;3MGDIXNd017|$jrt?Q7o2beB5+SL=pg>*P5|utoXjaL$V_x ztHw%uGX_C0bk6MpxQVs{avjcO)SvgGP000&U1^@s6HNQ8u00004b3#c}2nYxW zdyD28hkRH zPJb2vaL#?Fs@K{aNyY#!HOChsvIihHv)p_Cbd4s@)FmQbL|XZhG?JyN?v-Wv2mpt} z;X5QJ&bco|l8?RjKdplcyD! zT$bgpYvBTb!C>$)fNc?(nArrtyZ;sQ#*6Rw`?pnftId&QL~=m#z2@o_fPIpA6h(Pa z6pwL+F=*$z%aII8*Z>@n{5^`Iy`m_l0PI{0{eJ&*k|83`y!Ut4#^s#rh{!cF%S0pt z;2JRm?G0Scxf=l95BOeE)iKE-fVWf?0G^WEF|#~Lk|R|O;aUO>E>*pC(SkIynTYI? z%sZVP000&U1^@s6HNQ8u00004b3#c}2nYxW zdux+o%-Nw%r#M{DgyOztw!r175TodR$JKsU(+k~7Y^LvebNtGQh6eM81) zGMN)$7>)oqO>)&*`z#E@vN2{%RU^HuPm%?&4N0fd=K#b##jY?6&x?qXd>I76D-k&h zUB>GhRgAB@&4j*=)Ab+uM7Uxm;dLrBZF4=iMWD#u)P!z&BML5s`v1=6h7Gs+NETjqmU8 zKOO|ZIDnLh%&2NnMD75X_kDkS=jFw20ssaE208&Gq6EJ0cayvgpoQd95!nDRL9$e> zR>vxpN^P$uUA@rgZk_2tFHpzeu?bdo$4qX_^^?-y`j@f(*TH1x}--+TZ7002ov JPDHLkV1jwrP1yhd literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/softProof.png b/rtdata/images/Light/actions/softProof.png new file mode 100644 index 0000000000000000000000000000000000000000..2c12e216fe3e86915a5928a7a413c37a6219fc23 GIT binary patch literal 868 zcmV-q1DpJbP)F_~hZyqC1|D|6?a z(?w@OJI;&~@C%Q7Ih^x(-*fNfUSOcb#l`2AmX@Bu|0FY(*W)-oGe1B7bCzYTS;1VXR1AQ( z0E8kEG4tEY%ggfsUKl2+>RD#KnIy?8Gdu2dIwuN+LLGpJNR64lZnxVfnEB0-+yW7; z$8nscY5Mzrf?KVYPt)|DVzKzFs@|{FYPX8T;!^-FjO!3UC641lnx?m>fq86@IiFUf zsu!Je9|E9bfdSl|1|I0$BuOq!G&e3-tyVK4$^pO_L)Kch)>04zk2zG;3(mPu2M1s# z$2k#Y%#1J$If^2Vq9_Q%kgc_&?XNc)jnAEP(JWx7>R$k0tqr0m3I^ce$RoLDnfc3= zm6emTfd3eP$y&=p=hj*_#_;H}h{%hbPUp(%>guVfU;uv(Cxt>G2*WTK0*BuiGfS;j z>#}q1$$u^SQ7g>90LZ=fYK&nK(LB$InTeS}^f;G@`l|XpfXlU7?cPLiwOYNKB*{w39budY)dXk8YstPmLOQq5W6K|*EC`pn}RP_{q uAJ^8_u5WB?OuZdvmUHgaa=HA(qp=6oX)*PXM7#a~0000Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l MAIN_TOOLTIP_THRESHOLD;Threshold MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +MONITOR_PROFILE_SYSTEM;System default NAVIGATOR_B;B: NAVIGATOR_G;G: NAVIGATOR_H;H: @@ -1512,6 +1513,7 @@ TP_ICM_INPUTPROFILE;Input Profile TP_ICM_LABEL;Color Management TP_ICM_NOICM;No ICM: sRGB Output TP_ICM_OUTPUTPROFILE;Output Profile +TP_ICM_OUTPUTPROFILEINTENT;Output Rendering Intent TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index a97ae7f39..cd68aa0a6 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -33,7 +33,7 @@ extern const Settings* settings; Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) : EditBuffer(editDataProvider), origCrop(NULL), laboCrop(NULL), labnCrop(NULL), cropImg(NULL), cbuf_real(NULL), cshmap(NULL), transCrop(NULL), cieCrop(NULL), cbuffer(NULL), - updating(false), newUpdatePending(false), skip(10), + softProofing(false), updating(false), newUpdatePending(false), skip(10), cropx(0), cropy(0), cropw(-1), croph(-1), trafx(0), trafy(0), trafw(-1), trafh(-1), rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1), @@ -987,7 +987,7 @@ void Crop::update (int todo) EditBuffer::setReady(); // switch back to rgb - parent->ipf.lab2monitorRgb (labnCrop, cropImg); + parent->ipf.lab2monitorRgb (labnCrop, cropImg, softProofing); //parent->ipf.lab2monitorRgb (laboCrop, cropImg); @@ -1030,13 +1030,13 @@ void Crop::update (int todo) Image8 *cropImgtrue; if(settings->HistogramWorking) { - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, RI_RELATIVE, false); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, params.icm.outputIntent, false); } int finalW = rqcropw; diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index 57f388a51..ea9b1bc00 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -54,6 +54,7 @@ protected: // ----------------------------------------------------------------- float** cbuffer; + bool softProofing; /// True if the Crop has to display a soft proof of the output with its profile bool updating; /// Flag telling if an updater thread is currently processing bool newUpdatePending; /// Flag telling the updater thread that a new update is pending int skip; @@ -103,6 +104,10 @@ public: /** @brief Asynchronously reprocess the detailed crop */ void fullUpdate (); // called via thread + void setSoftProofing(bool doSoftProof) { + softProofing = doSoftProof; + } + void setListener (DetailedCropListener* il); void destroy (); int get_skip () diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index ed9fbb424..6b41987f7 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -91,6 +91,7 @@ public: // Main monitors standard profile name, from OS void findDefaultMonitorProfile (); cmsHPROFILE getDefaultMonitorProfile () const; + Glib::ustring getDefaultMonitorProfileStr () const; cmsHPROFILE workingSpace (const Glib::ustring& name) const; cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; @@ -134,6 +135,11 @@ inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const return getProfile (defaultMonitorProfile); } +inline Glib::ustring ICCStore::getDefaultMonitorProfileStr () const +{ + return defaultMonitorProfile; +} + inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const { return getInputIntents (getProfile (name)); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8389ec34e..62de26076 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -31,9 +31,9 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), - ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10), - highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), - bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), + ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), + highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true), + softProofing(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), hltonecurve(65536), shtonecurve(65536), @@ -781,9 +781,16 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } + // Update the output color transform if necessary + if (isColorProfileDirty || (todo & M_MONITOR)) { + ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProofing); + isColorProfileDirty = false; + } + // process crop, if needed for (size_t i = 0; i < crops.size(); i++) if (crops[i]->hasListener () && cropCall != crops[i] ) { + crops[i]->setSoftProofing(softProofing); crops[i]->update (todo); // may call ourselves } @@ -794,23 +801,23 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) progress ("Conversion to RGB...", 100 * readyphase / numofphases); - if (todo != CROP && todo != MINUPDATE) { + if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) { MyMutex::MyLock prevImgLock(previmg->getMutex()); try { - ipf.lab2monitorRgb (nprevl, previmg); + ipf.lab2monitorRgb (nprevl, previmg, softProofing); delete workimg; Glib::ustring outProfile = params.icm.output; if(settings->HistogramWorking) { Glib::ustring workProfile = params.icm.working; - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, true); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, RI_RELATIVE, true); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { - if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { + if (params.icm.output.empty() || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, false); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, params.icm.outputIntent, false); } } catch(char * str) { progress ("Error converting file...", 0); @@ -1126,6 +1133,28 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } +void ImProcCoordinator::setSoftProofing (bool softProof) +{ + softProofing = softProof; +} + +void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingIntent intent) +{ + if (profile != monitorProfile) { + monitorProfile = profile; + isColorProfileDirty = true; + } + if (intent != monitorIntent) { + monitorIntent = intent; + isColorProfileDirty = true; + } +} + +void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent) +{ + profile = monitorProfile; + intent = monitorIntent; +} void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index ef981fe6a..901804eba 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -72,11 +72,18 @@ protected: ImProcFunctions ipf; + Glib::ustring monitorProfile; + + eRenderingIntent monitorIntent; + int scale; bool highDetailPreprocessComputed; bool highDetailRawComputed; bool allocated; + bool isColorProfileDirty; + bool softProofing; + void freeAll (); // Precomputed values used by DetailedCrop ---------------------------------------------- @@ -249,6 +256,10 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); + void setMonitorProfile (Glib::ustring profile, eRenderingIntent intent); + void getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent); + void setSoftProofing (bool softProof); + bool updateTryLock () { return updaterThreadStart.trylock(); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index c9fa3c6c8..e99daa79a 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -186,12 +186,11 @@ void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) } } */ -void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) + + +void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing) { - // set up monitor transform - Glib::ustring wprofile = params->icm.working; - if (monitorTransform != NULL) { cmsDeleteTransform (monitorTransform); } @@ -210,36 +209,30 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB -#if defined(WIN32) - - cmsHPROFILE monitor = settings->autoMonitorProfile - ? iccStore->getDefaultMonitorProfile () - : iccStore->getProfile (params->icm.monitorProfile); - -#else - - cmsHPROFILE monitor = iccStore->getProfile (params->icm.monitorProfile); - -#endif + cmsHPROFILE monitor = iccStore->getProfile (monitorProfile); + printf("ImProcFunctions::updateColorProfiles / monitor profile = %s / intent = %d\n", monitorProfile.c_str(), monitorIntent); if (monitor) { MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, + printf(" - monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; - if (params->icm.output != "" && params->icm.output != ColorManagementParams::NoICMString) { - outputProfile = params->icm.output; + if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) { + outputProfile = icm.output; cmsHPROFILE jprof = iccStore->getProfile(outputProfile); if (jprof) { - lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + //TODO: Create a dedicated softproof transformation (line below to be finished) + //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING ); - if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - } + printf(" - lab2outputTransform = cmsCreateTransform / intent=%d\n", icm.outputIntent); + lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + printf(" - output2monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } @@ -247,6 +240,13 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par } #endif +} + +void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) +{ + + Glib::ustring wprofile = params->icm.working; + // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments int T = 1; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index cfabbba64..c34219c0d 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,6 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); + void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -265,7 +266,7 @@ public: void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage); float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh); - void lab2monitorRgb (LabImage* lab, Image8* image); + void lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing=false); void resize (Image16* src, Image16* dst, float dScale); void Lanczos (const LabImage* src, LabImage* dst, float scale); void Lanczos (const Image16* src, Image16* dst, float scale); @@ -379,9 +380,9 @@ public: void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); - Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma); - Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw);//without gamma ==>default + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma); + Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw);//without gamma ==>default // CieImage *ciec; bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index cc01b783f..a727423ef 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -39,7 +39,7 @@ const double (*iwprof[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, const char* wprofnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; const int numprof = 7; -void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) +void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing) { //gamutmap(lab); @@ -78,7 +78,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) buffer[iy++] = rb[j] / 327.68f; } - if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { + if (softProofing && !settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { AlignedBuffer buf(3 * W); cmsDoTransform (lab2outputTransform, buffer, buf.data, W); cmsDoTransform (output2monitorTransform, buf.data, data + ix, W); @@ -134,7 +134,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) } } -Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma) +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma) { //gamutmap(lab); @@ -167,7 +167,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, lcmsMutex->lock (); cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); - cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, + cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety cmsCloseProfile(hLab); lcmsMutex->unlock (); @@ -259,7 +259,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, return image; } // for default (not gamma) -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw) { //gamutmap(lab); @@ -322,7 +322,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); @@ -363,7 +363,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int // for gamma options (BT709...sRGB linear...) -Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) +Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { //gamutmap(lab); @@ -593,7 +593,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 4dbbad07c..4609c674a 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -454,6 +454,9 @@ enum ProcEvent { EvLbaselog = 424, // EvLgrbl = 425, EvRetinexlhcurve = 425, + EvOIntent = 426, + EvSoftProof = 427, + EvMonitorTransform = 428, NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 44c02a531..2c93bfd47 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -894,8 +894,7 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; - monitorProfile = Glib::ustring (); - monitorIntent = 1; + outputIntent = RI_PERCEPTUAL; gamma = "default"; gampos = 2.22; slpos = 4.5; @@ -2550,6 +2549,20 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_string ("Color Management", "OutputProfile", icm.output); } + if (!pedited || pedited->icm.outputIntent) { + Glib::ustring intent; + if (icm.outputIntent == RI_PERCEPTUAL) { + intent = "Perceptual"; + } else if (icm.outputIntent == RI_RELATIVE) { + intent = "Relative"; + } else if (icm.outputIntent == RI_SATURATION) { + intent = "Saturation"; + } else if (icm.outputIntent == RI_ABSOLUTE) { + intent = "Absolute"; + } + keyFile.set_string ("Color Management", "OutputProfileIntent", intent); + } + if (!pedited || pedited->icm.gamma) { keyFile.set_string ("Color Management", "Gammafree", icm.gamma); } @@ -5674,6 +5687,23 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Color Management", "OutputProfileIntent")) { + Glib::ustring intent = keyFile.get_string ("Color Management", "OutputProfileIntent"); + if (intent == "Perceptual") { + icm.outputIntent = RI_PERCEPTUAL; + } else if (intent == "Relative") { + icm.outputIntent = RI_RELATIVE; + } else if (intent == "Saturation") { + icm.outputIntent = RI_SATURATION; + } else if (intent == "Absolute") { + icm.outputIntent = RI_ABSOLUTE; + } + + if (pedited) { + pedited->icm.outputIntent = true; + } + } + if (keyFile.has_key ("Color Management", "Gammafree")) { icm.gamma = keyFile.get_string ("Color Management", "Gammafree"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 77c1004e8..cbbbed7a5 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "LUT.h" #include "coord.h" @@ -41,6 +42,14 @@ class WavOpacityCurveW; class WavOpacityCurveWL; class RetinextransmissionCurve; +typedef enum RenderingIntent { + RI_PERCEPTUAL = INTENT_PERCEPTUAL, + RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC, + RI_SATURATION = INTENT_SATURATION, + RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC, + RI__COUNT +} eRenderingIntent; + namespace procparams { @@ -941,8 +950,7 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; - Glib::ustring monitorProfile; // Not stored persistently as it is just an optional settings override. - int monitorIntent; // Not store persistently as it is just an optional settings override. + eRenderingIntent outputIntent; static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 3505da24f..37d0f52b4 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -64,9 +64,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DARKFRAME, // EvLCPUseVign, TRANSFORM, // EvLCPUseCA, M_VOID, // EvFixedExp - WHITEBALANCE, // EvWBMethod, - WHITEBALANCE, // EvWBTemp, - WHITEBALANCE, // EvWBGreen, + ALLNORAW, // EvWBMethod, + ALLNORAW, // EvWBTemp, + ALLNORAW, // EvWBGreen, RGBCURVE, // EvToneCurveMode1, RGBCURVE, // EvToneCurve2, RGBCURVE, // EvToneCurveMode2, @@ -75,7 +75,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { 0, // EvCDNEnabled:obsolete, ALL, // EvBlendCMSMatrix, RGBCURVE, // EvDCPToneCurve, - INPUTPROFILE, // EvDCPIlluminant, + ALLNORAW, // EvDCPIlluminant, RETINEX, // EvSHEnabled, RGBCURVE, // EvSHHighlights, RGBCURVE, // EvSHShadows, @@ -97,7 +97,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { ALLNORAW, // EvHRMethod, ALLNORAW, // EvWProfile, OUTPUTPROFILE, // EvOProfile, - INPUTPROFILE, // EvIProfile, + ALLNORAW, // EvIProfile, TRANSFORM, // EvVignettingAmount, RGBCURVE, // EvChMixer, RESIZE, // EvResizeScale, @@ -234,8 +234,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvCATbadpix LUMINANCECURVE, // EvCATAutoadap DEFRINGE, // EvPFCurve - WHITEBALANCE, // EvWBequal - WHITEBALANCE, // EvWBequalbo + ALLNORAW, // EvWBequal + ALLNORAW, // EvWBequalbo TRANSFORM, // EvGradientDegree TRANSFORM, // EvGradientEnabled TRANSFORM, // EvPCVignetteStrength @@ -421,7 +421,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DIRPYREQUALIZER, // EvWavNeutral RGBCURVE, // EvDCPApplyLookTable, RGBCURVE, // EvDCPApplyBaselineExposureOffset, - INPUTPROFILE, // EvDCPApplyHueSatMap + ALLNORAW, // EvDCPApplyHueSatMap DIRPYREQUALIZER, // EvWavenacont DIRPYREQUALIZER, // EvWavenachrom DIRPYREQUALIZER, // EvWavenaedge @@ -452,7 +452,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DEMOSAIC, // EvLslope RETINEX, // EvLhighl DEMOSAIC, // EvLbaselog -// DEMOSAIC, // EvLgrbl - DEMOSAIC // EvRetinexlhcurve +// DEMOSAIC, // EvLgrbl + DEMOSAIC, // EvRetinexlhcurve + ALLNORAW, // EvOIntent + ALLNORAW, // EvSoftProof + MONITORTRANSFORM // EvMonitorTransform + }; diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index e24d0c422..23e179f9f 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -20,15 +20,16 @@ #define __REFRESHMAP__ // Use M_VOID if you wish to update the proc params without updating the preview at all ! -#define M_VOID (1<<15) +#define M_VOID (1<<16) // Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview") // Must NOT be used with other event (i.e. will be used for MINUPDATE only) -#define M_MINUPDATE (1<<14) +#define M_MINUPDATE (1<<15) // Force high quality -#define M_HIGHQUAL (1<<13) +#define M_HIGHQUAL (1<<14) // Elementary functions that can be done to // the preview image when an event occurs +#define M_MONITOR (1<<13) #define M_RETINEX (1<<12) #define M_CROP (1<<11) #define M_PREPROC (1<<10) @@ -45,31 +46,30 @@ // Bitfield of functions to do to the preview image when an event occurs // Use those or create new ones for your new events -#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE) -#define SHARPENING M_LUMINANCE -#define IMPULSEDENOISE M_LUMINANCE -#define DEFRINGE M_LUMINANCE -#define WHITEBALANCE (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DIRPYRDENOISE (M_COLOR|M_LUMINANCE) -#define CROP M_CROP -#define RESIZE M_VOID -#define EXIF M_VOID -#define IPTC M_VOID -#define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE) -#define OUTPUTPROFILE (M_INIT|M_COLOR|M_LUMINANCE) -#define INPUTPROFILE WHITEBALANCE -#define GAMMA (M_COLOR|M_LUMINANCE) -#define MINUPDATE M_MINUPDATE -#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RETINEX (M_RETINEX|ALLNORAW) +#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define ALLNORAW (M_INIT|M_LINDENOISE|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_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define SHARPENING (M_LUMINANCE|M_COLOR) +#define IMPULSEDENOISE (M_LUMINANCE|M_COLOR) +#define DEFRINGE (M_LUMINANCE|M_COLOR) +#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR) +#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR) +#define GAMMA (M_LUMINANCE|M_COLOR) +#define CROP M_CROP +#define RESIZE M_VOID +#define EXIF M_VOID +#define IPTC M_VOID +#define MINUPDATE M_MINUPDATE +#define RETINEX (M_RETINEX|ALLNORAW) +#define MONITORTRANSFORM M_MONITOR +#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM) extern int refreshmap[]; #endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 195911a3a..d10acb561 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -35,7 +35,7 @@ #include "LUT.h" /** * @file - * This file contains the main functionality of the raw therapee engine. + * This file contains the main functionality of the RawTherapee engine. * */ @@ -413,9 +413,13 @@ public: virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; virtual void setAutoChromaListener (AutoChromaListener* l) = 0; - virtual void setRetinexListener (RetinexListener* l) = 0; + virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; + virtual void setMonitorProfile (Glib::ustring monitorProfile, eRenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring &monitorProfile, eRenderingIntent &intent) = 0; + virtual void setSoftProofing (bool softProof) = 0; + virtual ~StagedImageProcessor () {} /** Returns a staged, cached image processing manager supporting partial updates diff --git a/rtengine/settings.h b/rtengine/settings.h index bd37faaf2..98c85ba6f 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -19,6 +19,8 @@ #ifndef _RTSETTINGS_ #define _RTSETTINGS_ +#include "procparams.h" + namespace rtengine { @@ -37,7 +39,7 @@ public: int leveldnautsimpl; // STD or EXPERT Glib::ustring monitorProfile; ///< ICC profile name used for the monitor - int monitorIntent; ///< Colorimetric intent used with the above profile + eRenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 5ea834b2d..1edfa590c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1151,7 +1151,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p cmsFloat64Number Parameters[7]; double ga0, ga1, ga2, ga3, ga4, ga5, ga6; // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); + readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); customGamma = true; //or selected Free gamma @@ -1343,7 +1343,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p bwonly = false; } - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, bwonly); + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, bwonly); if (settings->verbose) { printf("Output profile_: \"%s\"\n", params.icm.output.c_str()); diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index c6d2804c1..a762fc95b 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -35,88 +35,171 @@ using namespace rtengine::procparams; class MonitorProfileSelector { private: - Gtk::ComboBoxText profileBox; - Gtk::ComboBoxText intentBox; + Gtk::ToggleButton* softProof; + MyComboBoxText* profileBox; + //PopUpButton* intentBox; + MyComboBoxText* intentBox; + sigc::connection profileConn, intentConn; - rtengine::StagedImageProcessor* const& processor; + rtengine::StagedImageProcessor* processor; private: - MonitorProfileSelector(const MonitorProfileSelector&); - MonitorProfileSelector& operator=(const MonitorProfileSelector&); + void prepareSoftProofButton () + { + Gtk::Image *softProofImg = Gtk::manage (new RTImage("softProof.png")); + softProofImg->set_padding(0, 0); + softProof = Gtk::manage(new Gtk::ToggleButton()); + softProof->add(*softProofImg); + softProof->set_relief(Gtk::RELIEF_NONE); + softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); + } void prepareProfileBox () { - profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); - profileBox.set_active (0); + profileBox = Gtk::manage(new MyComboBoxText()); + profileBox->set_size_request(100,-1); - const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); - for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) - profileBox.append_text (*iterator); + profileBox->append_text (M("PREFERENCES_PROFILE_NONE")); + #if defined(WIN32) + profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileStr() + ")"); + profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); + #else + profileBox->set_active (0); + #endif + + const std::vector profiles = rtengine::iccStore->getProfiles (); + for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) { + profileBox->append_text (*iterator); + } + profileConn = profileBox->signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } void prepareIntentBox () { - intentBox.append_text (M("PREFERENCES_INTENT_RELATIVE")); - intentBox.append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox.set_active (0); + intentBox = Gtk::manage(new MyComboBoxText()); + intentBox->set_size_request(-1,-1); + //intentBox = Gtk::manage(new PopUpButton()); + + intentBox->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox->append_text (M("PREFERENCES_INTENT_RELATIVE")); + //intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + //intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + //intentBox->setSelected(0); + intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); + //intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); + } + + void softProofToggled () + { + if (processor) { + processor->setSoftProofing( softProof->get_active() ); + processor->endUpdateParams ( rtengine::EvMonitorTransform ); + } + } + + void updateIntent (int i) + { + updateParameters(); } void updateParameters () { - const Glib::ustring profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring(); + Glib::ustring profile; +#ifdef WIN32 + if (profileBox->get_active_row_number () == 1) { + profile = rtengine::iccStore->getDefaultMonitorProfileStr (); + if (profile.empty()) { + profile = options.rtSettings.monitorProfile; + } + if (profile.empty()) { + profile = "sRGB IEC61966-2.1"; // assuming this profile always exist on Windows + } + } else if (profileBox->get_active_row_number () > 1) { + profile = profileBox->get_active_text (); + } +#else + profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring(); +#endif - std::uint8_t supportedIntents = rtengine::ICCStore::getInstance ()->getProofIntents (profile); + std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; if (supportsPerceptual && supportsRelativeColorimetric) { - intentBox.set_sensitive (true); + intentBox->set_sensitive (true); } else { - intentBox.set_sensitive (false); - intentBox.set_active (supportsPerceptual ? 1 : 0); + bool wasBlocked = intentConn.block(true); + intentBox->set_active(supportsPerceptual ? 0 : 1); + //intentBox->setSelected(supportsPerceptual ? 0 : 1); + intentBox->set_sensitive (false); + intentConn.block(wasBlocked); } - const int intent = intentBox.get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + //rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; + rtengine::eRenderingIntent intent = intentBox->get_active_row_number() > 0 ? rtengine::RI_RELATIVE : rtengine::RI_PERCEPTUAL; - if (!processor) + if (!processor) { return; + } - rtengine::ProcParams* parameters = processor->beginUpdateParams (); + // either store them in the options file for the default value when opening the next EditorPanel + //options.rtSettings.monitorProfile = profile; + //options.rtSettings.monitorIntent = intent; - parameters->icm.monitorProfile = profile; - parameters->icm.monitorIntent = intent; - - processor->endUpdateParams (rtengine::EvOProfile); + // ...or store them locally + printf("Appel de processor->setMonitorProfile(%s, %d)\n", profile.c_str(), intent); + processor->setMonitorProfile(profile, intent); + printf("Appel de processor->endUpdateParams(%d)\n", rtengine::EvMonitorTransform); + processor->endUpdateParams (rtengine::EvMonitorTransform); } public: - MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : - profileBox (), - intentBox (), - processor (ipc) + MonitorProfileSelector () : + processor (NULL) { + prepareSoftProofButton (); prepareProfileBox (); prepareIntentBox (); reset (); - - profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); - intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } - void pack_end (Gtk::Box* box) + // HOMBRE: renamed to 'pack_end_in', because 'pack_end' already widely used by Gtk::Widget in a different way + void pack_end_in (Gtk::Box* box) { - box->pack_end (intentBox, Gtk::PACK_SHRINK, 0); - box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); + box->pack_end (*intentBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*profileBox, Gtk::PACK_EXPAND_WIDGET, 0); } void reset () { - setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); - intentBox.set_active (options.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); + bool wasBlocked; +#ifdef WIN32 + wasBlocked = profileConn.block(true); + if (options.rtSettings.autoMonitorProfile) { + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 1); + } else { + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + } + profileConn.block(wasBlocked); +#else + wasBlocked = profileConn.block(true); + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + profileConn.block(wasBlocked); +#endif + wasBlocked = intentConn.block(true); + intentBox->set_active (options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + //intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + intentConn.block(wasBlocked); - updateParameters (); + // useless, set_active will trigger the signal_changed event + //updateParameters (); + } + + void setImageProcessor (rtengine::StagedImageProcessor* imageProc) { + processor = imageProc; } }; @@ -269,6 +352,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // Save buttons Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ()); + iops->set_spacing(2); //Gtk::Image *saveButtonImage = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)); Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("gtk-save-large.png")); @@ -346,14 +430,16 @@ EditorPanel::EditorPanel (FilePanel* filePanel) navSync->set_relief(Gtk::RELIEF_NONE); navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP")); + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0); iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0); iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); - iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); } - monitorProfile.reset(new MonitorProfileSelector (ipc)); - monitorProfile->pack_end (iops); + // Monitor profile buttons + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); + monitorProfile = new MonitorProfileSelector (); + monitorProfile->pack_end_in (iops); editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0); @@ -491,6 +577,7 @@ EditorPanel::~EditorPanel () delete ppframe; delete leftbox; delete vboxright; + delete monitorProfile; //delete saveAsDialog; if(catalogPane) { @@ -612,6 +699,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) this->isrc = isrc; ipc = rtengine::StagedImageProcessor::create (isrc); + monitorProfile->setImageProcessor(ipc); ipc->setProgressListener (this); ipc->setPreviewImageListener (previewHandler); ipc->setPreviewScale (10); // Important @@ -662,6 +750,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) history->resetSnapShotNumber(); + //HOMBRE: not sure if we want to reset on opening a new image monitorProfile->reset (); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index ffb8a93a4..0575b7f92 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -86,7 +86,7 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; - std::auto_ptr monitorProfile; + MonitorProfileSelector* monitorProfile; ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d40b7d720..0112f9ebf 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1139,6 +1139,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.icm.input = options.fastexport_icm_input ; params.icm.working = options.fastexport_icm_working ; params.icm.output = options.fastexport_icm_output ; + params.icm.outputIntent = options.fastexport_icm_outputIntent ; params.icm.gamma = options.fastexport_icm_gamma ; params.resize.enabled = options.fastexport_resize_enabled ; params.resize.scale = options.fastexport_resize_scale ; diff --git a/rtgui/history.cc b/rtgui/history.cc index 57f7549db..689ea6394 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -24,7 +24,6 @@ using namespace rtengine; using namespace rtengine::procparams; Glib::ustring eventDescrArray[NUMOFEVENTS]; -extern Glib::ustring argv0; History::History (bool bookmarkSupport) : blistener(NULL), tpc (NULL), bmnum (1) { @@ -204,8 +203,8 @@ void History::bookmarkSelectionChanged () void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { - // to prevent recursion, we filter out the events triggered by the history - if (ev == EvHistoryBrowsed) { + // to prevent recursion, we filter out the events triggered by the history and events that should not be registered + if (ev == EvHistoryBrowsed || ev == EvMonitorTransform) { return; } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 51ee408a2..55e8e1a6e 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -193,6 +193,18 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->set_active (0); + // Rendering intent + + Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_OUTPUTPROFILEINTENT"))); + oVBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); + ointent = Gtk::manage (new MyComboBoxText ()); + oVBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); + ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); + ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + ointent->set_active(0); + // Output gamma Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ()); @@ -282,6 +294,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); @@ -507,6 +520,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) if (onames->get_active_row_number() == -1) { onames->set_active_text (M("TP_ICM_NOICM")); } + ointent->set_active(pp->icm.outputIntent); ckbToneCurve->set_active (pp->icm.toneCurve); lastToneCurve = pp->icm.toneCurve; @@ -545,6 +559,10 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) onames->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->icm.outputIntent) { + ointent->set_active_text(M("GENERAL_UNCHANGED")); + } + if (!pedited->icm.dcpIlluminant) { dcpIll->set_active_text(M("GENERAL_UNCHANGED")); } @@ -605,6 +623,13 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pp->icm.output = onames->get_active_text(); } + int ointentVal = ointent->get_active_row_number(); + if (ointentVal >= 0 && ointentVal < RI__COUNT) { + pp->icm.outputIntent = static_cast(ointentVal); + } else { + pp->icm.outputIntent = rtengine::RI_PERCEPTUAL; + } + pp->icm.freegamma = freegamma->get_active(); DCPProfile* dcp = NULL; @@ -641,6 +666,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pedited->icm.input = !iunchanged->get_active (); pedited->icm.working = wnames->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.output = onames->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->icm.outputIntent = ointent->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent (); pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent (); @@ -876,7 +902,7 @@ void ICMPanel::opChanged () { if (listener) { - listener->panelChanged (EvOProfile, onames->get_active_text()); + listener->panelChanged (EvOProfile, Glib::ustring(onames->get_active_text())+Glib::ustring("\n")+ointent->get_active_text()); } } @@ -979,6 +1005,7 @@ void ICMPanel::setBatchMode (bool batchMode) iVBox->reorder_child (*iunchanged, 5); removeIfThere (this, saveRef); onames->append_text (M("GENERAL_UNCHANGED")); + ointent->append_text (M("GENERAL_UNCHANGED")); wnames->append_text (M("GENERAL_UNCHANGED")); wgamma->append_text (M("GENERAL_UNCHANGED")); dcpIll->append_text (M("GENERAL_UNCHANGED")); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 93828f5fd..e10f42b20 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -78,6 +78,7 @@ private: MyComboBoxText* wgamma; MyComboBoxText* onames; + MyComboBoxText* ointent; Gtk::RadioButton* ofromdir; Gtk::RadioButton* ofromfile; Gtk::RadioButton* iunchanged; diff --git a/rtgui/options.cc b/rtgui/options.cc index ce85acc09..1ffc74e2b 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,6 +470,7 @@ void Options::setDefaults () fastexport_icm_input = "(camera)"; fastexport_icm_working = "ProPhoto"; fastexport_icm_output = "RT_sRGB"; + fastexport_icm_outputIntent = rtengine::RI_PERCEPTUAL; fastexport_icm_gamma = "default"; fastexport_resize_enabled = true; fastexport_resize_scale = 1; @@ -636,7 +637,7 @@ void Options::setDefaults () rtSettings.leveldnautsimpl = 0; rtSettings.monitorProfile = Glib::ustring(); - rtSettings.monitorIntent = 1; + rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" @@ -1461,7 +1462,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.monitorIntent = keyFile.get_integer("Color Management", "Intent"); + rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -1712,6 +1713,10 @@ int Options::readFromFile (Glib::ustring fname) fastexport_icm_output = keyFile.get_string ("Fast Export", "fastexport_icm_output" ); } + if (keyFile.has_key ("Fast Export", "fastexport_icm_output_intent" )) { + fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" )); + } + if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) { fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" ); } @@ -2075,6 +2080,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); + keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent ); keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); diff --git a/rtgui/options.h b/rtgui/options.h index 614042fa2..969b66642 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -264,6 +264,7 @@ public: Glib::ustring fastexport_icm_input; Glib::ustring fastexport_icm_working; Glib::ustring fastexport_icm_output; + rtengine::eRenderingIntent fastexport_icm_outputIntent; Glib::ustring fastexport_icm_gamma; bool fastexport_resize_enabled; double fastexport_resize_scale; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ac2fe6523..28d4c13b8 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -816,6 +816,7 @@ void ParamsEdited::initFrom (const std::vector icm.dcpIlluminant = icm.dcpIlluminant && p.icm.dcpIlluminant == other.icm.dcpIlluminant; icm.working = icm.working && p.icm.working == other.icm.working; icm.output = icm.output && p.icm.output == other.icm.output; + icm.outputIntent = icm.outputIntent && p.icm.outputIntent == other.icm.outputIntent; icm.gamma = icm.gamma && p.icm.gamma == other.icm.gamma; icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma; icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos; @@ -2119,6 +2120,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.icm.output = mods.icm.output; } + if (icm.outputIntent) { + toEdit.icm.outputIntent = mods.icm.outputIntent; + } + //if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos; //if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos; if (icm.gampos) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3fa753013..1993c7aaa 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -530,6 +530,7 @@ public: bool dcpIlluminant; bool working; bool output; + bool outputIntent; bool gamma; bool gampos; bool slpos; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4aa1d2427..56fb63c3e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1434,7 +1434,7 @@ void Preferences::storePreferences () #if !defined(__APPLE__) // monitor profile not supported on apple moptions.rtSettings.monitorProfile = monProfile->get_active_text (); - moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif diff --git a/tools/source_icons/scalable/intent-absolute.file b/tools/source_icons/scalable/intent-absolute.file new file mode 100644 index 000000000..57278bff2 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.file @@ -0,0 +1 @@ +intent-absolute.png,w25,actions diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg new file mode 100644 index 000000000..497ce9c66 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -0,0 +1,1378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-perceptual.file b/tools/source_icons/scalable/intent-perceptual.file new file mode 100644 index 000000000..3e7520042 --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.file @@ -0,0 +1 @@ +intent-perceptual.png,w25,actions diff --git a/tools/source_icons/scalable/intent-perceptual.svg b/tools/source_icons/scalable/intent-perceptual.svg new file mode 100644 index 000000000..ab34b86b7 --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.svg @@ -0,0 +1,1366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-relative.file b/tools/source_icons/scalable/intent-relative.file new file mode 100644 index 000000000..5191a25c3 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.file @@ -0,0 +1 @@ +intent-relative.png,w25,actions diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg new file mode 100644 index 000000000..31a2fb342 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.svg @@ -0,0 +1,1374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-saturation.file b/tools/source_icons/scalable/intent-saturation.file new file mode 100644 index 000000000..9f33b978e --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.file @@ -0,0 +1 @@ +intent-saturation.png,w25,actions diff --git a/tools/source_icons/scalable/intent-saturation.svg b/tools/source_icons/scalable/intent-saturation.svg new file mode 100644 index 000000000..638df39f2 --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.svg @@ -0,0 +1,1366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/softProof.file b/tools/source_icons/scalable/softProof.file new file mode 100644 index 000000000..e275113ec --- /dev/null +++ b/tools/source_icons/scalable/softProof.file @@ -0,0 +1 @@ +softProof.png,w22,actions diff --git a/tools/source_icons/scalable/softProof.svg b/tools/source_icons/scalable/softProof.svg new file mode 100644 index 000000000..7d142fc4c --- /dev/null +++ b/tools/source_icons/scalable/softProof.svg @@ -0,0 +1,1389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + From e9141dd98c98d3e8d9dee1fb36bfa0cfbef360d8 Mon Sep 17 00:00:00 2001 From: Hombre Date: Fri, 18 Dec 2015 01:45:59 +0100 Subject: [PATCH 07/16] Cleaning up the GUI for the monitor profile and rendering intent + output profile rendering intent + soft-proof button. DCP profile GUI switched from 2x2 array to a single column. --- rtdata/languages/default | 3 +- rtengine/iccstore.cc | 5 +++ rtengine/improcfun.cc | 4 -- rtgui/editorpanel.cc | 87 ++++++++++++++++++++++------------------ rtgui/editorpanel.h | 2 +- rtgui/icmpanel.cc | 26 ++++++------ rtgui/popupbutton.cc | 5 +++ rtgui/popupbutton.h | 1 + 8 files changed, 75 insertions(+), 58 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ad30fbff2..a5e4611c6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -773,6 +773,7 @@ MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l MAIN_TOOLTIP_THRESHOLD;Threshold MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +MONITOR_SOFTPROOF;Soft-proof MONITOR_PROFILE_SYSTEM;System default NAVIGATOR_B;B: NAVIGATOR_G;G: @@ -1513,7 +1514,7 @@ TP_ICM_INPUTPROFILE;Input Profile TP_ICM_LABEL;Color Management TP_ICM_NOICM;No ICM: sRGB Output TP_ICM_OUTPUTPROFILE;Output Profile -TP_ICM_OUTPUTPROFILEINTENT;Output Rendering Intent +TP_ICM_PROFILEINTENT;Rendering Intent TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 24f2bb936..b77da03dd 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -478,6 +478,11 @@ void ICCStore::findDefaultMonitorProfile () if (GetICMProfileA(hDC, &profileLength, profileName)) { defaultMonitorProfile = Glib::ustring(profileName); + defaultMonitorProfile = Glib::path_get_basename(defaultMonitorProfile); + size_t pos = defaultMonitorProfile.rfind("."); + if (pos != Glib::ustring::npos) { + defaultMonitorProfile = defaultMonitorProfile.substr(0, pos); + } } // might fail if e.g. the monitor has no profile diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index e99daa79a..8866cd398 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -211,11 +211,9 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Gli cmsHPROFILE monitor = iccStore->getProfile (monitorProfile); - printf("ImProcFunctions::updateColorProfiles / monitor profile = %s / intent = %d\n", monitorProfile.c_str(), monitorIntent); if (monitor) { MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - printf(" - monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision @@ -229,9 +227,7 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Gli //TODO: Create a dedicated softproof transformation (line below to be finished) //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING ); - printf(" - lab2outputTransform = cmsCreateTransform / intent=%d\n", icm.outputIntent); lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - printf(" - output2monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index a762fc95b..74fa2f937 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -37,9 +37,8 @@ class MonitorProfileSelector private: Gtk::ToggleButton* softProof; MyComboBoxText* profileBox; - //PopUpButton* intentBox; - MyComboBoxText* intentBox; - sigc::connection profileConn, intentConn; + PopUpButton* intentBox; + sigc::connection profileConn, intentConn, softProofConn; rtengine::StagedImageProcessor* processor; @@ -51,7 +50,8 @@ private: softProof = Gtk::manage(new Gtk::ToggleButton()); softProof->add(*softProofImg); softProof->set_relief(Gtk::RELIEF_NONE); - softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); + softProof->set_tooltip_text(M("MONITOR_SOFTPROOF")); + softProofConn = softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); } void prepareProfileBox () @@ -76,17 +76,13 @@ private: void prepareIntentBox () { - intentBox = Gtk::manage(new MyComboBoxText()); - intentBox->set_size_request(-1,-1); - //intentBox = Gtk::manage(new PopUpButton()); - - intentBox->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox->append_text (M("PREFERENCES_INTENT_RELATIVE")); - //intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); - //intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); - //intentBox->setSelected(0); - intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); - //intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); + PopUpButton *bt = new PopUpButton(); + intentBox = Gtk::manage(bt); + intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox->setSelected(0); + intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); + intentBox->show(); } void softProofToggled () @@ -105,6 +101,7 @@ private: void updateParameters () { Glib::ustring profile; + profileBox->set_tooltip_text(profileBox->get_active_text ()); #ifdef WIN32 if (profileBox->get_active_row_number () == 1) { profile = rtengine::iccStore->getDefaultMonitorProfileStr (); @@ -121,23 +118,36 @@ private: profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring(); #endif - std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); - const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; - const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; - - if (supportsPerceptual && supportsRelativeColorimetric) { - intentBox->set_sensitive (true); - } - else { + // MonitorProfile = None , disabling everything + if (profileBox->get_active_row_number () == 0) { + profile.clear(); bool wasBlocked = intentConn.block(true); - intentBox->set_active(supportsPerceptual ? 0 : 1); - //intentBox->setSelected(supportsPerceptual ? 0 : 1); + intentBox->setSelected(1); intentBox->set_sensitive (false); intentConn.block(wasBlocked); + softProof->set_active(false); + softProof->set_sensitive(false); + wasBlocked = softProofConn.block(true); + softProofConn.block(wasBlocked); + + } else { + std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + + if (supportsPerceptual && supportsRelativeColorimetric) { + intentBox->set_sensitive (true); + } + else { + bool wasBlocked = intentConn.block(true); + intentBox->setSelected(supportsPerceptual ? 0 : 1); + intentBox->set_sensitive (false); + intentConn.block(wasBlocked); + } + softProof->set_sensitive(true); } - //rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; - rtengine::eRenderingIntent intent = intentBox->get_active_row_number() > 0 ? rtengine::RI_RELATIVE : rtengine::RI_PERCEPTUAL; + rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; if (!processor) { return; @@ -148,9 +158,14 @@ private: //options.rtSettings.monitorIntent = intent; // ...or store them locally - printf("Appel de processor->setMonitorProfile(%s, %d)\n", profile.c_str(), intent); + processor->beginUpdateParams (); + if (options.rtSettings.verbose) { + printf("Monitor profile: %s, Intent: %s)\n", + profile.empty() ? "None" : profile.c_str(), + intent > 0 ? M("PREFERENCES_INTENT_PERCEPTUAL").c_str() : M("PREFERENCES_INTENT_RELATIVE").c_str() + ); + } processor->setMonitorProfile(profile, intent); - printf("Appel de processor->endUpdateParams(%d)\n", rtengine::EvMonitorTransform); processor->endUpdateParams (rtengine::EvMonitorTransform); } @@ -169,8 +184,8 @@ public: void pack_end_in (Gtk::Box* box) { box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); - box->pack_end (*intentBox, Gtk::PACK_SHRINK, 0); - box->pack_end (*profileBox, Gtk::PACK_EXPAND_WIDGET, 0); + box->pack_end (*intentBox->buttonGroup, Gtk::PACK_SHRINK, 0); + box->pack_end (*profileBox, Gtk::PACK_SHRINK, 0); } void reset () @@ -190,12 +205,10 @@ public: profileConn.block(wasBlocked); #endif wasBlocked = intentConn.block(true); - intentBox->set_active (options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); - //intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); intentConn.block(wasBlocked); - // useless, set_active will trigger the signal_changed event - //updateParameters (); + updateParameters(); } void setImageProcessor (rtengine::StagedImageProcessor* imageProc) { @@ -205,7 +218,7 @@ public: }; EditorPanel::EditorPanel (FilePanel* filePanel) - : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) + : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), monitorProfile(new MonitorProfileSelector ()), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { epih = new EditorPanelIdleHelper; @@ -438,7 +451,6 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // Monitor profile buttons iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); - monitorProfile = new MonitorProfileSelector (); monitorProfile->pack_end_in (iops); editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); @@ -577,7 +589,6 @@ EditorPanel::~EditorPanel () delete ppframe; delete leftbox; delete vboxright; - delete monitorProfile; //delete saveAsDialog; if(catalogPane) { diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 0575b7f92..ffb8a93a4 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -86,7 +86,7 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; - MonitorProfileSelector* monitorProfile; + std::auto_ptr monitorProfile; ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 55e8e1a6e..8b2965cab 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -83,7 +83,8 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch dcpFrame = Gtk::manage (new Gtk::Frame ("DCP")); Gtk::VBox* dcpFrameVBox = Gtk::manage (new Gtk::VBox ()); - dcpFrameVBox->set_border_width(4); + dcpFrameVBox->set_border_width(0); + dcpFrameVBox->set_spacing(2); Gtk::HBox* dcpIllHBox = Gtk::manage (new Gtk::HBox ()); dcpIllLabel = Gtk::manage (new Gtk::Label (M("TP_ICM_DCPILLUMINANT") + ":")); @@ -101,29 +102,25 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch dcpIllHBox->pack_start(*dcpIllLabel, Gtk::PACK_SHRINK, 4); dcpIllHBox->pack_start(*dcpIll); - Gtk::HBox* c1HBox = Gtk::manage ( new Gtk::HBox(true, 4)); ckbToneCurve = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_TONECURVE"))); ckbToneCurve->set_sensitive (false); ckbToneCurve->set_tooltip_text (M("TP_ICM_TONECURVE_TOOLTIP")); ckbApplyHueSatMap = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYHUESATMAP"))); ckbApplyHueSatMap->set_sensitive (false); ckbApplyHueSatMap->set_tooltip_text (M("TP_ICM_APPLYHUESATMAP_TOOLTIP")); - c1HBox->pack_start (*ckbToneCurve); - c1HBox->pack_start (*ckbApplyHueSatMap); - Gtk::HBox* c2HBox = Gtk::manage ( new Gtk::HBox(true, 4)); ckbApplyLookTable = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYLOOKTABLE"))); ckbApplyLookTable->set_sensitive (false); ckbApplyLookTable->set_tooltip_text (M("TP_ICM_APPLYLOOKTABLE_TOOLTIP")); ckbApplyBaselineExposureOffset = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET"))); ckbApplyBaselineExposureOffset->set_sensitive (false); ckbApplyBaselineExposureOffset->set_tooltip_text (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP")); - c2HBox->pack_start (*ckbApplyLookTable); - c2HBox->pack_start (*ckbApplyBaselineExposureOffset); - dcpFrameVBox->pack_start(*dcpIllHBox); - dcpFrameVBox->pack_start(*c1HBox); - dcpFrameVBox->pack_start(*c2HBox); + dcpFrameVBox->pack_start(*dcpIllHBox, Gtk::PACK_SHRINK, 0); + dcpFrameVBox->pack_start(*ckbToneCurve, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyHueSatMap, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyLookTable, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyBaselineExposureOffset, Gtk::PACK_SHRINK,0); dcpFrame->add(*dcpFrameVBox); dcpFrame->set_sensitive(false); iVBox->pack_start (*dcpFrame); @@ -194,16 +191,17 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->set_active (0); // Rendering intent - - Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_OUTPUTPROFILEINTENT"))); - oVBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); + Gtk::HBox *riHBox = Gtk::manage ( new Gtk::HBox()); + Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_PROFILEINTENT")+":")); + riHBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); ointent = Gtk::manage (new MyComboBoxText ()); - oVBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); + riHBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); ointent->set_active(0); + oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK); // Output gamma diff --git a/rtgui/popupbutton.cc b/rtgui/popupbutton.cc index 440d7b420..e0cca8bd0 100644 --- a/rtgui/popupbutton.cc +++ b/rtgui/popupbutton.cc @@ -39,3 +39,8 @@ void PopUpButton::set_tooltip_text (const Glib::ustring &text) { PopUpCommon::set_tooltip_text (text); } + +void PopUpButton::set_sensitive (bool isSensitive) +{ + buttonGroup->set_sensitive(isSensitive); +} diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h index 23a9211a8..dec848b14 100644 --- a/rtgui/popupbutton.h +++ b/rtgui/popupbutton.h @@ -31,6 +31,7 @@ public: PopUpButton (const Glib::ustring& label = ""); void show (); void set_tooltip_text (const Glib::ustring &text); + void set_sensitive (bool isSensitive=true); }; #endif From 052533bdcc049469a2140c2ea8c49817285b0e0f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 19 Dec 2015 15:45:35 +0100 Subject: [PATCH 08/16] Always enable C++11 support and warn if GCC older than 4.9 is used. --- CMakeLists.txt | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4724c4001..6f5c168f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,14 @@ endif () string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) +# Set required C and C++ standards and check GCC version +SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11") +SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9") + message(WARNING "RawTherapee should be built using GCC version 4.9 or higher!") +endif() + # We might want to build using the old C++ ABI, even when using a new GCC version if (USE_OLD_CXX_ABI) add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0) @@ -89,6 +97,7 @@ option(USE_EXPERIMENTAL_LANG_VERSIONS "Build RT with -std=c++0x" OFF) option (BUILD_SHARED "Build rawtherapee with shared libraries" OFF) option (WITH_BZIP "Build with Bzip2 support" ON) option (WITH_MYFILE_MMAP "Build using memory mapped file" ON) +option (WITH_LTO "Build with link-time optimizations" OFF) option (OPTION_OMP "Build with OpenMP support" ON) option (PROTECT_VECTORS "Protect critical vectors by custom R/W Mutex, recommanded even if your std::vector is thread safe" ON) option (STRICT_MUTEX "True (recommended): MyMutex will behave like POSIX Mutex; False: MyMutex will behave like POSIX RecMutex; Note: forced to ON for Debug builds" ON) @@ -266,6 +275,12 @@ if (WITH_MYFILE_MMAP) add_definitions (-DMYFILE_MMAP) endif (WITH_MYFILE_MMAP) +if (WITH_LTO) + SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto") + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") +endif (WITH_LTO) + if (OPTION_OMP) find_package(OpenMP) if (OPENMP_FOUND) @@ -273,11 +288,6 @@ if (OPTION_OMP) endif (OPENMP_FOUND) endif (OPTION_OMP) -if(USE_EXPERIMENTAL_LANG_VERSIONS OR NOT (SIGC_VERSION VERSION_LESS 2.5.1)) - SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu1x") - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") -endif () - # find out whether we are building out of source get_filename_component(ABS_SOURCE_DIR "${PROJECT_SOURCE_DIR}" ABSOLUTE) get_filename_component(ABS_BINARY_DIR "${CMAKE_BINARY_DIR}" ABSOLUTE) From 151556ae23b0ec883a098c739c18092aac69bb4f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 20 Dec 2015 15:56:12 +0100 Subject: [PATCH 09/16] Add an optional function to the pop-up button, so that it will select the next entry when clicked and also do some miscellaneous code clean-ups including forward declarations. --- rtgui/colortoning.cc | 1 + rtgui/diagonalcurveeditorsubgroup.cc | 1 + rtgui/editorpanel.cc | 3 +- rtgui/flatcurveeditorsubgroup.cc | 1 + rtgui/popupbutton.cc | 29 ++++++- rtgui/popupbutton.h | 11 ++- rtgui/popupcommon.cc | 119 +++++++++++---------------- rtgui/popupcommon.h | 49 +++++++---- rtgui/popuptogglebutton.h | 2 +- rtgui/retinex.cc | 1 + rtgui/wavelet.cc | 1 + 11 files changed, 127 insertions(+), 91 deletions(-) diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 38cf88230..99ad03e9f 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -3,6 +3,7 @@ */ #include "colortoning.h" #include "mycurve.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index ad896789f..4ca2bb159 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -30,6 +30,7 @@ #include "mydiagonalcurve.h" #include "curveeditor.h" #include "diagonalcurveeditorsubgroup.h" +#include "rtimage.h" DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 74fa2f937..621c088e3 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -29,6 +29,7 @@ #include "soundman.h" #include "rtimage.h" #include +#include "popupbutton.h" using namespace rtengine::procparams; @@ -76,7 +77,7 @@ private: void prepareIntentBox () { - PopUpButton *bt = new PopUpButton(); + PopUpButton *bt = new PopUpButton(Glib::ustring(), true); intentBox = Gtk::manage(bt); intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 516bed44a..691fbe3dd 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -31,6 +31,7 @@ #include "myflatcurve.h" #include "curveeditor.h" #include "flatcurveeditorsubgroup.h" +#include "rtimage.h" FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { diff --git a/rtgui/popupbutton.cc b/rtgui/popupbutton.cc index e0cca8bd0..554f41cc6 100644 --- a/rtgui/popupbutton.cc +++ b/rtgui/popupbutton.cc @@ -21,6 +21,8 @@ #include "popupbutton.h" +#include + /* * PopUpButton::PopUpButton (const Glib::ustring& label, bool imgRight) * @@ -28,8 +30,14 @@ * * Parameters: * label = label displayed in the button + * nextOnClicked = selects the next entry if the button is clicked */ -PopUpButton::PopUpButton (const Glib::ustring& label) : Gtk::Button(), PopUpCommon(this, label) { } +PopUpButton::PopUpButton (const Glib::ustring& label, bool nextOnClicked) + : Gtk::Button () + , PopUpCommon (this, label) + , nextOnClicked(nextOnClicked) +{ +} void PopUpButton::show() { @@ -44,3 +52,22 @@ void PopUpButton::set_sensitive (bool isSensitive) { buttonGroup->set_sensitive(isSensitive); } + +bool PopUpButton::on_button_release_event (GdkEventButton* event) +{ + if (nextOnClicked && getEntryCount () > 1) + { + const int last = getEntryCount () - 1; + int next = getSelected (); + + if (event->state & GDK_SHIFT_MASK) { + next = next > 0 ? next - 1 : last; + } else { + next = next < last ? next + 1 : 0; + } + + entrySelected (next); + } + + return Gtk::Button::on_button_release_event(event); +} diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h index dec848b14..245d29aee 100644 --- a/rtgui/popupbutton.h +++ b/rtgui/popupbutton.h @@ -21,17 +21,24 @@ #ifndef _POPUPBUTTON_ #define _POPUPBUTTON_ -#include +#include #include "popupcommon.h" class PopUpButton : public Gtk::Button, public PopUpCommon { public: - PopUpButton (const Glib::ustring& label = ""); + PopUpButton (const Glib::ustring& label = Glib::ustring (), bool nextOnClicked = false); void show (); void set_tooltip_text (const Glib::ustring &text); void set_sensitive (bool isSensitive=true); + +protected: + bool on_button_release_event (GdkEventButton* event); + +private: + bool nextOnClicked; + }; #endif diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 2a1387d3f..8acbd2802 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -26,6 +26,9 @@ #include "rtimage.h" PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) + : selected (-1) // -1 means that the button is invalid + , menu (0) + , buttonImage (0) { button = thisButton; hasMenu = false; @@ -42,15 +45,6 @@ PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) // Create the global container and put the button in it buttonGroup = Gtk::manage( new Gtk::HBox(false, 0)); buttonGroup->pack_start(*button, Gtk::PACK_EXPAND_WIDGET, 0); - // Create the list entry - imageFilenames.clear(); - images.clear(); - sItems.clear(); - items.clear(); - selected = -1; // -1 : means that the button is invalid - menu = 0; - buttonImage = 0; - buttonHint = ""; } PopUpCommon::~PopUpCommon () @@ -59,81 +53,59 @@ PopUpCommon::~PopUpCommon () delete *i; } - for (std::vector::iterator i = items.begin(); i != items.end(); ++i) { - delete *i; - } - - if (menu) { - delete menu; - } - - if (buttonImage) { - delete buttonImage; - } - + delete menu; + delete buttonImage; delete buttonGroup; } -PopUpCommon::type_signal_changed PopUpCommon::signal_changed() +bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) { - return message; -} + if (label.empty ()) + return false; -bool PopUpCommon::addEntry (Glib::ustring fileName, Glib::ustring label) -{ - bool added = false; + // Create the image + RTImage* newImage = new RTImage(fileName); + images.push_back(newImage); + imageFilenames.push_back(fileName); + int currPos = (int)images.size(); + // Create the menu item + Gtk::ImageMenuItem* newItem = Gtk::manage(new Gtk::ImageMenuItem (*newImage, label)); - if ( label.size() ) { - imageFilenames.push_back(fileName); - sItems.push_back(label); - // Create the image - RTImage* newImage = new RTImage(fileName); - images.push_back(newImage); - int currPos = (int)images.size(); - // Create the menu item - Gtk::ImageMenuItem* newItem = new Gtk::ImageMenuItem (*newImage, label); - items.push_back(newItem); - - if (selected == -1) { - // Create the menu on the first item - menu = new Gtk::Menu (); - // Create the image for the button - buttonImage = new RTImage(fileName); - // Use the first image by default - imageContainer->pack_start(*buttonImage, Gtk::PACK_EXPAND_WIDGET); - selected = 0; - } - - // When there is at least 1 choice, we add the arrow button - if (images.size() == 1) { - Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); - RTImage* arrowImage = Gtk::manage( new RTImage("popuparrow.png") ); - arrowButton->add(*arrowImage); //menuSymbol); - arrowButton->set_relief (Gtk::RELIEF_NONE); - arrowButton->set_border_width (0); - buttonGroup->pack_start(*arrowButton, Gtk::PACK_SHRINK, 0); - arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); - hasMenu = true; - } - - newItem->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &PopUpCommon::entrySelected), currPos - 1)); - menu->attach (*newItem, 0, 1, currPos - 1, currPos); - // The item has been created - added = true; + if (selected == -1) { + // Create the menu on the first item + menu = new Gtk::Menu (); + // Create the image for the button + buttonImage = new RTImage(fileName); + // Use the first image by default + imageContainer->pack_start(*buttonImage, Gtk::PACK_EXPAND_WIDGET); + selected = 0; } - return added; + // When there is at least 1 choice, we add the arrow button + if (images.size() == 1) { + Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); + RTImage* arrowImage = Gtk::manage( new RTImage("popuparrow.png") ); + arrowButton->add(*arrowImage); //menuSymbol); + arrowButton->set_relief (Gtk::RELIEF_NONE); + arrowButton->set_border_width (0); + buttonGroup->pack_start(*arrowButton, Gtk::PACK_SHRINK, 0); + arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); + hasMenu = true; + } + + newItem->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &PopUpCommon::entrySelected), currPos - 1)); + menu->attach (*newItem, 0, 1, currPos - 1, currPos); + + return true; } // TODO: 'PopUpCommon::removeEntry' method to be created... void PopUpCommon::entrySelected (int i) { - if (setSelected((unsigned int)i)) - // Emit a a signal if the selected item has changed - { - message.emit(selected); - } + // Emit a a signal if the selected item has changed + if (setSelected (i)) + message (selected); } void PopUpCommon::setItemSensitivity (int i, bool isSensitive) { @@ -181,7 +153,12 @@ void PopUpCommon::setButtonHint() } if (selected > -1) { - hint += sItems.at(selected); + // HACK: Gtk::MenuItem::get_label does not seem to work reliably. + Gtk::MenuItem& item = menu->items ()[selected]; + Gtk::Label* label = dynamic_cast(item.get_child ()); + + if (label) + hint += label->get_text (); } button->set_tooltip_markup(hint); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 7b05a08e9..04044fb2d 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -21,11 +21,21 @@ #ifndef _POPUPCOMMON_ #define _POPUPCOMMON_ +#include +#include +#include -#include -#include -#include "rtimage.h" +namespace Gtk +{ +class HBox; +class Menu; +class Button; +class ImageMenuItem; +} +typedef struct _GdkEventButton GdkEventButton; + +class RTImage; class PopUpCommon { @@ -37,12 +47,10 @@ public: PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); - bool addEntry (Glib::ustring fileName, Glib::ustring label); + bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label); + int getEntryCount () const; bool setSelected (int entryNum); - int getSelected () - { - return selected; - } + int getSelected () const; void setButtonHint(); void show (); void set_tooltip_text (const Glib::ustring &text); @@ -50,14 +58,8 @@ public: private: type_signal_changed message; - /* - TODO: MenuItem::get_label() doesn't return any string, or an empty string !? - That's why we store entries strings in sItems, but it would be nice to get ride of it... - */ - std::vector sItems; std::vector imageFilenames; std::vector images; - std::vector items; Glib::ustring buttonHint; RTImage* buttonImage; Gtk::HBox* imageContainer; @@ -67,9 +69,26 @@ private: bool hasMenu; void showMenu(GdkEventButton* event); - void entrySelected (int i); void setItemSensitivity (int i, bool isSensitive); +protected: + void entrySelected (int i); + }; +inline PopUpCommon::type_signal_changed PopUpCommon::signal_changed () +{ + return message; +} + +inline int PopUpCommon::getEntryCount () const +{ + return images.size(); +} + +inline int PopUpCommon::getSelected () const +{ + return selected; +} + #endif diff --git a/rtgui/popuptogglebutton.h b/rtgui/popuptogglebutton.h index 58342e66c..930fae4f2 100644 --- a/rtgui/popuptogglebutton.h +++ b/rtgui/popuptogglebutton.h @@ -21,7 +21,7 @@ #ifndef _POPUPTOGGLEBUTTON_ #define _POPUPTOGGLEBUTTON_ -#include "popupbutton.h" +#include #include "popupcommon.h" class PopUpToggleButton : public Gtk::ToggleButton, public PopUpCommon diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index b964ecbb5..43cbe4f28 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -3,6 +3,7 @@ */ #include "retinex.h" #include "mycurve.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 4bebb10ad..abab1d2d1 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -21,6 +21,7 @@ #include #include "edit.h" #include "guiutils.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; From 0daea6659747ce4b0eeecbf56dcd37cae4a6c0ba Mon Sep 17 00:00:00 2001 From: Hombre Date: Mon, 28 Dec 2015 14:43:37 +0100 Subject: [PATCH 10/16] Adding the Absolute entry for monitor rendering intent + icons updated --- .../images/Dark/actions/intent-absolute.png | Bin 464 -> 670 bytes .../images/Dark/actions/intent-perceptual.png | Bin 666 -> 898 bytes .../images/Dark/actions/intent-relative.png | Bin 944 -> 1072 bytes .../images/Dark/actions/intent-saturation.png | Bin 809 -> 1012 bytes rtdata/images/Dark/actions/softProof.png | Bin 827 -> 842 bytes .../images/Light/actions/intent-absolute.png | Bin 445 -> 674 bytes .../Light/actions/intent-perceptual.png | Bin 638 -> 847 bytes .../images/Light/actions/intent-relative.png | Bin 882 -> 1057 bytes .../Light/actions/intent-saturation.png | Bin 779 -> 1007 bytes rtdata/images/Light/actions/softProof.png | Bin 868 -> 915 bytes rtgui/editorpanel.cc | 10 +- rtgui/popupcommon.h | 2 +- .../source_icons/scalable/intent-absolute.svg | 122 +++++++++++------- .../scalable/intent-perceptual.svg | 70 +++++----- .../source_icons/scalable/intent-relative.svg | 53 +++++--- .../scalable/intent-saturation.svg | 72 +++++------ tools/source_icons/scalable/softProof.svg | 4 +- 17 files changed, 182 insertions(+), 151 deletions(-) diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png index bb7e1a85d0cf0b4a131e3dc02ef8e74161a5f367..7732eba534d0ac33ee87d0275054fa27426bcb94 100644 GIT binary patch delta 572 zcmV-C0>k~#1D*wtZGQqANklPv`rxu3axWCQ#04v zws_kX?b^4OHZ58O(b`222!R`6m_JBFE{mWb5*LvKDm=t=NPX{~7C9i2j*}1ituFT* ze&4<49ynJ3TCLW_y}i8%Ac~?LYwbpi4WyN+j<2c^xtZTK}porWw z#@q!i0h_?Ab8fy|E~mZRFH@RIXQXOIaeqY3Ol7zX$$x(s8g;-A~M$P+Pz9uzgDZ& zrw%|w)>O5aH$+6%^7cF$2GDFaABGSv=WT9`S*}znFMmwl#{W&7?uu1)v|Dn|<|5y# z)#|JRP}Qr(m}_}MLI`K__B>JoP_Nf-i^y=d7nI>ZhHo+>D!5^^6BLsI-rd03| z(%VX~wa+_fnQoJ{vq>Q-v{A9L(sVJh2)p-MsAXU-jCkt9_rYc6&JX}(S=M4^4@G9P z+0$@1nNv2Yqmzu&J^ zlAk_5oK+~hKtB+uh+YF0AQ_6wC_nsthM(5z9qFh=2D#+XYC5s|3d?M9VK<%A1B02+S5@_fh=f2FxCb=Li7Gt?d|ROr9~!bwOVgD=Qe@QRP{9x8K`R8dw)L+!-G<(H27DMDaQY4jOi^cEyZhV zYrWH(s@1AlUw>c!C`ppr#+X|`AR?-&T@m?fv`$qYmCNO?0|0C77o0NQdrut4G#U-3 zs?SvQv50hxF^{da9pGSVYwO3|-QA@i2yUin`Yv$U7?Yc*5dj1M&beYVvNbFYG%ro!*aQNXD*Rh?Ck9178Vwkz4znm%49PA&CShU1Au0;`K9;% zor@4N#*Cj;^(Wx&$df@31Q!w^lcZ@nfH^&x#jwkklO)NG-o0>L=VfHPwf35GZUwjw zyanWez<+y>wRXJTdw&Sr3E=E7T5I!Zn&yXHQvj}r$Vwc?c>w1efCG+!M?fSZJ?C7{ zT03sxG)@1RlhecKy&oGWA}R12@K8iLz>_3NI*W^oPfMjzTC3GA6$*t9z4xoYbyXdA zmx%lV{4jMGN3n8pa?+a?fYoZ%6pO`=o6Y8JRe${i2#hgjV#OHKgE@__*XwTvLGUTV zfK=6iG3I;VzP0w@%z&K5(a}+Oe0+Q+>P2KXm&<)yEEfC!Rb%Q;OI35mnAd?Ds=5k< zA`+?Uy)X=$8yg#)a~*xisD(dg!gvuuRRMli)$f3IyWM_JtycX!#a|FPZG0w^d7jN? fqZ(=dlK;cse2jX}&U8Ab00000NkvXXu0mjfML(4T delta 567 zcmV-70?7S>2bu+tZhsd^L_t(YiM5t7XcSQphQBwn=UyR16e~MPh~U{;9h`8StCkii zLcl`O+NZnD!p>4mD^^xw?s5kygdi3oTnf=9a@be|P6CGAw{L865M=jq8*)lK|k=N~Z`^#J;yqdd>wsj3y_=6QYq6*bw}*{P>#dK+knNCQ{`bVkZvr_hEtg7ncvd&fYJMj5bGnS1NRb4Z)1v8s9R;rt^-|sh6b=}Nv zQguL{hA?v(^%uRgqT@mjoO3hRZyd*GUcXb}UtHuz;ve`mD&BLzDw6;J002ovPDHLk FV1iq93Sj^M diff --git a/rtdata/images/Dark/actions/intent-relative.png b/rtdata/images/Dark/actions/intent-relative.png index c1fb040a9ddabae8f9ebdd03367c2bacbba0978c..117806ddb42aac5c440c5634ce1279bbebb971b7 100644 GIT binary patch delta 976 zcmV;>126or2e1f`Zhx&wL_t(YiH%iDPg_SAJ>NIiZ{Ws}qSR>6S%)Kv(?(-Q*8+n{BsUcvI1ZWo%Ov386~ebOAt+hLaLZNl-BIR=VCdsj3Ael@?thEXN&bdB-{kgfh*Of{oNpi{wa%MC5?vOV9KE$mMb!04SA8A4Q|lthIJrRWkraL?j+gPV(0v2)>c4x>#FV8|`#D z84-EtoSOnL2_QXydm{2L$u}hX#+YuX(Z7Qr_)Y+zQh%vDQPqhHYNSZMZA3&40c?@n zJU%|&Xf~TK78e)8`*6+#0IJpMV^zHy>Y^(mJ(7DQcdfPC3kwT>i3m%jQcP7Jsp>e% zj4>ufG8s!AOv^1JZr5;&pCslO{Cr8&Cz&!wagKsAkx*Y_;)6+@5 z0`Td%F@Hr80DO`oL(2^Sn*cVPbM<^a|LQ6wxU5JYK$qkmfL&|tw&!{EAPDvWpj0Z| zipS&Q&bbVLlyh!GRnH`F&i#|m=fA%eUBHRHk(?lzC7BhG+gC@O-1zryJOEg0V*q>+ z$p9Dy0Fpfb&qZXz^SpYy-QGzg5^r+3-0}M=d4Gez`y|6h*s5xqWRv7CBC-vj9*IPL z%jI&%#bVL;zJD(ki#@Q`j#aDGm~-xoeu>Ddd_Mo|+H@6*#i;N5AIru5OIkoS&cH1%TDn)p)1V`M?-+!&)0585@o_#_R)lEda2- zzMg0_8fMtR_kD&RrE`*upKfhNj7PIJrhyZ{m`9M{_cFwi?{r*qYYITt1a~%YL zIF2g-Qri|0FMlE@Ns@GGwOX%UubZ{CwMFlJKr%4Kyp|PQRZqe&{G5}jP*v{k?!J{I zNnngw0kEX1h4JcPD5Jo~VHkc%0BAHC_lz;OGx9i9&5ysI0ywhPwl6L&+SO{c zJE=%ud?q9xkWA%Q{yC5nl1CdG8xKk9-rn8|s=C~4Hh*gXUe5|HB9F@D@)r~70)YMf z{Tsbr?~aJ97-N#i|oApVFiDc5gM))#>h-!@4uh(`DI%$iko==mDt$jSUEAB+Ip^GMl7XrQBo_gs z>fJS531p+u_()Y>%BUt!a*5>osyZ`X>jH?ZwSVp5aCn-_M~YHW(uUL zJ|VdapzXbHS1OgWad)@!`TRSh(I}M>Ywe!^&Kv*~3Wd+Iq<(&WUd!e3IRHda^s;mA zgE)=@Rb2sa)B7xy2LN;cY+XwIVzF3E9Z6NqMNzag9^F?}6#xdR`lB)CTau^Vdr9*Z zkx0LQtIK#7Kq_4%L2^X$XA$|%IoBq6yuQAkB_;oX0{~;p{Uk|lq#8IU!{P9^X&;v#H$-}C;S45KL8^)L`BrlNsGmhhBYi$HzT~)P3XBhwzC#L}% zODZHmG7-E6V1HIsN8>pDHI+)u_V@QM3=a>dUDrM4y6#Z`PmydFkq(mgwK$mq@S_6& z#+diFwzh5x-WanHMbWiVsq|O!RxX!KZ*T9@VHm!aN~KN!*drn!xga9fN&ZH%-tyVs zn@+OXZ1r||_`aVp#uNa&2w*?SbyfYwT00TP@lWmT?SHzmvT^{x0RZSF* z4T~hX*BEm|M2?VDlHURNBA3hk5QgFL`T6;`NggMuBJvA>AprBLx}d5z5)s#RH=9mK z7D+aP2Y(QW$R7Yct=H>cl}e?#Fbp3Ig5XV6?Q4u{$Z?!XXJ_YftyX(pRr`!F2T8gK ziHJ-C*xvX|CiBkR+?-8{larGh<#JgX_8A000l>=uQmXo;h-w zi{vtZS(0lBkE&LIJ8Zn~`}>VCuLF2ORcDMb?|1|eCT=JRR9RX@L3T#LvjS>yjv&~7Iz~6?BWUsLC_&0Zx~~q6p>2+&KC-W_1y~GR%Bvg zBE7b@b`ro#B-5(;k>`1z?G)}EMSS0X)fn?=%X>;y4>ivC6v+>Ax!m->B~OqX$S#rx rTi!PST!`a%tXM35|6j@PDgFjNYM$N22@Vuu00000NkvXXu0mjf)!MSg delta 712 zcmV;(0yq8i2dM^-ZGQr$Nklc#CR(V7%&4te zg+Wl8B5D~SWG{McBB)L4{(!>P>KJa)MNrU#%3cIIL=Q@#VPu?hzAYLDg5T5_(b?Yb z`F`#>-+O`oPyztOVsV7zj(=`0GB+?Va4i6UnSJu!Xa6-sRewJL^-2D=ip641Rok1L z#~3U5e7+RcYU;i3B-v$VT_V!qy>EI^GkXSLG}N2B0OXQ{A`(Sp$EvBS3IHYfmgHUU z{W~+WCY&VzSe@hmfX*ZpNsv?#d1GdGLkLeZnap!l%~UFtLnM!jBoAX|F919Z0N|Xv zxw5j77<`P8&VRX5e}Dfn08CF$hjO{R7r=h!Tvk;dg%B!DwlLqAB%jZhnvDBPO-@ek ztkr5q0dxR(U9DEfQmNEBl8Jg%{n~)EV7}EkcZB3F0AJ1QMvU>Jh>Vg<%n|^+_s;-4 z2z8S_l8H~zIoA$gkff2k9b>$ss=cauh2&BQ;X<`qU4KgIjWJdllZeP35lIZbem)D} z*38Vz=boOPgCzHnd?zB0&FokR$qO;FR{(zg__nsTOA8ANK1rC%$pv_X$0|6iCTz_kRp;mlAR!= z2{I^_J`e&H5$uH6+N;>u2_a386nWfrhZLfQ2mu8V42UAZVwXI3vUhjxv2a$BHJir6gl)Pd{VqvN7i7zJnO5TO^|MmS^E^)rA(Rk8N-0I7IL(|ALX1sMPakb6&SWxQIp;~OR!gLm zDwT2}1Ovc0|0kLNSOV~JczC!h|1qX?cXw|XW4`R{>|9Ke#4*N*h{!od0LVG#(kWvA zZ)>%h8GjlYD%JB%#cAk$rBXRxE|<4F&r{Y~8^`f>9LE(R`pG#j6pO`oVHn!R?1AD^ zskGSH*?DDseO(A4q_wu+2D=83ZhyE*L_t(IjjfeUXcSox$NyDb-9r$TKtKdpSZ|7Z_Fy77Hgrq8 zh=&$D2#Ox|?#D$j;!V7XMnMpDL2u#;laH6!L{RYHl7JpWyc$T%C=QZz&+AtnG9%+S zGs%E|D0p2|{klHren3ML6BB>U&CUIZ-y~@seBVEv=eYxL5q|(CCntA%o_Cm;C&DoN zzh5u|fH7vjs_q1^D^1f801%N20FFE79vWlDr>3U1_5-FgO{FM`aaG;c@GWLpcD__9 zy#U}f16B2l=XqztFnqqLit{`#Ip=Pu>I{HsRlNydTPqX*h-lC`cgq-aY*XMkj=x1w zG*3i}&bh@Xiht%sguBFh04^D0&TI(oP4_Iy#q^mp=n20Dzgv^E?(2BBGxvB%-6k!^79oG?jKnM{trP1rdEFA_PIeK@hO- z`(6+PEF$ggAF|e7uT(0f4Z#4Qs_y_mM7(zMJg+_PKz|SfcNP{FwrmFc23Q}3@B7>| z5n&NwW~R3IJxfbV_tP{T>yY-hwf0`6Qu*VTp|`+ZTWbsFoQen& zk*aDFincuhfW`U;c5ifa^lMjexm^AYb z4iTX|&kG`YSro;CD2h@d(yqC^z~yq;GV>MZ+}C=&{;%)*2g5Kt5y$bfR_OHf^r`ks z;>QMzF$pv4%F4=<4(|v67a>bfi}Y-K45pus&AD z%paKfT-U!-KQhK#1u#fNbJc3~QIaG@&*k-@7Xt$W&qhW@YE8#?B7inNCLk&I00000 LNkvXXu0mjfO-@%3 diff --git a/rtdata/images/Light/actions/intent-absolute.png b/rtdata/images/Light/actions/intent-absolute.png index 1396e378553270124944c886d2536016f879e622..7a507e0f5cbea2301a3bccdc4b36630d804c1426 100644 GIT binary patch delta 576 zcmV-G0>Aye1EK|xZGQqENkl-|8NI{5*S4B|b<_D<=!nPo3(}W~s_UoZp$)!zFw)nlw z%-fmo=gllLPXNI4yo=V_MI5ScjA{A4-$qO_qxO-i7NTGnhJSEfcL<;X;48^5jYi`; z0GA?b8_vET1IQE+#6 z_aN%$^ZDh$U~pYT?vPvsuupO$old_km&?PcA)e}4{Q=-(u~__EDwS+5 zm%9ewJ^)ulet$ZS^Sn~2)TV;0t*zZAc_9jtTo92}k{*Bsl79efwcG8@APBmi=iMOr zfMf!|t9rfu2FLs_nUq8(lbKi5d1K6+s&7LvF%!x?f_x*#TKmq`{ zT<-BG>sTcs)mp9g%!~#*qpimc*@@fpXcz#vuKN(crGHcKZ`AAcmwF1u|3}e1xkqwk z(&U-VMSl6dzhMBtT6%({0`g;5beQU_X^gwWh6nlk^w1l;)l@3ok|h O0000-X&&nlR`SB%~kL%^cfUMAAkl+%Cfvv z)u?kNNfLK1;0}0-kyvZLV)|Q;0T_)&=c-zE4mYN%>-x&B9u}$^^_~Pu7F{zp%K(PM z;TR~kz<-&|W|L$K;QxsMaL%2m>Y#JDF|Q(WV*$MP`$>`T21{@)#mb(@w9~>l_{){)6{`2mnF|-%I-R{C_ZnfH;m3$MFkEJ7%_B ztyUjyZEdChhlBvIva<3SfcXr`B}rFERsh@pkR$oh-D~cCXK!!s>C7b4u(`RJ>-YP& zLI~dis19qIlJ15O?$+z|-aC_w5H6maoP1648vq{xIF__c^8R2j*xBFTKb}Z3Dm;J_ zl3jQ2HJi=un14E}R4QM%`)zl>MKS^)NiPAMUNk2gySuwTjTIhe6(EUnxtx-GM)HZf zADGz_GdoyZT->SEYJZeUrOWwzzDjb#%&th9%k=0>o1_S!0H7!-HnVGzmXTQwNh!%^ z0NTR|UIFNa5C&P2Mx*f{0)SSl)tn&1Ybck?MR#A0qJQWUNy{X!Nh*^p0{8#`-2LKv zl8*sAm`V6)SXx?|D-;TGk|Y<`6+-AY8jU|A09adF`$5v$yAq{o3i7}Imb44t=Li5u z9+P}85i){fU`C%zL#b4{JU>4lr)hfW{Oq;sdRt_LclTv8yYB8w0E#3dNief)$zuRN zM!>`sE`Q=|g+Da2kB2K<3?V=g0Hl)sBH57Ck<`VQ6$U1x@CXt~f0KMPG~?5u8QZm5 zEm>Gt$QKHQ&!Z@+0J!e%Su^efIP*!GroW7f6_VWv0ceuGTwhb%7 delta 540 zcmV+%0^|M92L1$)ZGQp#NklbRON=sR= zkZtYv7g*R?E^aGURw8U|BNnnSQ%FpPm0;t5gR+neL+-JeEtF(tGVGr6z4PwLefOUG zA^3f_^K?Ppn*Z+|TkhT$Cm*Xsz*xho_e zl2qs1huLiQW;&gov=&*1e!qXs%$}0G3*dz0+cZtz1F$m_IYk`DaaC2jA`%10Nxn|g z^vgyfK@fz_xyy9~=bSATi|>=k>LXQ! z@B6u#jhu7uM1&2Q`~q6mq}%OYQq_T~4oMD4Mk1msG8rdHve!zaPSo?f8zgJvsA`cU z$qx?zq9}S!GTK&5r2bn;egp8zTaroCU00i+b%k%bE&yWydmgab zjQF>OLlIGu0FVPX6p`a~Exgu@OEN?xCwW*^)yT}oMNur4W_;XqPDBy_pVykPX{`9Z zzeBPkBCEzqdou<>Fm%rC0=S8`19BbCWYnMcqvb6FJ!mTYvXhQT?k7pI)${8CfbaV+ eagIL{e-#0jvM`gDSQBdi0000?E!t3^JJJ#r{eb{U z8z4xj#=jwdAWhm7Y2Btxqaw&32&gVVnt-4vl1C~GB1I+~+14k?)80%99UbySOPuC_ zeLMSR-tD|404NrVE2{b!sSuG1$8oNP!{Jr8+dT!K={>WAlYe}_0`PSjWM+s6GMNm5 zAQ%!+6Tt7xTz6gfs9LRF&O$-}P$(20EiNuTm;i_}BEkTms@KeX+GsT1EH5wTJkKkO z$R;xfBJzZYmH=dK9ZpnhwOZefI_aOBoJ8XrJkR57Hk-57dLr^nRZBq-lmV=&DiM*Y z>LD{XMdTDfpMRO-6iM%WC&gm%dsW@Mt7TP<0UR)MT|{cen7wARc|MC=PQthgppmNL zDvskwRnM6Dm9_TIZnrxC0N?iu06q(Xph!e{5m^Ki7=}O4eN~i7r6nTDTWd?q zTn4bAsvjkAL`27``c_r1jWNUVToL&@48xx&sq8yuUVon=(E<`llgchcWS@xkn7OvK zwbkC)*@@G6w>koVAP8PC^V4x4j^klc={q9oF>|NUX#530ec#VA^K&99ib$S_7F0Di zrO0l(-Tv`jxqutVRP{M-q$;awKt!XP8L8?!B8mVE#`8p^)9G|x5&*2Nt$oAHYg5jj zCn8T(7k|gr4n<^-h-$f9u3oKHU*jGpaPGja0bBqGRka78BO>*KgM(85@O}UB<>h73 z_x;bAc_F!B6T!^?v|6p7XOauJ@izeLBC-i!lZck@%Nb4l2Y);O#BrPj;1N+Cz*4dt z5m8fBYXIu1dQ>PB-c~9V`ynz1094gi)rl*dOn-PEz&U_F0CWJnKL2+0RIxvZvgg*=#Yrcj4^}TG>CviE@u8RZIDC+RRs}U0C*)L zzkfQ8Q_o~Fd$n4v2LP+9t8;U6b05cX{7^(P*4k`}Ei0lHWTWj}6wm(aZCjO;}%%?$P kOkYIK!!SIX^}uQIA2l`3U`$oa>;M1&07*qoM6N<$f(FpQX#fBK delta 786 zcmV+t1MU2w2=WGyZGQsqNklXKa(q?6ngq!O|*{r9_*oXR~u&3Xc&%bInSe z?%p|{kKTJm03c1%tvHUmXfcwn%d$Lb`?jvd01!pd*JgG-P=DkEz*qmf2+3ba?gV_Q ze;&r;@s+BoG7-s0W+L)ID7lF2mu2~F3;>J8qNu7WYIEG&+)UCm{X$hU0NHZ6+!7H0 zc&)01ncY*>I#6T=00IDm!Qgw6t+>vOWDUTR%vCif`M`T$T@>?oF#s42hqp+!j%{YO zs+RNleE<0P_yD2 z8hkRHPJb2vaL#?Fs@K{aNyY#!HOChsvIihHv)p_Cbd4s@)FmQbL|XZhG?JyN?v-Wv z2mpt};X5QJ&bco|l8?RjKdplcy0l zH8aaZBm>|YF$C=mT+X>00NxMyUQ*RD$svHZR22Z8lH4(~JV}xxRSn@<0u3%zy>-!o zG_#qA?2^noolbsmaB$Kz*IO=^pIw0KIe-%Z&VL?TXw|DKXS3N$0LZdz^YrvI1CW{7 zwuoE_H3s|(SCS+yNs?Ac#&O))*w`48oGccL51Z>sME)T88-ODbv9{Q{uIE65D~{va zAzUOua;2&dN!}ru_j_0iGMjn&oF#?;i**u=!d3Fq8#l8;(zQvfDC&l`^mopTicKgQ#F z&pG#}#e1IDw$|RL)oR_Lu*&6fj};1qmjIk3IU*t;*$|PN0DcmYUVKid?zh&S z0`N4+F%hW)SWF}mUpwb!j4|_C>$3o+j4{w!!#Ovo7m=#~E_(ow&*z`S?vkOk7HjPh z00m=A0RTyUueJWHTCJ|k&d!!a-+wzBU*E~ZkcsMTscWsI3uN*yDah($;S0CsPD zyWM`X+wJN&*=#o30Ak-#EEX4>b1yjO4k@KRkD}Gx0Xz(#E+X#+K~OK1N`L8IuXhf>NdR@{+|v5``gZ`h7moly zsZ>e>7>R>BJ3EH~JWg@}fL2N^mdoW&mzS5V@B3Mjuamq-L_Q9~aB;}>o)7@=egB=| z%NUOoz-4Rg2laaW=l;1TNS*`G0q}MhhL!!uV|W1IoVy6%%22$SNF;(vrE)!PCZErr zA%A(A!1SricC*Wk0q1IQ_i{P zNsei)Kde@(pWrsjy`xAzpMOzA9vq4v0+7Y-%TUo;zrVJ&7W`fE81bJmP4d`4S)@(! ml2YocAP9c=r{s4Pe*h?1j$Np+MCSki00{s|MNUMnLSTYz#<9Nu delta 682 zcmV;b0#*I*2a5)fZGQrYNklQ?}BJGakOHPUzyVGsnR zVzKxO0EUN$U4N-mx+o%-Nw%r#M{DgyOztw!r175TodR$JKsU(+k~7Y^LvebNtGQh6 zeM81)GMN)$7>)oqO>)&*`z#E@vN2{%RU^HuPm%?&4N0fd=K#b##jY?6&x?qXd>I76 zD-k&hUB>GhRgAB@&4j*?(-d(%aj6mE`;{!8m}Fh|H*JQAF+lnD>2ueCOrGZUO)X1_n9-B%%bq?{|~D4WNbOQxVw! zFhR0Zt$$X>DwRrYuO?l+(CBWS0H_#a?gL1u>J-TzTU%QbjR5{YRP{B04^aXUq3`=| zlF8%|RhVPe@u-y;~?0mKy~CfZ0pX*VlK{_x;BJlFqrw zW&uEbl5{$KT|`dCXi@+U2SM;~X=&+mvjCv(i6e+~k~|ip2>?v*7jR(l8(2pVitl67jFFzT(}pC3)eb>y732yEz(Y{uP_XqV$=4u&F|#(-Q&Wf z#@M78nD6Rx?)QA|x#w^%(9y!e!tCPW;?sCcQr(4f?!7pU9e;pN0AOxz?isE1i%F9F z8iwKSqk<&>SZh}Ryg@|4UaYdVe~du0>IF|4MMJR*R!3`YW5w&M>(;l@Q`T zej<9sTKmrG>Z%;IVh5l~L^L)wW>Tq?mrA9)@$qp_Yk#eJjYM>PV`Jlk<>h5P3K-1% z5CFU$br118PxX11DwWEIv$M1QDB$}5ptY8s=Xt*G8?Ci5#%N=V5kkm5|GZM__R`W) zYABe99(30osHe5oQc9(ilE#?-^_7Tb8jZ&7TrM}R`Zs$N5>XPzaiX=>Ns@q>lQ@ov zh^TLl0Dq7;=YEq?-r3*ZuMY%=VOX}-{!y(~U&v%Kj)*u(68`7b%$*Ml02)N}W4&Jg zW^ZpV>gErt7yy25wOY?rDwV1+M#pj7E|<%-dcEH24EL@v=BLfg&31p{P;jwW{AGQ8 z{q@7cLurgr&1SQ8etv#WN_l5zXXkeSJSg{K0DnOcJkQJ=MbTC_wzajz>2$i}oV(U; zw|_9ke6hW~{q6Db@j)+Set!Pl>FMdiQmJ(DVlSR!p-{L5fR$2T_n+?jzG^m`=Yy(? znO+*3k`^|Q0H&kqg`Y8T*qK7SLy&0(z>BxX(#kz!^igxJmHavu%+ogPK`eEu_L xek>Be_r+rI%eA$&qK;VZf@>QmSum(ar~L8o)eMR<2XJuKR^F-mSwG3!Ca|S z41l))gd!3#^V`eI%kuzU7$&LeS!TYOB*`l?JMMHkCkll^9e{{PjhVl0x7#O}`OT5s z0uimpah#=T`hWX>f?KVYPt)|DVzKzFs@|{FYPX8T;!^-FjO!3UC641lnx?m>fq86@ zIiFUfsu!Je9|E9bfdSl|1|I0$BuOq!G&e3-tyVK4$^pO_L)Kch)>04zk2zG;3(mPu z2M1s#$2k#Y%#1J$If^2Vq9_Q%kgc_&?XNc)jnAEP(SIypsOnz;V66?JC<+GP;m9Mo zXPNoSm6er~vw;5?fXQ0RL+937HpcMivWUowolfV<>gwvLsbBzq4kv{|Aqc}T7y^gi z7&A+)R_n5J?#X{G`cW&)zW~U+_iBt`5z#!)iJ6I+LG(D6i2ADfJ%G!#TJ7FMaJ5>! znzp`nKo5r~Km4BS`MZ@S&?S35g9cZT&7!2=iHdhcIqHk&>SL-yWF zv)SzTdOZ=5ZDzjOZntmj?(TL*Yo~%srP9qtqw)U!{{HjE80z(Uxrp2rk*oE3{RaR# zsdn1tVRLh{PedR0`~7=|hlkeyoZH^sey3iq-+X!$y0EbD-smH7v;*aG`3(SSjJYx9 zA0dF=Bm>_2OCs_#GyisQaPY<6-d^hnoFvJ40OzN5FiEOQrZ zNs>=g^%Q^~*VfjqZ)|K#y&Y$kbMDo0x%|YVu?N*@G4+r{yZ!(G002ovPDHLkV1jAd Bh4TOa diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 621c088e3..f27e27467 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -81,6 +81,7 @@ private: intentBox = Gtk::manage(bt); intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); intentBox->setSelected(0); intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); intentBox->show(); @@ -135,9 +136,12 @@ private: std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC; - if (supportsPerceptual && supportsRelativeColorimetric) { + if (supportsPerceptual && (supportsRelativeColorimetric || supportsAbsoluteColorimetric)) { intentBox->set_sensitive (true); + intentBox->setItemSensitivity(0, supportsRelativeColorimetric); + intentBox->setItemSensitivity(2, supportsAbsoluteColorimetric); } else { bool wasBlocked = intentConn.block(true); @@ -148,7 +152,7 @@ private: softProof->set_sensitive(true); } - rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; + rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? (intentBox->getSelected() == 1 ? rtengine::RI_PERCEPTUAL : rtengine::RI_ABSOLUTE) : rtengine::RI_RELATIVE; if (!processor) { return; @@ -206,7 +210,7 @@ public: profileConn.block(wasBlocked); #endif wasBlocked = intentConn.block(true); - intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_RELATIVE ? 0 : options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 1 : 2); intentConn.block(wasBlocked); updateParameters(); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 04044fb2d..b5cb757f4 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -54,6 +54,7 @@ public: void setButtonHint(); void show (); void set_tooltip_text (const Glib::ustring &text); + void setItemSensitivity (int i, bool isSensitive); private: type_signal_changed message; @@ -69,7 +70,6 @@ private: bool hasMenu; void showMenu(GdkEventButton* event); - void setItemSensitivity (int i, bool isSensitive); protected: void entrySelected (int i); diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg index 497ce9c66..799deffc0 100644 --- a/tools/source_icons/scalable/intent-absolute.svg +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -28,8 +28,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.28397906" - inkscape:cx="443.36338" - inkscape:cy="-4.6332449" + inkscape:cx="497.94487" + inkscape:cy="-71.539587" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1294,6 +1294,24 @@ y1="1004.7048" x2="1694.8438" y2="1004.7048" /> + + + + + + @@ -1303,7 +1321,7 @@ image/svg+xml - + @@ -1329,50 +1347,56 @@ inkscape:groupmode="layer" id="layer1" transform="translate(464.16179,164.03236)" /> - - - - - - - - - + + + + + + + + diff --git a/tools/source_icons/scalable/intent-perceptual.svg b/tools/source_icons/scalable/intent-perceptual.svg index ab34b86b7..3c949c91e 100644 --- a/tools/source_icons/scalable/intent-perceptual.svg +++ b/tools/source_icons/scalable/intent-perceptual.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-relative.svg" + sodipodi:docname="intent-perceptual.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -28,8 +28,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.28397906" - inkscape:cx="443.36338" - inkscape:cy="-4.6332449" + inkscape:cx="-22.166458" + inkscape:cy="-89.632823" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1329,38 +1329,34 @@ inkscape:groupmode="layer" id="layer1" transform="translate(464.16179,164.03236)" /> - - - - - - - + + + + + diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg index 31a2fb342..1cd7135f2 100644 --- a/tools/source_icons/scalable/intent-relative.svg +++ b/tools/source_icons/scalable/intent-relative.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-perceptual.svg" + sodipodi:docname="intent-relative.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.28397906" - inkscape:cx="443.36338" - inkscape:cy="-4.6332449" + inkscape:zoom="0.20080352" + inkscape:cx="1490.3375" + inkscape:cy="469.77917" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1294,6 +1294,16 @@ y1="1004.7048" x2="1694.8438" y2="1004.7048" /> + + + @@ -1307,6 +1317,13 @@ + - diff --git a/tools/source_icons/scalable/intent-saturation.svg b/tools/source_icons/scalable/intent-saturation.svg index 638df39f2..1af08f4f2 100644 --- a/tools/source_icons/scalable/intent-saturation.svg +++ b/tools/source_icons/scalable/intent-saturation.svg @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.10040176" - inkscape:cx="2047.3204" - inkscape:cy="-1169.7659" + inkscape:zoom="0.28397906" + inkscape:cx="432.87769" + inkscape:cy="408.60409" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1303,7 +1303,7 @@ image/svg+xml - + @@ -1329,38 +1329,34 @@ inkscape:groupmode="layer" id="layer1" transform="translate(464.16179,164.03236)" /> - - - - - - - + + + + + diff --git a/tools/source_icons/scalable/softProof.svg b/tools/source_icons/scalable/softProof.svg index 7d142fc4c..d09f316a2 100644 --- a/tools/source_icons/scalable/softProof.svg +++ b/tools/source_icons/scalable/softProof.svg @@ -1337,7 +1337,7 @@ image/svg+xml - + @@ -1369,7 +1369,7 @@ d="m 95.191608,588.78944 0,-496.118075" style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#2a7fff;stroke-width:30;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4687)" /> Date: Tue, 29 Dec 2015 03:52:50 +0100 Subject: [PATCH 11/16] Updated icons (from Drslony), code cleanup and bugfix --- .../images/Dark/actions/intent-absolute.png | Bin 670 -> 710 bytes .../images/Dark/actions/intent-relative.png | Bin 1072 -> 1140 bytes .../images/Light/actions/intent-absolute.png | Bin 674 -> 700 bytes .../images/Light/actions/intent-relative.png | Bin 1057 -> 1101 bytes rtdata/languages/default | 1 + rtengine/iccstore.h | 4 +- rtengine/improccoordinator.cc | 4 +- rtengine/improccoordinator.h | 6 +- rtengine/improcfun.cc | 2 +- rtengine/improcfun.h | 8 +- rtengine/iplab2rgb.cc | 6 +- rtengine/procparams.h | 6 +- rtengine/rtengine.h | 4 +- rtengine/settings.h | 2 +- rtgui/editorpanel.cc | 37 +++++--- rtgui/icmpanel.cc | 14 ++- rtgui/icmpanel.h | 1 + rtgui/options.cc | 4 +- rtgui/options.h | 2 +- rtgui/preferences.cc | 29 ++++++- .../source_icons/scalable/intent-absolute.svg | 60 ++++--------- .../source_icons/scalable/intent-relative.svg | 80 ++++++------------ 22 files changed, 135 insertions(+), 135 deletions(-) diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png index 7732eba534d0ac33ee87d0275054fa27426bcb94..6d274a2c0aa81d1a0965843aa6040aacbe205a22 100644 GIT binary patch delta 611 zcmV-p0-XJx1;z!CZhu2bL_t(YiN%)9OH@%9#((d*7t@i^E>Zz z4(B}vP_0(`Tdh`y_x^WRSJ%%{snjAv89=2{c?b*wn3;edz<+1pQxrvWrBZ46*pOm`jr6Q4A15XgKGNbxrqD z2%(X+=e}wm{Jjvu#jMSpb4%rN`H9Qg_`j)ryCx)^&41k7>|2r~lQDp#E6%yASwlhy z-C29?D+8FCn!1xdBiWjptqu+9>+3xz_V*=**bD2jm|NquRA z{lE!H09+epHXA~C@4cTLA0MwBrkxldilV#T`$6X%l1Qgv!^~EISHPl~EjAjBrK3#7 x7{EFA*g5C7x3|OE+S*33Slld^%b9&9{sR8a444G8me>FQ002ovPDHLkV1l7wD!Bjv delta 571 zcmV-B0>u5s1)c?vZhsp|L_t(YiN%&rNK{c2hre_09rR6=vO(7Kut#dY0GuPU- zc-t23+P9ZBEm{T9+C>lufg53%KS)F_i=ZG97m)-iJj8TJeea$YIUtgblMni>F83UM z-@WG^I9C8#t=7f8y}bw^ilQBB?MA6o`bka_fJUS71Q%i!K?hj*3Eltz<)YQ~=&ydB%#b{+^#dbF1INs{4Yqi>-h}<;B z+yyQHo4~AdZoXVDr@h?daJd4oDk5Kiw@H$`kK;I7SXj7`rs;j)iims*Aw2WmFP#X| zY&P!z!w2^J_kT}4rmFoSk^uEA%jUfI?M9<P%uL_N z$Vi`au8?J!T5Gq<1i`LIeFGOS11$;JEc--3-~LjQ?5rMGS=7On=_S|4p6lidA*ATXN6lBHydk z>Z}7$)vLysYk5OL2xs#4JW>Ksuh(yj$Z)shUZtw5-uspVu+~;W2#4p%sb#JG1pI+S zQS^9yecj~^85$Z&0USWP-5xI%i-Vn@F{ZfRZ4;_`K}2>{^__^ks#Gegy}~-(b&mt{ zB!qyf?lc->mVmh=N!}bBWd8&)#yszQB%E`>TDu8soOJSa({JNC(wg5+2=oY$Zh!GfL_t(YiLF&lZ&YO%J?D96rh`zSv`k~=Gni7KgpUvxEYyLv z(_p%AgNeVvtqV7XojW)F0`)H_nR?sI#?Y0aLTjKX0zGb0B#nG#rkWBjE|3>kyHpFU1zjH2iafR6NikbGulk0jkUv)FrI2XKGWxFm6ObhLwH!8x}tgwPA1&&&=; zqNLc&rhfq3kaVkFug{K*jI3@I*QWrElFWq=@+5Zv$h7n&0Dc2-1HfcYPtWx6FHdxT0KnifcL)J%nAVB1ds=iA^BinVBo7Jkq7V?K*Kq=9zs|FFz>xzFtfScyLaC^ zd-iOjQmJI(IPR;}Y9B{Ybh=ut9s-b&1TzDGC4T@<0n{bMA%v%!#??d=MLWIs2LT*0 zvpxVPNaoY>eE?IEW+dHhZ*Q-iJ9lpFWpRB%@<2KjSxGx36-ee5DOS&m(p5%iN!c3`D zntxA8yS(?OqbNEBpf5?1!atagC9RPRTgC+dV`F380D8UmN6qXMfPEW#% zJLhf}i^V6c^-M}M44^xNup?cf4l^r+5DJpEr9?r}f|)5@)`VmQ!1os}T)6u(qs_S9 z2hdNlx!tR2RI?->NUDVpj*u*+fOOS%yhk!e z@;ZQT1_lOZUWNPxk#f2Gu5)frdQWtQ5Dt+%oSrn1G?B?0oN$S6lZp2^rh8lp2I}ZH8 P00000NkvXXu0mjf&{*-h delta 976 zcmV;>126pa2(So{Zhx&wL_t(YiH%iDPg_SAJ>NIiZ{Ws}qSR>6S%)Kv(?(-Q*8+n{BsUcvI1ZWo%Ov386~ebOAt+hLaLZNl-BIR=VCdsj3Ael@?thEXN&bdB-{kgfh*Of{oNpi{wa%MC5?vOV9KE$mMb!04SA8A4Q|lthIJrRWkraL?j+gPV(0v2)>c4x>#FV8|`#D z84-EtoSOnL2_QXydm{2L$u}hX#+YuX(Z7Qr_)Y+zQh%vDQPqhHYNSZMZA3&40c?@n zJU%|&Xf~TK78e)8`*6+#0IJpMV^zHy>Y^(mJ(7DQcdfPC3kwT>i3m%jQcP7Jsp>e% zj4>ufG8s!AOv^1JZr5;&pCslO{Cr8&Cz&!wagKsAkx*Y_;)6+@5 z0`Td%F@Hr80DO`oL(2^Sn*cVPbM<^a|LQ6wxU5JYK$qkmfL&|tw&!{EAPDvWpj0Z| zipS&Q&bbVLlyh!GRnH`F&i#|m=fA%eUBHRHk(?lzC7BhG+gC@O-1zryJOEg0V*q>+ z$p9Dy0Fpfb&qZXz^SpYy-QGzg5^r+3-0}M=d4Gez`y|6h*s5xqWRv7CBC-vj9*IPL z%jI&%#bVL;zJD(ki#@Q`j#aDGm~-xoeu>Ddd_Mo|+H@6*#i;N5AIru5OIkoS&cH1%TDn)p)1V`M?-+!&)0585@o_#_R)lEda2- zzMg0_8fMtR_kD&RrE!Xy3zx~FyFj9zxRFl z=AF*~k|Y^1vtpKIzslwE_u1Lm4n36Rko%G*@-<2N=A8RzW`7^TFq~glSXeqTB#z_B zAP9yf^#MbY&I1*o4-oLqd;e^5a`M&8%uIGDNV!}-8OQNfcblfCr-NFpHoCR7bp8A2e@zy{>?N^AG%{O{y*CJPHsy&+jDcXFMsuV{YeOrW!XjN+@)SavMf8* zYtMgbXLns^dxZ2_D`}cO4*{HWQ(XhHXEL)IunlRoTK6_LH-o)@ayaA8vr3d6h+l2iUz&+k#jBt`Xvps-NF&z zM4nko(o&qHx4>MQri%xuD9rD-Bu$tZl3;s+t^v!EUYJ=U2!cknT5TTs&zL01NTE>3 n+U>UA*w|=|kB_%|d6@VE!OsP-8KN>y00000NkvXXu0mjfQ>81f delta 575 zcmV-F0>J&e1)>FzZhs$1L_t(YiN%%AYZE~f$G`9Gl(q?4sGtzj65?j7CMBLdst3J# z@an;vc=aFf;=z+3{sn^2AoL!Df6rA<<{_`S@` z+nMj@%`7ud0KoISi`Lpj9I9`OY5Bh2MocoJ_K~U2!Lr-|st7aCdk2 zAnNDy`Q^c2a9u?1kX!|@PjVxjPQNXe%fqQ5p65L!Ss06lBm-6b0pMe?So~Znm257T zy9VGs09QnQI)9Gyyi%#urh=@kt=%ShAqtXQ5Rp}q9)Jase*kQ?+wILD2)dr<-5~jZ zWCFmedcFPz$NVpultdN6|gGM{;G- z;fTCP=Q3To;k^00tyKS!-W6o6TTWSd{%; z5&3sqBsc+JpsF>Jo2^#s!+0S(Dda^MhKm5;I8F#)Kb1XNM{#*G^jR}HmvZ2LN`Bdr6ph61H!-h1=D`SQE>ewP3cMbW!vRtSQilVw@g-FKSJW`h4o?1g+KX@Ba_+75s%lJ`iiy8B9& zWlODAtMghRwOZ{)5CoMx&x-(xBu@c22jDz_VF0H9KvLJtmI2I3`h9wOI=*%5R{lyM z!^6WTk|YU^G7Sw4Rn2USYol^?Lma0M|$cl1?5DC;1dWOme}@ z<`x$hn*cO1G4XbmWs#YUNUBPz0ys^wOws_f_HjwN7k>nSxqC-aSJF-xhMOd}NVXRj z7w-YUl`B_<%xt<=t9@){H@e;KS(1se2Hbs+WY{-J>H_$a;>cBzM}0^l@&0RSP%^*D~d4tvaVNe=;JBoj%yK@e5&Q+i@KK0{|l-BnlTGBYlN*@=w4<>c@XC(clxBy^kYO0#1X#`+G(lmez zhkreiR!Gj1Y@}(r(rUFH9b69qU~FvcBS}?vACzPy&ze~UKqX0%6Fsj>+9D|cl+-2p z3&|f=R#w)IYqXE+14&aPVP;R=eGkBy{;U#9(0fAi+e z^x)r6tJO+oHZExf!25Xq&&-?Iw@XV)@n)+Oe<37_qW2`7Cwa=<-vV$Mz$nSEhvhd( zKQ^1q#(yc^SN~Oi0${2)gSuw+x4Zu==?{0GTU%Ru{5r*72qF1Rp-^xDX`|8D2B0@7 bdRYGg*Dn1MGhyDO00000NkvXXu0mjfQ-b47 delta 961 zcmV;y13vuC2%!j&ZhxLhL_t(YiH%h~ZyQGteKUJJN|fYt3>XS6+EAc7(h?Q@fdEMx zAV{gkzaf7hP1+P`-KI^WBFG;Is4hU7fS@RnM=A^=MJ62C)+fo+-b@M|9r8p=oaTUi zJNstd?Yt!bC>Dz=s`?nI5RnVVaju5L;Z?WWJq4iYJ+p+9e1E?J@O2twW{3zfnGAv; z7!pwv!0*glcU||WTCHBrLP7vgC=?zoE-pTp0EjXo!T_ME*UWs{Xf)m|FE8gj&nt__ zCNl>j@`Q+%0Ay|*PE>2PTHlU3>7SgOMB^Jg&*N-1o3qw>BJxaCOFtm;-}eguJ_~}NNJM!NSp+aQMXpvDhCk4KRg_AlB_hgOYfH>r z2C$*3A0==^M8~T7R#mT!F~jj(5&1g|!=EUr>^o*&pMN6J0uo7+$}U7?pNRIDxwf^n z)!y0JiPL$vIs$+o2wpJr({Uh<<6%l-iU178^F*Z6>2zKa0IaR8eZ$OaQ_i0! zB2QHp$A8uiMP!eNYPnplUaeMN;~pn)?!c}ATmT4FwFjUhBK3oVgHr(TegE<0?!hahwI<5m6q%QnDNo zQBzfG0P3oGR45eQRw@R#w7FrDC_Yw@tNL zeP*o>2{}Rz}0QQOKkciHVF@xJQh=4>cX8tm5kVFJk1rc2UcqJmg zI)9E+&tx)twOXwQ0IRF3b8~ZZAIEY0P((7;+H8vC6u_I&don*94$U~q%-ZYqCLX17 zx%{Z#?{6^kr_8*ms!uUyJ9o;kA;YxhUCKTC`z{-ub_r$J*( jUqsHsFg%;}z-jRxH8sv)OjXS600000NkvXXu0mjfc<8`G diff --git a/rtdata/languages/default b/rtdata/languages/default index 4f0dae8f7..d83171de2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -657,6 +657,7 @@ HISTORY_MSG_423;Retinex - Gamma slope HISTORY_MSG_424;Retinex - HL threshold HISTORY_MSG_425;Retinex - Log base HISTORY_MSG_426;Retinex - Hue equalizer +HISTORY_MSG_427;Output rendering intent HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 6b41987f7..8b6e6465c 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -91,7 +91,7 @@ public: // Main monitors standard profile name, from OS void findDefaultMonitorProfile (); cmsHPROFILE getDefaultMonitorProfile () const; - Glib::ustring getDefaultMonitorProfileStr () const; + Glib::ustring getDefaultMonitorProfileName () const; cmsHPROFILE workingSpace (const Glib::ustring& name) const; cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; @@ -135,7 +135,7 @@ inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const return getProfile (defaultMonitorProfile); } -inline Glib::ustring ICCStore::getDefaultMonitorProfileStr () const +inline Glib::ustring ICCStore::getDefaultMonitorProfileName () const { return defaultMonitorProfile; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 62de26076..8d700a0cc 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1138,7 +1138,7 @@ void ImProcCoordinator::setSoftProofing (bool softProof) softProofing = softProof; } -void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingIntent intent) +void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, RenderingIntent intent) { if (profile != monitorProfile) { monitorProfile = profile; @@ -1150,7 +1150,7 @@ void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingInte } } -void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent) +void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent) { profile = monitorProfile; intent = monitorIntent; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 901804eba..31f9543b6 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -74,7 +74,7 @@ protected: Glib::ustring monitorProfile; - eRenderingIntent monitorIntent; + RenderingIntent monitorIntent; int scale; bool highDetailPreprocessComputed; @@ -256,8 +256,8 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); - void setMonitorProfile (Glib::ustring profile, eRenderingIntent intent); - void getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent); + void setMonitorProfile (Glib::ustring profile, RenderingIntent intent); + void getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent); void setSoftProofing (bool softProof); bool updateTryLock () diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 18b5eed6d..18ffc0e8d 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -188,7 +188,7 @@ void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) */ -void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing) +void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing) { // set up monitor transform if (monitorTransform != NULL) { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c34219c0d..af49cb937 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,7 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); - void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing); + void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -380,9 +380,9 @@ public: void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); - Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma); - Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw);//without gamma ==>default + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma); + Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw);//without gamma ==>default // CieImage *ciec; bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index a727423ef..a53bdb8e1 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -134,7 +134,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softPro } } -Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma) +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma) { //gamutmap(lab); @@ -259,7 +259,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, return image; } // for default (not gamma) -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw) { //gamutmap(lab); @@ -363,7 +363,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int // for gamma options (BT709...sRGB linear...) -Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) +Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { //gamutmap(lab); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index cbbbed7a5..1103d274d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -42,13 +42,13 @@ class WavOpacityCurveW; class WavOpacityCurveWL; class RetinextransmissionCurve; -typedef enum RenderingIntent { +enum RenderingIntent { RI_PERCEPTUAL = INTENT_PERCEPTUAL, RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC, RI_SATURATION = INTENT_SATURATION, RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC, RI__COUNT -} eRenderingIntent; +}; namespace procparams { @@ -950,7 +950,7 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; - eRenderingIntent outputIntent; + RenderingIntent outputIntent; static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index d10acb561..0c6999158 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -416,8 +416,8 @@ public: virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; - virtual void setMonitorProfile (Glib::ustring monitorProfile, eRenderingIntent intent) = 0; - virtual void getMonitorProfile (Glib::ustring &monitorProfile, eRenderingIntent &intent) = 0; + virtual void setMonitorProfile (Glib::ustring monitorProfile, RenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring &monitorProfile, RenderingIntent &intent) = 0; virtual void setSoftProofing (bool softProof) = 0; virtual ~StagedImageProcessor () {} diff --git a/rtengine/settings.h b/rtengine/settings.h index 98c85ba6f..3e9c9d38a 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -39,7 +39,7 @@ public: int leveldnautsimpl; // STD or EXPERT Glib::ustring monitorProfile; ///< ICC profile name used for the monitor - eRenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile + RenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index f27e27467..518b5ad8d 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -62,7 +62,7 @@ private: profileBox->append_text (M("PREFERENCES_PROFILE_NONE")); #if defined(WIN32) - profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileStr() + ")"); + profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileName() + ")"); profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); #else profileBox->set_active (0); @@ -77,8 +77,7 @@ private: void prepareIntentBox () { - PopUpButton *bt = new PopUpButton(Glib::ustring(), true); - intentBox = Gtk::manage(bt); + intentBox = Gtk::manage(new PopUpButton(Glib::ustring(), true)); intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); intentBox->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); @@ -90,6 +89,7 @@ private: void softProofToggled () { if (processor) { + processor->beginUpdateParams (); processor->setSoftProofing( softProof->get_active() ); processor->endUpdateParams ( rtengine::EvMonitorTransform ); } @@ -106,7 +106,7 @@ private: profileBox->set_tooltip_text(profileBox->get_active_text ()); #ifdef WIN32 if (profileBox->get_active_row_number () == 1) { - profile = rtengine::iccStore->getDefaultMonitorProfileStr (); + profile = rtengine::iccStore->getDefaultMonitorProfileName (); if (profile.empty()) { profile = options.rtSettings.monitorProfile; } @@ -152,7 +152,15 @@ private: softProof->set_sensitive(true); } - rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? (intentBox->getSelected() == 1 ? rtengine::RI_PERCEPTUAL : rtengine::RI_ABSOLUTE) : rtengine::RI_RELATIVE; + rtengine::RenderingIntent intent = rtengine::RI_PERCEPTUAL; + switch (intentBox->getSelected()) { + case (0): + intent = rtengine::RI_RELATIVE; + break; + case (2): + intent = rtengine::RI_ABSOLUTE; + break; + } if (!processor) { return; @@ -165,10 +173,20 @@ private: // ...or store them locally processor->beginUpdateParams (); if (options.rtSettings.verbose) { - printf("Monitor profile: %s, Intent: %s)\n", - profile.empty() ? "None" : profile.c_str(), - intent > 0 ? M("PREFERENCES_INTENT_PERCEPTUAL").c_str() : M("PREFERENCES_INTENT_RELATIVE").c_str() - ); + Glib::ustring intentName; + switch (intent) { + case (0): + intentName = M("PREFERENCES_INTENT_RELATIVE"); + break; + case (1): + intentName = M("PREFERENCES_INTENT_PERCEPTUAL"); + break; + case (2): + default: // to avoid complains from gcc + intentName = M("PREFERENCES_INTENT_ABSOLUTE"); + break; + } + printf("Monitor profile: %s, Intent: %s)\n", profile.empty() ? "None" : profile.c_str(), intentName.c_str()); } processor->setMonitorProfile(profile, intent); processor->endUpdateParams (rtengine::EvMonitorTransform); @@ -185,7 +203,6 @@ public: reset (); } - // HOMBRE: renamed to 'pack_end_in', because 'pack_end' already widely used by Gtk::Widget in a different way void pack_end_in (Gtk::Box* box) { box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 8b2965cab..d24ec9312 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -292,7 +292,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); - ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::oiChanged) ); wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); @@ -623,7 +623,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) int ointentVal = ointent->get_active_row_number(); if (ointentVal >= 0 && ointentVal < RI__COUNT) { - pp->icm.outputIntent = static_cast(ointentVal); + pp->icm.outputIntent = static_cast(ointentVal); } else { pp->icm.outputIntent = rtengine::RI_PERCEPTUAL; } @@ -900,7 +900,15 @@ void ICMPanel::opChanged () { if (listener) { - listener->panelChanged (EvOProfile, Glib::ustring(onames->get_active_text())+Glib::ustring("\n")+ointent->get_active_text()); + listener->panelChanged (EvOProfile, onames->get_active_text()); + } +} + +void ICMPanel::oiChanged () +{ + + if (listener) { + listener->panelChanged (EvOIntent, ointent->get_active_text()); } } diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index e10f42b20..863e88a46 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -108,6 +108,7 @@ public: void wpChanged (); void opChanged (); + void oiChanged (); void ipChanged (); void gpChanged (); void GamChanged (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 1ffc74e2b..c2e31ec38 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -1462,7 +1462,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); + rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -1714,7 +1714,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Fast Export", "fastexport_icm_output_intent" )) { - fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" )); + fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" )); } if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) { diff --git a/rtgui/options.h b/rtgui/options.h index 969b66642..b896f4129 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -264,7 +264,7 @@ public: Glib::ustring fastexport_icm_input; Glib::ustring fastexport_icm_working; Glib::ustring fastexport_icm_output; - rtengine::eRenderingIntent fastexport_icm_outputIntent; + rtengine::RenderingIntent fastexport_icm_outputIntent; Glib::ustring fastexport_icm_gamma; bool fastexport_resize_enabled; double fastexport_resize_scale; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4551b6bad..68f8206e1 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -705,7 +705,8 @@ Gtk::Widget* Preferences::getColorManagementPanel () monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE")); monIntent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - monIntent->set_active (0); + monIntent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + monIntent->set_active (1); iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged)); @@ -1446,7 +1447,18 @@ void Preferences::storePreferences () #if !defined(__APPLE__) // monitor profile not supported on apple moptions.rtSettings.monitorProfile = monProfile->get_active_text (); - moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; + switch (monIntent->get_active_row_number ()) { + case (0): + moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE; + break; + case (2): + moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; + break; + case (1): + default: + moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; + break; + } #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif @@ -1565,7 +1577,18 @@ void Preferences::fillPreferences () #if !defined(__APPLE__) // monitor profile not supported on apple setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); - monIntent->set_active (moptions.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); + switch (moptions.rtSettings.monitorIntent) { + case(0) : + monIntent->set_active (0); + break; + case(2) : + monIntent->set_active (2); + break; + case(1) : + default: + monIntent->set_active (1); + break; + } #if defined(WIN32) cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); #endif diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg index 799deffc0..b5092b0c5 100644 --- a/tools/source_icons/scalable/intent-absolute.svg +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-absolute.svg" + sodipodi:docname="intent-absolute-3.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.28397906" - inkscape:cx="497.94487" - inkscape:cy="-71.539587" + inkscape:zoom="0.5" + inkscape:cx="400" + inkscape:cy="350" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -47,7 +47,13 @@ inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" - inkscape:snap-global="false" /> + inkscape:snap-global="true" + inkscape:object-paths="false" + inkscape:snap-intersection-paths="false" + inkscape:object-nodes="true" + inkscape:snap-smooth-nodes="false" + inkscape:snap-midpoints="false" + inkscape:snap-nodes="true" /> - + id="path5187" + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#2a7fff;stroke-width:50;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 39.8267,50 c 372.08564,0 376.87989,202 720.3466,202 M 39.8267,150 c 372.08564,0 376.87989,102 720.3466,102 m -720.346599,0 720.346599,0" /> - - - + id="path5189" + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#2a7fff;stroke-width:50;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 39.826704,649.33407 C 408.29238,649.33407 404.24771,550 760.1733,550 m -720.346599,0 720.346599,0" /> diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg index 1cd7135f2..706de23d1 100644 --- a/tools/source_icons/scalable/intent-relative.svg +++ b/tools/source_icons/scalable/intent-relative.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-relative.svg" + sodipodi:docname="intent-relative-3.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.20080352" - inkscape:cx="1490.3375" - inkscape:cy="469.77917" + inkscape:zoom="0.40160704" + inkscape:cx="315.89751" + inkscape:cy="196.7604" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -47,7 +47,14 @@ inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" - inkscape:snap-global="false" /> + inkscape:snap-global="true" + inkscape:object-paths="false" + inkscape:snap-intersection-paths="false" + inkscape:object-nodes="true" + inkscape:snap-smooth-nodes="false" + inkscape:snap-midpoints="false" + inkscape:snap-nodes="true" + inkscape:snap-page="false" /> + id="clipPath7774"> + + + + d="m -48.208488,-24.69248 0,219.02655 896.416978,0 0,-219.02655 -896.416978,0 z" + id="path7780" + inkscape:connector-curvature="0" /> image/svg+xml - + - - - - - - + d="m 39.826704,649.33407 c 368.465676,0 364.421006,-201.42391 720.346596,-201.42391 M 39.8267,50 c 372.08564,0 376.87989,99.91016 720.3466,99.91016 M 39.8267,150 c 372.08564,0 376.87989,-0.0898 720.3466,-0.0898 M 39.826701,550 C 403.19705,550 404.27294,447.91016 760.1733,447.91016 M 39.826701,450 C 405.68704,450 405.51794,347.91016 760.1733,347.91016 M 39.826701,252 C 411.99422,252 414.41617,149.91016 760.1733,149.91016 M 39.826701,350 C 410.66703,350 410.49793,247.91016 760.1733,247.91016" /> From 5fd5d5bece84b0930a8aa96e6b83ce4b5194a2b2 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Fri, 1 Jan 2016 19:43:09 +0100 Subject: [PATCH 12/16] Remove the soft proof button and internal flag as it was decided not to mix this with the output profile handling. --- rtengine/dcrop.cc | 38 +----- rtengine/dcrop.h | 5 - rtengine/improccoordinator.cc | 12 +- rtengine/improccoordinator.h | 2 - rtengine/improcfun.cc | 52 +------- rtengine/improcfun.h | 4 +- rtengine/iplab2rgb.cc | 4 +- rtengine/procevents.h | 3 +- rtengine/refreshmap.cc | 1 - rtengine/rtengine.h | 1 - rtgui/editorpanel.cc | 218 +++++++++++++++------------------- rtgui/editorpanel.h | 3 +- rtgui/guiutils.h | 16 +++ rtgui/popupcommon.cc | 1 - 14 files changed, 121 insertions(+), 239 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index cd68aa0a6..2220f68c5 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -33,7 +33,7 @@ extern const Settings* settings; Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) : EditBuffer(editDataProvider), origCrop(NULL), laboCrop(NULL), labnCrop(NULL), cropImg(NULL), cbuf_real(NULL), cshmap(NULL), transCrop(NULL), cieCrop(NULL), cbuffer(NULL), - softProofing(false), updating(false), newUpdatePending(false), skip(10), + updating(false), newUpdatePending(false), skip(10), cropx(0), cropy(0), cropw(-1), croph(-1), trafx(0), trafy(0), trafw(-1), trafh(-1), rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1), @@ -987,42 +987,8 @@ void Crop::update (int todo) EditBuffer::setReady(); // switch back to rgb - parent->ipf.lab2monitorRgb (labnCrop, cropImg, softProofing); + parent->ipf.lab2monitorRgb (labnCrop, cropImg); - //parent->ipf.lab2monitorRgb (laboCrop, cropImg); - - //cropImg = baseCrop->to8(); - /* - // int xref,yref; - xref=000;yref=000; - if (colortest && cropw>115 && croph>115) - for(int j=1;j<5;j++){ - xref+=j*30;yref+=j*30; - int rlin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))]/255.0) * 255.0); - int glin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1]/255.0) * 255.0); - int blin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2]/255.0) * 255.0); - - printf("after lab2rgb RGB lab2 Xr%i Yr%i Skip=%d R=%d G=%d B=%d \n",xref,yref,skip, - rlin,glin,blin); - //cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))], - //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1)], - //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2)]); - //printf("after lab2rgb Lab lab2 Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327); - printf("after lab2rgb Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, - labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327, - labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, - labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327)q; - } - */ - /* - if (colortest && cropImg->height>115 && cropImg->width>115) {//for testing - xref=000;yref=000; - printf("dcrop final R= %d G= %d B= %d \n", - cropImg->data[3*xref/(skip)*(cropImg->width+1)], - cropImg->data[3*xref/(skip)*(cropImg->width+1)+1], - cropImg->data[3*xref/(skip)*(cropImg->width+1)+2]); - } - */ if (cropImageListener) { // this in output space held in parallel to allow analysis like shadow/highlight Glib::ustring outProfile = params.icm.output; diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index ea9b1bc00..57f388a51 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -54,7 +54,6 @@ protected: // ----------------------------------------------------------------- float** cbuffer; - bool softProofing; /// True if the Crop has to display a soft proof of the output with its profile bool updating; /// Flag telling if an updater thread is currently processing bool newUpdatePending; /// Flag telling the updater thread that a new update is pending int skip; @@ -104,10 +103,6 @@ public: /** @brief Asynchronously reprocess the detailed crop */ void fullUpdate (); // called via thread - void setSoftProofing(bool doSoftProof) { - softProofing = doSoftProof; - } - void setListener (DetailedCropListener* il); void destroy (); int get_skip () diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8d700a0cc..63ca9c5d0 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -33,7 +33,7 @@ ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true), - softProofing(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), + bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), hltonecurve(65536), shtonecurve(65536), @@ -783,14 +783,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) // Update the output color transform if necessary if (isColorProfileDirty || (todo & M_MONITOR)) { - ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProofing); + ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent); isColorProfileDirty = false; } // process crop, if needed for (size_t i = 0; i < crops.size(); i++) if (crops[i]->hasListener () && cropCall != crops[i] ) { - crops[i]->setSoftProofing(softProofing); crops[i]->update (todo); // may call ourselves } @@ -805,7 +804,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) MyMutex::MyLock prevImgLock(previmg->getMutex()); try { - ipf.lab2monitorRgb (nprevl, previmg, softProofing); + ipf.lab2monitorRgb (nprevl, previmg); delete workimg; Glib::ustring outProfile = params.icm.output; @@ -1133,11 +1132,6 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } -void ImProcCoordinator::setSoftProofing (bool softProof) -{ - softProofing = softProof; -} - void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, RenderingIntent intent) { if (profile != monitorProfile) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 31f9543b6..78d3dca7f 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -82,7 +82,6 @@ protected: bool allocated; bool isColorProfileDirty; - bool softProofing; void freeAll (); @@ -258,7 +257,6 @@ public: void setMonitorProfile (Glib::ustring profile, RenderingIntent intent); void getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent); - void setSoftProofing (bool softProof); bool updateTryLock () { diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 18ffc0e8d..b1f47c3a9 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -140,55 +140,8 @@ void ImProcFunctions::firstAnalysisThread (Imagefloat* original, Glib::ustring w } } } -/* -void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) -{ - const double toxyz[3][3] = {{0.7976749, 0.1351917, 0.0313534}, - {0.2880402, 0.7118741, 0.0000857}, - {0.0000000, 0.0000000, 0.8252100}}; - const double xyzto[3][3] = {{1.3459433, -0.2556075, -0.0511118}, - {-0.5445989, 1.5081673, 0.0205351}, - {0.0000000, 0.0000000, 1.2118128}}; - int fw = baseImg->width; - int fh = baseImg->height; - - double CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22; - double Xxx,Yyy,Zzz; - // Xxx=1.09844; - // Yyy=1.0; - // Zzz=0.355961; - //params.wb.temperature, params.wb.green, params.wb.method - double Xxyz, Zxyz; -// ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xxyz, Zxyz); - ColorTemp::temp2mulxyz (5000.0, 1.0, "Camera", Xxyz, Zxyz); - - ColorTemp::cieCAT02(Xxx, Yyy, Zzz, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22); - printf("00=%f 01=%f 11=%f 20=%f 22=%f\n", CAM02BB00,CAM02BB01,CAM02BB11,CAM02BB20,CAM02BB22); - - - for (int i=0; ir(i,j); - float g = baseImg->g(i,j); - float b = baseImg->b(i,j); - - float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; - float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; - float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; - float Xcam=CAM02BB00* x +CAM02BB01* y + CAM02BB02* z ; - float Ycam=CAM02BB10* x +CAM02BB11* y + CAM02BB12* z ; - float Zcam=CAM02BB20* x +CAM02BB21* y + CAM02BB22* z ; - baseImg->r(i,j) = xyzto[0][0] * Xcam + xyzto[0][1] * Ycam + xyzto[0][2] * Zcam; - baseImg->g(i,j) = xyzto[1][0] * Xcam + xyzto[1][1] * Ycam + xyzto[1][2] * Zcam; - baseImg->b(i,j) = xyzto[2][0] * Xcam + xyzto[2][1] * Ycam + xyzto[2][2] * Zcam; - } - } -} -*/ - - -void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing) +void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent) { // set up monitor transform if (monitorTransform != NULL) { @@ -224,9 +177,6 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Gli cmsHPROFILE jprof = iccStore->getProfile(outputProfile); if (jprof) { - //TODO: Create a dedicated softproof transformation (line below to be finished) - //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING ); - lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index af49cb937..ec81f26eb 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,7 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); - void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing); + void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -266,7 +266,7 @@ public: void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage); float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh); - void lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing=false); + void lab2monitorRgb (LabImage* lab, Image8* image); void resize (Image16* src, Image16* dst, float dScale); void Lanczos (const LabImage* src, LabImage* dst, float scale); void Lanczos (const Image16* src, Image16* dst, float scale); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index a53bdb8e1..c36e185d0 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -39,7 +39,7 @@ const double (*iwprof[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, const char* wprofnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; const int numprof = 7; -void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing) +void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) { //gamutmap(lab); @@ -78,7 +78,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softPro buffer[iy++] = rb[j] / 327.68f; } - if (softProofing && !settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { + if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { AlignedBuffer buf(3 * W); cmsDoTransform (lab2outputTransform, buffer, buf.data, W); cmsDoTransform (output2monitorTransform, buf.data, data + ix, W); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 4609c674a..21ecf5a83 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -455,8 +455,7 @@ enum ProcEvent { // EvLgrbl = 425, EvRetinexlhcurve = 425, EvOIntent = 426, - EvSoftProof = 427, - EvMonitorTransform = 428, + EvMonitorTransform = 427, NUMOFEVENTS }; } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 37d0f52b4..f31300a64 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -455,7 +455,6 @@ int refreshmap[rtengine::NUMOFEVENTS] = { // DEMOSAIC, // EvLgrbl DEMOSAIC, // EvRetinexlhcurve ALLNORAW, // EvOIntent - ALLNORAW, // EvSoftProof MONITORTRANSFORM // EvMonitorTransform }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 0c6999158..d20b89c33 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -418,7 +418,6 @@ public: virtual void setMonitorProfile (Glib::ustring monitorProfile, RenderingIntent intent) = 0; virtual void getMonitorProfile (Glib::ustring &monitorProfile, RenderingIntent &intent) = 0; - virtual void setSoftProofing (bool softProof) = 0; virtual ~StagedImageProcessor () {} diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 518b5ad8d..b9f123ac5 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -33,131 +33,113 @@ using namespace rtengine::procparams; -class MonitorProfileSelector +class EditorPanel::MonitorProfileSelector { private: - Gtk::ToggleButton* softProof; - MyComboBoxText* profileBox; - PopUpButton* intentBox; - sigc::connection profileConn, intentConn, softProofConn; + MyComboBoxText profileBox; + PopUpButton intentBox; + sigc::connection profileConn, intentConn; - rtengine::StagedImageProcessor* processor; + rtengine::StagedImageProcessor* const& processor; private: - void prepareSoftProofButton () - { - Gtk::Image *softProofImg = Gtk::manage (new RTImage("softProof.png")); - softProofImg->set_padding(0, 0); - softProof = Gtk::manage(new Gtk::ToggleButton()); - softProof->add(*softProofImg); - softProof->set_relief(Gtk::RELIEF_NONE); - softProof->set_tooltip_text(M("MONITOR_SOFTPROOF")); - softProofConn = softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); - } - void prepareProfileBox () { - profileBox = Gtk::manage(new MyComboBoxText()); - profileBox->set_size_request(100,-1); + profileBox.set_size_request (100, -1); - profileBox->append_text (M("PREFERENCES_PROFILE_NONE")); - #if defined(WIN32) - profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileName() + ")"); - profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); - #else - profileBox->set_active (0); - #endif + profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); +#ifdef WIN32 + profileBox.append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileName() + ")"); + profileBox.set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); +#else + profileBox.set_active (0); +#endif const std::vector profiles = rtengine::iccStore->getProfiles (); for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) { - profileBox->append_text (*iterator); + profileBox.append_text (*iterator); } - profileConn = profileBox->signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } void prepareIntentBox () { - intentBox = Gtk::manage(new PopUpButton(Glib::ustring(), true)); - intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); - intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); - intentBox->setSelected(0); - intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); - intentBox->show(); + intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + intentBox.addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox.addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); + + intentBox.setSelected(0); + intentBox.show (); } - void softProofToggled () + void profileBoxChanged () { - if (processor) { - processor->beginUpdateParams (); - processor->setSoftProofing( softProof->get_active() ); - processor->endUpdateParams ( rtengine::EvMonitorTransform ); - } + updateParameters (); + + profileBox.set_tooltip_text (profileBox.get_active_text ()); } - void updateIntent (int i) + void intentBoxChanged (int) { - updateParameters(); + updateParameters (); } void updateParameters () { + ConnectionBlocker profileBlocker (profileConn); + ConnectionBlocker intentBlocker (intentConn); + Glib::ustring profile; - profileBox->set_tooltip_text(profileBox->get_active_text ()); + #ifdef WIN32 - if (profileBox->get_active_row_number () == 1) { + if (profileBox.get_active_row_number () == 1) { profile = rtengine::iccStore->getDefaultMonitorProfileName (); - if (profile.empty()) { + if (profile.empty ()) { profile = options.rtSettings.monitorProfile; } - if (profile.empty()) { - profile = "sRGB IEC61966-2.1"; // assuming this profile always exist on Windows + if (profile.empty ()) { + profile = "sRGB IEC61966-2.1"; } - } else if (profileBox->get_active_row_number () > 1) { - profile = profileBox->get_active_text (); + } else if (profileBox.get_active_row_number () > 1) { + profile = profileBox.get_active_text (); } #else - profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring(); + profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring (); #endif - // MonitorProfile = None , disabling everything - if (profileBox->get_active_row_number () == 0) { + if (profileBox.get_active_row_number () == 0) { + profile.clear(); - bool wasBlocked = intentConn.block(true); - intentBox->setSelected(1); - intentBox->set_sensitive (false); - intentConn.block(wasBlocked); - softProof->set_active(false); - softProof->set_sensitive(false); - wasBlocked = softProofConn.block(true); - softProofConn.block(wasBlocked); + + intentBox.set_sensitive (false); + intentBox.setSelected (0); } else { - std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); - const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC; - if (supportsPerceptual && (supportsRelativeColorimetric || supportsAbsoluteColorimetric)) { - intentBox->set_sensitive (true); - intentBox->setItemSensitivity(0, supportsRelativeColorimetric); - intentBox->setItemSensitivity(2, supportsAbsoluteColorimetric); + if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) { + intentBox.set_sensitive (true); + intentBox.setItemSensitivity(0, supportsRelativeColorimetric); + intentBox.setItemSensitivity(1, supportsPerceptual); + intentBox.setItemSensitivity(2, supportsAbsoluteColorimetric); + } else { + intentBox.set_sensitive (false); + intentBox.setSelected (0); } - else { - bool wasBlocked = intentConn.block(true); - intentBox->setSelected(supportsPerceptual ? 0 : 1); - intentBox->set_sensitive (false); - intentConn.block(wasBlocked); - } - softProof->set_sensitive(true); } - rtengine::RenderingIntent intent = rtengine::RI_PERCEPTUAL; - switch (intentBox->getSelected()) { - case (0): + rtengine::RenderingIntent intent; + switch (intentBox.getSelected ()) { + default: + case 0: intent = rtengine::RI_RELATIVE; break; - case (2): + case 1: + intent = rtengine::RI_PERCEPTUAL; + break; + case 2: intent = rtengine::RI_ABSOLUTE; break; } @@ -166,81 +148,67 @@ private: return; } - // either store them in the options file for the default value when opening the next EditorPanel - //options.rtSettings.monitorProfile = profile; - //options.rtSettings.monitorIntent = intent; - - // ...or store them locally processor->beginUpdateParams (); - if (options.rtSettings.verbose) { - Glib::ustring intentName; - switch (intent) { - case (0): - intentName = M("PREFERENCES_INTENT_RELATIVE"); - break; - case (1): - intentName = M("PREFERENCES_INTENT_PERCEPTUAL"); - break; - case (2): - default: // to avoid complains from gcc - intentName = M("PREFERENCES_INTENT_ABSOLUTE"); - break; - } - printf("Monitor profile: %s, Intent: %s)\n", profile.empty() ? "None" : profile.c_str(), intentName.c_str()); - } - processor->setMonitorProfile(profile, intent); + processor->setMonitorProfile (profile, intent); processor->endUpdateParams (rtengine::EvMonitorTransform); } public: - MonitorProfileSelector () : - processor (NULL) + MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : + intentBox (Glib::ustring (), true), + processor (ipc) { - prepareSoftProofButton (); prepareProfileBox (); prepareIntentBox (); reset (); + + profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::profileBoxChanged)); + intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::intentBoxChanged)); } void pack_end_in (Gtk::Box* box) { - box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); - box->pack_end (*intentBox->buttonGroup, Gtk::PACK_SHRINK, 0); - box->pack_end (*profileBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*intentBox.buttonGroup, Gtk::PACK_SHRINK, 0); + box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); } void reset () { - bool wasBlocked; + ConnectionBlocker profileBlocker (profileConn); + ConnectionBlocker intentBlocker (intentConn); + #ifdef WIN32 - wasBlocked = profileConn.block(true); if (options.rtSettings.autoMonitorProfile) { - setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 1); + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 1); } else { - setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); } - profileConn.block(wasBlocked); #else - wasBlocked = profileConn.block(true); - setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); - profileConn.block(wasBlocked); + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); #endif - wasBlocked = intentConn.block(true); - intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_RELATIVE ? 0 : options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 1 : 2); - intentConn.block(wasBlocked); - updateParameters(); - } + switch (options.rtSettings.monitorIntent) + { + default: + case rtengine::RI_RELATIVE: + intentBox.setSelected (0); + break; + case rtengine::RI_PERCEPTUAL: + intentBox.setSelected (1); + break; + case rtengine::RI_ABSOLUTE: + intentBox.setSelected (2); + break; + } - void setImageProcessor (rtengine::StagedImageProcessor* imageProc) { - processor = imageProc; + updateParameters (); } }; EditorPanel::EditorPanel (FilePanel* filePanel) - : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), monitorProfile(new MonitorProfileSelector ()), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) + : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { epih = new EditorPanelIdleHelper; @@ -471,8 +439,10 @@ EditorPanel::EditorPanel (FilePanel* filePanel) iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); } - // Monitor profile buttons iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); + + // Monitor profile buttons + monitorProfile.reset (new MonitorProfileSelector (ipc)); monitorProfile->pack_end_in (iops); editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); @@ -732,7 +702,6 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) this->isrc = isrc; ipc = rtengine::StagedImageProcessor::create (isrc); - monitorProfile->setImageProcessor(ipc); ipc->setProgressListener (this); ipc->setPreviewImageListener (previewHandler); ipc->setPreviewScale (10); // Important @@ -783,7 +752,6 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) history->resetSnapShotNumber(); - //HOMBRE: not sure if we want to reset on opening a new image monitorProfile->reset (); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index ffb8a93a4..6de9928bd 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -42,8 +42,6 @@ struct EditorPanelIdleHelper { int pending; }; -class MonitorProfileSelector; - class RTWindow; class EditorPanel : public Gtk::VBox, public PParamsChangeListener, @@ -86,6 +84,7 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; + class MonitorProfileSelector; std::auto_ptr monitorProfile; ImageAreaPanel* iareapanel; diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 80729b96b..79f050c2f 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -76,6 +76,22 @@ public: } }; +class ConnectionBlocker +{ +public: + ConnectionBlocker (sigc::connection& connection) : connection (connection) + { + wasBlocked = connection.block(); + } + ~ConnectionBlocker () + { + connection.block(wasBlocked); + } +private: + sigc::connection& connection; + bool wasBlocked; +}; + /** * @brief Glue box to control visibility of the MyExpender's content ; also handle the frame around it */ diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 8acbd2802..f7e667219 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -55,7 +55,6 @@ PopUpCommon::~PopUpCommon () delete menu; delete buttonImage; - delete buttonGroup; } bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) From cefb22122000654ed3b2521c1efb71ba6a0395b9 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Fri, 1 Jan 2016 20:10:48 +0100 Subject: [PATCH 13/16] Remove the redundant isColorProfile dirty flag, but keep updating the monitor profile using processing parameter change events. --- rtengine/improccoordinator.cc | 21 +++++++-------------- rtengine/improccoordinator.h | 6 ++---- rtengine/rtengine.h | 4 ++-- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 63ca9c5d0..6ff60506b 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -32,7 +32,7 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), - highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true), + highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), hltonecurve(65536), @@ -781,10 +781,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } - // Update the output color transform if necessary - if (isColorProfileDirty || (todo & M_MONITOR)) { + // Update the monitor color transform if necessary + if (todo & M_MONITOR) { ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent); - isColorProfileDirty = false; } // process crop, if needed @@ -1132,19 +1131,13 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } -void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, RenderingIntent intent) +void ImProcCoordinator::setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent) { - if (profile != monitorProfile) { - monitorProfile = profile; - isColorProfileDirty = true; - } - if (intent != monitorIntent) { - monitorIntent = intent; - isColorProfileDirty = true; - } + monitorProfile = profile; + monitorIntent = intent; } -void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent) +void ImProcCoordinator::getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const { profile = monitorProfile; intent = monitorIntent; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 78d3dca7f..4d442482e 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -81,8 +81,6 @@ protected: bool highDetailRawComputed; bool allocated; - bool isColorProfileDirty; - void freeAll (); // Precomputed values used by DetailedCrop ---------------------------------------------- @@ -255,8 +253,8 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); - void setMonitorProfile (Glib::ustring profile, RenderingIntent intent); - void getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent); + void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent); + void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const; bool updateTryLock () { diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index d20b89c33..42e06406e 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -416,8 +416,8 @@ public: virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; - virtual void setMonitorProfile (Glib::ustring monitorProfile, RenderingIntent intent) = 0; - virtual void getMonitorProfile (Glib::ustring &monitorProfile, RenderingIntent &intent) = 0; + virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0; virtual ~StagedImageProcessor () {} From 61f639192f32066bd6fc4498232a95a8c29ecb91 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Fri, 1 Jan 2016 20:24:10 +0100 Subject: [PATCH 14/16] Make use of the rendering intent enum in the preferences implementation as well. --- rtgui/preferences.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 68f8206e1..0033978c3 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1448,16 +1448,16 @@ void Preferences::storePreferences () #if !defined(__APPLE__) // monitor profile not supported on apple moptions.rtSettings.monitorProfile = monProfile->get_active_text (); switch (monIntent->get_active_row_number ()) { - case (0): + default: + case 0: moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE; break; - case (2): - moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; - break; - case (1): - default: + case 1: moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; break; + case 2: + moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; + break; } #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); @@ -1578,16 +1578,16 @@ void Preferences::fillPreferences () #if !defined(__APPLE__) // monitor profile not supported on apple setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); switch (moptions.rtSettings.monitorIntent) { - case(0) : + default: + case rtengine::RI_RELATIVE: monIntent->set_active (0); break; - case(2) : - monIntent->set_active (2); - break; - case(1) : - default: + case rtengine::RI_PERCEPTUAL: monIntent->set_active (1); break; + case rtengine::RI_ABSOLUTE: + monIntent->set_active (2); + break; } #if defined(WIN32) cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); From 15813b9fb045e8314e5a80615866754ffc1e889f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 2 Jan 2016 12:22:32 +0100 Subject: [PATCH 15/16] Fix the missing output profile intent in ParamsEdited::set and make sure the default output intent is relative colorimetric everywhere instead of perceptual as to not change the previous behaviour. --- rtengine/improccoordinator.cc | 2 +- rtengine/procparams.cc | 17 ++++++++++++----- rtgui/icmpanel.cc | 4 ++-- rtgui/options.cc | 4 ++-- rtgui/paramsedited.cc | 1 + 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 6ff60506b..96a55989e 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -31,7 +31,7 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), - ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), + ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_RELATIVE), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2c93bfd47..613334469 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -894,7 +894,7 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; - outputIntent = RI_PERCEPTUAL; + outputIntent = RI_RELATIVE; gamma = "default"; gampos = 2.22; slpos = 4.5; @@ -2551,15 +2551,22 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->icm.outputIntent) { Glib::ustring intent; - if (icm.outputIntent == RI_PERCEPTUAL) { + switch (icm.outputIntent) { + default: + case RI_PERCEPTUAL: intent = "Perceptual"; - } else if (icm.outputIntent == RI_RELATIVE) { + break; + case RI_RELATIVE: intent = "Relative"; - } else if (icm.outputIntent == RI_SATURATION) { + break; + case RI_SATURATION: intent = "Saturation"; - } else if (icm.outputIntent == RI_ABSOLUTE) { + break; + case RI_ABSOLUTE: intent = "Absolute"; + break; } + keyFile.set_string ("Color Management", "OutputProfileIntent", intent); } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index d24ec9312..8b8057d45 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -200,7 +200,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); - ointent->set_active(0); + ointent->set_active (1); oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK); // Output gamma @@ -625,7 +625,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) if (ointentVal >= 0 && ointentVal < RI__COUNT) { pp->icm.outputIntent = static_cast(ointentVal); } else { - pp->icm.outputIntent = rtengine::RI_PERCEPTUAL; + pp->icm.outputIntent = rtengine::RI_RELATIVE; } pp->icm.freegamma = freegamma->get_active(); diff --git a/rtgui/options.cc b/rtgui/options.cc index c2e31ec38..e97a27ecb 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,7 +470,7 @@ void Options::setDefaults () fastexport_icm_input = "(camera)"; fastexport_icm_working = "ProPhoto"; fastexport_icm_output = "RT_sRGB"; - fastexport_icm_outputIntent = rtengine::RI_PERCEPTUAL; + fastexport_icm_outputIntent = rtengine::RI_RELATIVE; fastexport_icm_gamma = "default"; fastexport_resize_enabled = true; fastexport_resize_scale = 1; @@ -637,7 +637,7 @@ void Options::setDefaults () rtSettings.leveldnautsimpl = 0; rtSettings.monitorProfile = Glib::ustring(); - rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; + rtSettings.monitorIntent = rtengine::RI_RELATIVE; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 28d4c13b8..866142a10 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -339,6 +339,7 @@ void ParamsEdited::set (bool v) icm.dcpIlluminant = v; icm.working = v; icm.output = v; + icm.outputIntent = v; icm.gamma = v; icm.freegamma = v; icm.gampos = v; From 527c45c68588ba7ce9bfc83dbedeabb17c5507e0 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 2 Jan 2016 14:28:48 +0100 Subject: [PATCH 16/16] Build failure on ARM and PowerPC architectures, fixes #3053 --- rtengine/dcraw.cc | 2 +- rtengine/dcraw.patch | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 9c41e17f9..b1260e307 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -1925,7 +1925,7 @@ void CLASS hasselblad_correct() blur than this, but this does not need any buffer and makes nice-looking radial gradients */ ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); - const char corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, + const int corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, { {0,1}, {0,2}, {1,1}, {1,2} }, { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 5b0a2b2ec..4451e8909 100644 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,5 +1,5 @@ ---- dcraw.c 2015-11-24 19:17:16 +0000 -+++ dcraw.cc 2015-11-27 12:35:05 +0000 +--- dcraw.c 2016-01-02 12:05:48 +0000 ++++ dcraw.cc 2016-01-02 13:21:21 +0000 @@ -1,3 +1,15 @@ +/*RT*/#include +/*RT*/#include @@ -470,7 +470,7 @@ + blur than this, but this does not need any buffer and makes nice-looking + radial gradients */ + ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); -+ const char corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, ++ const int corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, + { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, + { {0,1}, {0,2}, {1,1}, {1,2} }, + { {1,0}, {1,1}, {-1,-1}, {-1,-1} },