From 4bcd6e01deb62e2ec31a51858e5f9171a5fde17a Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 6 Apr 2018 17:35:33 +0200 Subject: [PATCH] Generate Free Output Integrate Profile - FOIP --- rtdata/languages/default | 3 +- rtengine/iccstore.cc | 60 ++++++++++++++++++++++++++++++++++------ rtengine/procparams.cc | 8 ++++-- rtengine/procparams.h | 1 + rtgui/icmpanel.cc | 48 ++++++++++++++++++++++++++++++-- rtgui/icmpanel.h | 5 ++++ rtgui/paramsedited.cc | 6 ++++ rtgui/paramsedited.h | 1 + 8 files changed, 117 insertions(+), 15 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3621596f3..dd7f2f956 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1591,7 +1591,8 @@ TP_FLATFIELD_CLIPCONTROL;Clip control TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. TP_FLATFIELD_LABEL;Flat-Field TP_GAMMA_CURV;Gamma -TP_GAMMA_FREE;Free gamma +TP_GAMMA_FREE;Free Output Integrate Profile (FOIP) +TP_GAMMA_PRIM;Primaries Output profile TP_GAMMA_OUTPUT;Output gamma TP_GAMMA_SLOP;Slope (linear) TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index f133dfce8..14d7ccde2 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -1291,14 +1291,14 @@ cmsHPROFILE rtengine::ICCStore::createGammaProfile(const procparams::ColorManage //primaries for 7 working profiles ==> output profiles // eventually to adapt primaries if RT used special profiles ! - if (icm.output == "WideGamut") { + if (icm.wprimari == "WideGamut") { p[0] = 0.7350; //Widegamut primaries p[1] = 0.2650; p[2] = 0.1150; p[3] = 0.8260; p[4] = 0.1570; p[5] = 0.0180; - } else if (icm.output == "Adobe RGB") { + } else if (icm.wprimari == "Adobe RGB") { p[0] = 0.6400; //Adobe primaries p[1] = 0.3300; p[2] = 0.2100; @@ -1306,7 +1306,7 @@ cmsHPROFILE rtengine::ICCStore::createGammaProfile(const procparams::ColorManage p[4] = 0.1500; p[5] = 0.0600; temp = ColorTemp::D65; - } else if (icm.output == "sRGB") { + } else if (icm.wprimari == "sRGB") { p[0] = 0.6400; // sRGB primaries p[1] = 0.3300; p[2] = 0.3000; @@ -1314,7 +1314,7 @@ cmsHPROFILE rtengine::ICCStore::createGammaProfile(const procparams::ColorManage p[4] = 0.1500; p[5] = 0.0600; temp = ColorTemp::D65; - } else if (icm.output == "BruceRGB") { + } else if (icm.wprimari == "BruceRGB") { p[0] = 0.6400; // Bruce primaries p[1] = 0.3300; p[2] = 0.2800; @@ -1322,21 +1322,21 @@ cmsHPROFILE rtengine::ICCStore::createGammaProfile(const procparams::ColorManage p[4] = 0.1500; p[5] = 0.0600; temp = ColorTemp::D65; - } else if (icm.output == "Beta RGB") { + } else if (icm.wprimari == "Beta RGB") { p[0] = 0.6888; // Beta primaries p[1] = 0.3112; p[2] = 0.1986; p[3] = 0.7551; p[4] = 0.1265; p[5] = 0.0352; - } else if (icm.output == "BestRGB") { + } else if (icm.wprimari == "BestRGB") { p[0] = 0.7347; // Best primaries p[1] = 0.2653; p[2] = 0.2150; p[3] = 0.7750; p[4] = 0.1300; p[5] = 0.0350; - } else if (icm.output == "Rec2020") { + } else if (icm.wprimari == "Rec2020") { p[0] = 0.7080; // Rec2020 primaries p[1] = 0.2920; p[2] = 0.1700; @@ -1352,7 +1352,16 @@ cmsHPROFILE rtengine::ICCStore::createGammaProfile(const procparams::ColorManage p[4] = 0.0366; p[5] = 0.0001; } - +//printf("prim p2=%f \n", p[2]); +/* + p[0] = 0.6400; // sRGB primaries + p[1] = 0.3300; + p[2] = 0.3000; + p[3] = 0.6000; + p[4] = 0.1500; + p[5] = 0.0600; + temp = ColorTemp::D65; +*/ cmsCIExyY xyD; cmsCIExyYTRIPLE Primaries = { {p[0], p[1], 1.0}, // red @@ -1387,6 +1396,7 @@ cmsHPROFILE rtengine::ICCStore::createCustomGammaOutputProfile(const procparams: pro = true; //pro=0 RT_sRGB || Prophoto } +/* // Check that output profiles exist, otherwise use LCMS2 // Use the icc/icm profiles associated to possible working profiles, set in "options" if (icm.working == "ProPhoto" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.prophoto) && !pro) { @@ -1417,11 +1427,43 @@ cmsHPROFILE rtengine::ICCStore::createCustomGammaOutputProfile(const procparams: return nullptr; } + */ + //outProfile = options.rtSettings.srgb; + + if (icm.wprimari == "ProPhoto" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.prophoto) && !pro) { + outProfile = options.rtSettings.prophoto; + } else if (icm.wprimari == "Adobe RGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.adobe) ) { + outProfile = options.rtSettings.adobe; + } else if (icm.wprimari == "WideGamut" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.widegamut) ) { + outProfile = options.rtSettings.widegamut; + } else if (icm.wprimari == "Beta RGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.beta) ) { + outProfile = options.rtSettings.beta; + } else if (icm.wprimari == "BestRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.best) ) { + outProfile = options.rtSettings.best; + } else if (icm.wprimari == "BruceRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.bruce) ) { + outProfile = options.rtSettings.bruce; + } else if (icm.wprimari == "sRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.srgb) && !pro) { + outProfile = options.rtSettings.srgb; + } else if (icm.wprimari == "sRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.srgb10) && pro) { + outProfile = options.rtSettings.srgb10; + } else if (icm.wprimari == "ProPhoto" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.prophoto10) && pro) { + outProfile = options.rtSettings.prophoto10; + } else if (icm.wprimari == "Rec2020" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.rec2020) ) { + outProfile = options.rtSettings.rec2020; + } else { + // Should not occurs + if (settings->verbose) { + printf("\"%s\": unknown working profile! - use LCMS2 substitution\n", icm.working.c_str() ); + } + return nullptr; + } + + //begin adaptation rTRC gTRC bTRC //"outputProfile" profile has the same characteristics than RGB values, but TRC are adapted... for applying profile if (settings->verbose) { - printf("Output Gamma - profile: \"%s\"\n", outProfile.c_str() ); //c_str() + printf("Output Gamma - profile Primaries as RT profile: \"%s\"\n", outProfile.c_str() ); //c_str() } outputProfile = ICCStore::getInstance()->getProfile(outProfile); //get output profile diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 0a87d9614..bb85c060f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1948,8 +1948,9 @@ ColorManagementParams::ColorManagementParams() : outputIntent(RI_RELATIVE), outputBPC(true), gamma("default"), - gampos(2.22), - slpos(4.5), + gampos(2.4), + slpos(12.92310), + wprimari("sRGB"), freegamma(false) { } @@ -1970,6 +1971,7 @@ bool ColorManagementParams::operator ==(const ColorManagementParams& other) cons && gamma == other.gamma && gampos == other.gampos && slpos == other.slpos + && wprimari == other.wprimari && freegamma == other.freegamma; } @@ -3182,6 +3184,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->icm.freegamma, "Color Management", "Freegamma", icm.freegamma, keyFile); saveToKeyfile(!pedited || pedited->icm.gampos, "Color Management", "GammaValue", icm.gampos, keyFile); saveToKeyfile(!pedited || pedited->icm.slpos, "Color Management", "GammaSlope", icm.slpos, keyFile); + saveToKeyfile(!pedited || pedited->icm.wprimari, "Color Management", "GammaPrimari", icm.wprimari, keyFile); // Wavelet saveToKeyfile(!pedited || pedited->wavelet.enabled, "Wavelet", "Enabled", wavelet.enabled, keyFile); @@ -4206,6 +4209,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Color Management", "Freegamma", pedited, icm.freegamma, pedited->icm.freegamma); assignFromKeyfile(keyFile, "Color Management", "GammaValue", pedited, icm.gampos, pedited->icm.gampos); assignFromKeyfile(keyFile, "Color Management", "GammaSlope", pedited, icm.slpos, pedited->icm.slpos); + assignFromKeyfile(keyFile, "Color Management", "GammaPrimari", pedited, icm.wprimari, pedited->icm.wprimari); } if (keyFile.has_group ("Wavelet")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index b158d7d1f..45147c53f 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1023,6 +1023,7 @@ struct ColorManagementParams { double gampos; double slpos; bool freegamma; + Glib::ustring wprimari; static const Glib::ustring NoICMString; diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index e6c6946b8..a36b5b4a6 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -19,6 +19,8 @@ #include #include "icmpanel.h" #include "options.h" +#include "eventmapper.h" + #include "guiutils.h" #include "../rtengine/iccstore.h" #include "../rtengine/dcp.h" @@ -31,7 +33,9 @@ extern Options options; ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr), lastRefFilename(""), camName("") { - + auto m = ProcEventMapper::getInstance(); + EvICMprimariMethod = m->newEvent(GAMMA, "HISTORY_MSG_ICMPRIMARI"); + isBatchMode = lastToneCurve = lastApplyLookTable = lastApplyBaselineExposureOffset = lastApplyHueSatMap = lastgamfree = false; ipDialog = Gtk::manage (new MyFileChooserButton (M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); @@ -239,11 +243,30 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch Gtk::VBox *fgVBox = Gtk::manage ( new Gtk::VBox()); fgVBox->set_spacing(2); + freegamma = Gtk::manage(new Gtk::CheckButton((M("TP_GAMMA_FREE")))); freegamma->set_active (false); fgFrame->set_label_widget(*freegamma); - gampos = Gtk::manage(new Adjuster (M("TP_GAMMA_CURV"), 1, 3.5, 0.00001, 2.22)); + + Gtk::HBox* priHBox = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* prilab = Gtk::manage (new Gtk::Label (M("TP_GAMMA_PRIM") + ":")); + + priHBox->pack_start (*prilab, Gtk::PACK_SHRINK); + wprimari = Gtk::manage (new MyComboBoxText ()); + priHBox->pack_start (*wprimari, Gtk::PACK_EXPAND_WIDGET); + + fgVBox->pack_start(*priHBox, Gtk::PACK_EXPAND_WIDGET); + + std::vector wprinames = rtengine::ICCStore::getInstance()->getWorkingProfiles(); + + for (size_t i = 0; i < wprinames.size(); i++) { + wprimari->append (wprinames[i]); + } + + wprimari->set_active (6); + + gampos = Gtk::manage(new Adjuster (M("TP_GAMMA_CURV"), 1, 3.5, 0.00001, 2.4)); gampos->setAdjusterListener (this); if (gampos->delay < options.adjusterMaxDelay) { @@ -251,7 +274,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch } gampos->show(); - slpos = Gtk::manage(new Adjuster (M("TP_GAMMA_SLOP"), 0, 15, 0.00001, 4.5)); + slpos = Gtk::manage(new Adjuster (M("TP_GAMMA_SLOP"), 0, 15, 0.00001, 12.92310)); slpos->setAdjusterListener (this); if (slpos->delay < options.adjusterMaxDelay) { @@ -309,6 +332,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch ointentconn = ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::oiChanged) ); wgammaconn = wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); dcpillconn = dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); + wprimariconn = wprimari->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wprimariChanged) ); obpcconn = obpc->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::oBPCChanged) ); gamcsconn = freegamma->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::GamChanged)); @@ -496,6 +520,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) ConnectionBlocker ointentconn_(ointentconn); ConnectionBlocker wgammaconn_(wgammaconn); ConnectionBlocker dcpillconn_(dcpillconn); + ConnectionBlocker wprimariconn_(wprimariconn); if(pp->icm.input.substr(0, 5) != "file:" && !ipDialog->get_filename().empty()) { ipDialog->set_filename(pp->icm.input); @@ -531,6 +556,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) wnames->set_active_text (pp->icm.working); wgamma->set_active_text (pp->icm.gamma); + wprimari->set_active_text (pp->icm.wprimari); if (pp->icm.output == ColorManagementParams::NoICMString) { onames->set_active_text (M("TP_ICM_NOICM")); @@ -562,6 +588,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) gampos->set_sensitive(pp->icm.freegamma); slpos->set_sensitive(pp->icm.freegamma); updateRenderingIntent(pp->icm.output); + //wprimari->set_sensitive(!pp->icm.freegamma); } gampos->setValue (pp->icm.gampos); @@ -596,6 +623,9 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) wgamma->set_active_text(M("GENERAL_UNCHANGED")); wgamma->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->icm.wprimari) { + wprimari->set_active_text(M("GENERAL_UNCHANGED")); + } gampos->setEditedState (pedited->icm.gampos ? Edited : UnEdited); slpos->setEditedState (pedited->icm.slpos ? Edited : UnEdited); @@ -629,6 +659,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pp->icm.working = wnames->get_active_text (); pp->icm.gamma = wgamma->get_active_text (); pp->icm.dcpIlluminant = rtengine::max(dcpIll->get_active_row_number(), 0); + pp->icm.wprimari = wprimari->get_active_text (); if (onames->get_active_text() == M("TP_ICM_NOICM")) { pp->icm.output = ColorManagementParams::NoICMString; @@ -667,6 +698,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pedited->icm.freegamma = !freegamma->get_inconsistent(); pedited->icm.gampos = gampos->getEditedState (); pedited->icm.slpos = slpos->getEditedState (); + pedited->icm.wprimari = wprimari->get_active_text() != M("GENERAL_UNCHANGED"); } } @@ -713,6 +745,15 @@ void ICMPanel::wpChanged () } } +void ICMPanel::wprimariChanged () +{ + + if (listener) { + listener->panelChanged (EvICMprimariMethod, wprimari->get_active_text ()); + } +} + + void ICMPanel::gpChanged () { @@ -1063,6 +1104,7 @@ void ICMPanel::setBatchMode (bool batchMode) ointent->show(); wnames->append (M("GENERAL_UNCHANGED")); wgamma->append (M("GENERAL_UNCHANGED")); + wprimari->append (M("GENERAL_UNCHANGED")); dcpIll->append (M("GENERAL_UNCHANGED")); gampos->showEditedCB (); slpos->showEditedCB (); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index f8c762b0e..c199442bc 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -59,6 +59,8 @@ protected: bool isBatchMode; private: + rtengine::ProcEvent EvICMprimariMethod; + Gtk::VBox * iVBox; Gtk::CheckButton* obpc; @@ -80,6 +82,8 @@ private: sigc::connection wnamesconn; MyComboBoxText* wgamma; sigc::connection wgammaconn; + MyComboBoxText* wprimari; + sigc::connection wprimariconn; MyComboBoxText* onames; sigc::connection onamesconn; @@ -109,6 +113,7 @@ public: void setAdjusterBehavior (bool gammaadd, bool slopeadd); void wpChanged (); + void wprimariChanged (); void opChanged (); void oiChanged (int n); void oBPCChanged (); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 868507ad0..a8d984a4c 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -388,6 +388,7 @@ void ParamsEdited::set (bool v) icm.freegamma = v; icm.gampos = v; icm.slpos = v; + icm.wprimari = v; raw.bayersensor.method = v; raw.bayersensor.imageNum = v; raw.bayersensor.ccSteps = v; @@ -951,6 +952,7 @@ void ParamsEdited::initFrom (const std::vector icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma; icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos; icm.slpos = icm.slpos && p.icm.slpos == other.icm.slpos; + icm.wprimari = icm.wprimari && p.icm.wprimari == other.icm.wprimari; raw.bayersensor.method = raw.bayersensor.method && p.raw.bayersensor.method == other.raw.bayersensor.method; raw.bayersensor.imageNum = raw.bayersensor.imageNum && p.raw.bayersensor.imageNum == other.raw.bayersensor.imageNum; raw.bayersensor.ccSteps = raw.bayersensor.ccSteps && p.raw.bayersensor.ccSteps == other.raw.bayersensor.ccSteps; @@ -2463,6 +2465,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (icm.gamma) { toEdit.icm.gamma = mods.icm.gamma; } + + if (icm.wprimari) { + toEdit.icm.wprimari = mods.icm.wprimari; + } if (icm.freegamma) { toEdit.icm.freegamma = mods.icm.freegamma; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 12c8ee86e..8903b1d93 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -586,6 +586,7 @@ public: bool gampos; bool slpos; bool freegamma; + bool wprimari; }; class WaveletParamsEdited {