diff --git a/rtdata/images/Dark/actions/spGamutCheck.png b/rtdata/images/Dark/actions/spGamutCheck.png new file mode 100644 index 000000000..ab812272a Binary files /dev/null and b/rtdata/images/Dark/actions/spGamutCheck.png differ diff --git a/rtdata/images/Dark/actions/unchanged-18.png b/rtdata/images/Dark/actions/unchanged-18.png new file mode 100644 index 000000000..9d08dda26 Binary files /dev/null and b/rtdata/images/Dark/actions/unchanged-18.png differ diff --git a/rtdata/images/Dark/actions/unchanged-22.png b/rtdata/images/Dark/actions/unchanged-22.png new file mode 100644 index 000000000..db03d456a Binary files /dev/null and b/rtdata/images/Dark/actions/unchanged-22.png differ diff --git a/rtdata/images/Light/actions/spGamutCheck.png b/rtdata/images/Light/actions/spGamutCheck.png new file mode 100644 index 000000000..b1ae3e423 Binary files /dev/null and b/rtdata/images/Light/actions/spGamutCheck.png differ diff --git a/rtdata/images/Light/actions/unchanged-18.png b/rtdata/images/Light/actions/unchanged-18.png new file mode 100644 index 000000000..9d08dda26 Binary files /dev/null and b/rtdata/images/Light/actions/unchanged-18.png differ diff --git a/rtdata/images/Light/actions/unchanged-22.png b/rtdata/images/Light/actions/unchanged-22.png new file mode 100644 index 000000000..db03d456a Binary files /dev/null and b/rtdata/images/Light/actions/unchanged-22.png differ diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 288c9c994..a7e4ca27b 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -37,6 +37,7 @@ #include "opthelper.h" #include "cplx_wavelet_dec.h" #include "median.h" +#include "iccstore.h" #ifdef _OPENMP #include diff --git a/rtengine/color.cc b/rtengine/color.cc index c822a6f33..5f87ce1f6 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -1433,7 +1433,7 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut } -void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5) +void Color::calcGamma (double pwr, double ts, int mode, int imax, GammaValues &gamma) { //from Dcraw (D.Coffin) int i; @@ -1469,12 +1469,13 @@ void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0 } if (!mode--) { - gamma0 = g[0]; - gamma1 = g[1]; - gamma2 = g[2]; - gamma3 = g[3]; - gamma4 = g[4]; - gamma5 = g[5]; + gamma.gamma0 = g[0]; + gamma.gamma1 = g[1]; + gamma.gamma2 = g[2]; + gamma.gamma3 = g[3]; + gamma.gamma4 = g[4]; + gamma.gamma5 = g[5]; + gamma.gamma6 = 0.; return; } } diff --git a/rtengine/color.h b/rtengine/color.h index bf42140c5..6566ea1ff 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -23,7 +23,6 @@ #include "rt_math.h" #include "LUT.h" #include "labimage.h" -#include "iccstore.h" #include "iccmatrices.h" #include "sleef.c" #define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c) @@ -47,6 +46,7 @@ public: #endif + class Color { @@ -95,6 +95,17 @@ private: #endif public: + class GammaValues { + public: + double gamma0; + double gamma1; + double gamma2; + double gamma3; + double gamma4; + double gamma5; + double gamma6; + }; + typedef enum Channel { CHANNEL_RED = 1 << 0, CHANNEL_GREEN = 1 << 1, @@ -852,21 +863,21 @@ public: return h; } - /** * @brief Get the gamma curves' parameters used by LCMS2 * @param pwr gamma value [>1] * @param ts slope [0 ; 20] * @param mode [always 0] * @imax imax [always 0] - * @param gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) - * @param gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value) - * @param gamma2 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) - * @param gamma3 used in ip2Lab2rgb [0 ; 1], usually near 0.003(return value) - * @param gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) - * @param gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) + * @param gamma a pointer to an array of 6 double gamma values: + * gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) + * gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value) + * gamma2 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) + * gamma3 used in ip2Lab2rgb [0 ; 1], usually near 0.003(return value) + * gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) + * gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) */ - static void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5); + static void calcGamma (double pwr, double ts, int mode, int imax, GammaValues &gamma); /** diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 9b68cc9ee..2f1c274ea 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -36,6 +36,7 @@ #include "opthelper.h" #include "ciecam02.h" #include "color.h" +#include "iccstore.h" #undef CLIPD #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 14b5dbc3c..559a5d009 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -96,20 +96,20 @@ void loadProfiles (const Glib::ustring& dirName, } catch (Glib::Exception&) {} } -inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, std::uint8_t& result) +inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, uint8_t& result) { if (cmsIsIntentSupported (profile, intent, direction)) { result |= 1 << intent; } } -inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction) +inline uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction) { if (!profile) { return 0; } - std::uint8_t result = 0; + uint8_t result = 0; getSupportedIntent (profile, INTENT_PERCEPTUAL, direction, result); getSupportedIntent (profile, INTENT_RELATIVE_COLORIMETRIC, direction, result); @@ -188,8 +188,8 @@ std::vector ICCStore::getProfilesFromDir (const Glib::ustring& di ProfileMap profiles; - loadProfiles (profilesDir, &profiles, NULL, NULL, false, true); - loadProfiles (dirName, &profiles, NULL, NULL, false, true); + loadProfiles (profilesDir, &profiles, nullptr, nullptr, false, true); + loadProfiles (dirName, &profiles, nullptr, nullptr, false, true); for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) { res.push_back (profile->first); @@ -202,14 +202,14 @@ 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) { - return NULL; + return nullptr; } cmsUInt32Number bytesNeeded = 0; cmsSaveProfileToMem(iprof, 0, &bytesNeeded); if (bytesNeeded == 0) { - return NULL; + return nullptr; } uint8_t *data = new uint8_t[bytesNeeded + 1]; @@ -363,180 +363,167 @@ cmsHPROFILE ICCStore::workingSpaceGamma (const Glib::ustring& name) const } } -void ICCStore::getGammaArray(const procparams::ColorManagementParams &icm, double *ga) +void ICCStore::getGammaArray(const procparams::ColorManagementParams &icm, Color::GammaValues &ga) { const double eps = 0.000000001; // not divide by zero if (!icm.freegamma) {//if Free gamma not selected // gamma : ga[0],ga[1],ga[2],ga[3],ga[4],ga[5] by calcul if(icm.gamma == "BT709_g2.2_s4.5") { - ga[0] = 2.22; //BT709 2.2 4.5 - my preferred as D.Coffin - ga[1] = 0.909995; - ga[2] = 0.090005; - ga[3] = 0.222222; - ga[4] = 0.081071; - ga[5] = 0.0; + ga.gamma0 = 2.22; //BT709 2.2 4.5 - my preferred as D.Coffin + ga.gamma1 = 0.909995; + ga.gamma2 = 0.090005; + ga.gamma3 = 0.222222; + ga.gamma4 = 0.081071; + ga.gamma5 = 0.0; } else if (icm.gamma == "sRGB_g2.4_s12.92") { - ga[0] = 2.40; //sRGB 2.4 12.92 - RT default as Lightroom - ga[1] = 0.947858; - ga[2] = 0.052142; - ga[3] = 0.077399; - ga[4] = 0.039293; - ga[5] = 0.0; + ga.gamma0 = 2.40; //sRGB 2.4 12.92 - RT default as Lightroom + ga.gamma1 = 0.947858; + ga.gamma2 = 0.052142; + ga.gamma3 = 0.077399; + ga.gamma4 = 0.039293; + ga.gamma5 = 0.0; } else if (icm.gamma == "High_g1.3_s3.35") { - ga[0] = 1.3 ; //for high dynamic images - ga[1] = 0.998279; - ga[2] = 0.001721; - ga[3] = 0.298507; - ga[4] = 0.005746; - ga[5] = 0.0; + ga.gamma0 = 1.3 ; //for high dynamic images + ga.gamma1 = 0.998279; + ga.gamma2 = 0.001721; + ga.gamma3 = 0.298507; + ga.gamma4 = 0.005746; + ga.gamma5 = 0.0; } else if (icm.gamma == "Low_g2.6_s6.9") { - ga[0] = 2.6 ; //gamma 2.6 variable : for low contrast images - ga[1] = 0.891161; - ga[2] = 0.108839; - ga[3] = 0.144928; - ga[4] = 0.076332; - ga[5] = 0.0; + ga.gamma0 = 2.6 ; //gamma 2.6 variable : for low contrast images + ga.gamma1 = 0.891161; + ga.gamma2 = 0.108839; + ga.gamma3 = 0.144928; + ga.gamma4 = 0.076332; + ga.gamma5 = 0.0; } else if (icm.gamma == "linear_g1.0") { - ga[0] = 1.0; //gamma=1 linear : for high dynamic images (cf : D.Coffin...) - ga[1] = 1.; - ga[2] = 0.; - ga[3] = 1. / eps; - ga[4] = 0.; - ga[5] = 0.0; + ga.gamma0 = 1.0; //gamma=1 linear : for high dynamic images (cf : D.Coffin...) + ga.gamma1 = 1.; + ga.gamma2 = 0.; + ga.gamma3 = 1. / eps; + ga.gamma4 = 0.; + ga.gamma5 = 0.0; } else if (icm.gamma == "standard_g2.2") { - ga[0] = 2.2; //gamma=2.2 (as gamma of Adobe, Widegamut...) - ga[1] = 1.; - ga[2] = 0.; - ga[3] = 1. / eps; - ga[4] = 0.; - ga[5] = 0.0; + ga.gamma0 = 2.2; //gamma=2.2 (as gamma of Adobe, Widegamut...) + ga.gamma1 = 1.; + ga.gamma2 = 0.; + ga.gamma3 = 1. / eps; + ga.gamma4 = 0.; + ga.gamma5 = 0.0; } else if (icm.gamma == "standard_g1.8") { - ga[0] = 1.8; //gamma=1.8 (as gamma of Prophoto) - ga[1] = 1.; - ga[2] = 0.; - ga[3] = 1. / eps; - ga[4] = 0.; - ga[5] = 0.0; + ga.gamma0 = 1.8; //gamma=1.8 (as gamma of Prophoto) + ga.gamma1 = 1.; + ga.gamma2 = 0.; + ga.gamma3 = 1. / eps; + ga.gamma4 = 0.; + ga.gamma5 = 0.0; } } else { //free gamma selected - double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; //gamma parameters + Color::GammaValues g_a; //gamma parameters double pwr = 1.0 / icm.gampos; double ts = icm.slpos; double slope = icm.slpos == 0 ? eps : icm.slpos; int mode = 0, imax = 0; - Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope : return parameters for LCMS2 - ga[4] = g_a3 * ts; - //printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4); - ga[0] = icm.gampos; - ga[1] = 1. / (1.0 + g_a4); - ga[2] = g_a4 / (1.0 + g_a4); - ga[3] = 1. / slope; - ga[5] = 0.0; + Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2 + ga.gamma4 = g_a.gamma3 * ts; + //printf("g_a.gamma0=%f g_a.gamma1=%f g_a.gamma2=%f g_a.gamma3=%f g_a.gamma4=%f\n", g_a.gamma0,g_a.gamma1,g_a.gamma2,g_a.gamma3,g_a.gamma4); + ga.gamma0 = icm.gampos; + ga.gamma1 = 1. / (1.0 + g_a.gamma4); + ga.gamma2 = g_a.gamma4 / (1.0 + g_a.gamma4); + ga.gamma3 = 1. / slope; + ga.gamma5 = 0.0; //printf("ga[0]=%f ga[1]=%f ga[2]=%f ga[3]=%f ga[4]=%f\n", ga[0],ga[1],ga[2],ga[3],ga[4]); } } -cmsHPROFILE ICCStore::createGammaProfile (const procparams::ColorManagementParams &icm, double ga[]) { - float p1, p2, p3, p4, p5, p6; //primaries - ga[6] = 0.0; - int mode = 0, imax = 0; +cmsHPROFILE ICCStore::createGammaProfile (const procparams::ColorManagementParams &icm, Color::GammaValues &ga) { + float p[6]; //primaries + ga.gamma6 = 0.0; - int t50; - int select_temp = 1; //5003K + enum class ColorTemp { + D50 = 5003, // for Widegamut, Prophoto Best, Beta -> D50 + D65 = 6504 // for sRGB, AdobeRGB, Bruce Rec2020 -> D65 + }; + ColorTemp temp = ColorTemp::D50; //primaries for 7 working profiles ==> output profiles // eventually to adapt primaries if RT used special profiles ! if (icm.output == "WideGamut") { - p1 = 0.7350; //Widegamut primaries - p2 = 0.2650; - p3 = 0.1150; - p4 = 0.8260; - p5 = 0.1570; - p6 = 0.0180; - select_temp = 1; + 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") { - p1 = 0.6400; //Adobe primaries - p2 = 0.3300; - p3 = 0.2100; - p4 = 0.7100; - p5 = 0.1500; - p6 = 0.0600; - select_temp = 2; + p[0] = 0.6400; //Adobe primaries + p[1] = 0.3300; + p[2] = 0.2100; + p[3] = 0.7100; + p[4] = 0.1500; + p[5] = 0.0600; + temp = ColorTemp::D65; } else if (icm.output == "sRGB") { - p1 = 0.6400; // sRGB primaries - p2 = 0.3300; - p3 = 0.3000; - p4 = 0.6000; - p5 = 0.1500; - p6 = 0.0600; - select_temp = 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; } else if (icm.output == "BruceRGB") { - p1 = 0.6400; // Bruce primaries - p2 = 0.3300; - p3 = 0.2800; - p4 = 0.6500; - p5 = 0.1500; - p6 = 0.0600; - select_temp = 2; + p[0] = 0.6400; // Bruce primaries + p[1] = 0.3300; + p[2] = 0.2800; + p[3] = 0.6500; + p[4] = 0.1500; + p[5] = 0.0600; + temp = ColorTemp::D65; } else if (icm.output == "Beta RGB") { - p1 = 0.6888; // Beta primaries - p2 = 0.3112; - p3 = 0.1986; - p4 = 0.7551; - p5 = 0.1265; - p6 = 0.0352; - select_temp = 1; + 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") { - p1 = 0.7347; // Best primaries - p2 = 0.2653; - p3 = 0.2150; - p4 = 0.7750; - p5 = 0.1300; - p6 = 0.0350; - select_temp = 1; + 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") { - p1 = 0.7080; // Rec2020 primaries - p2 = 0.2920; - p3 = 0.1700; - p4 = 0.7970; - p5 = 0.1310; - p6 = 0.0460; - select_temp = 2; + p[0] = 0.7080; // Rec2020 primaries + p[1] = 0.2920; + p[2] = 0.1700; + p[3] = 0.7970; + p[4] = 0.1310; + p[5] = 0.0460; + temp = ColorTemp::D65; } else { - p1 = 0.7347; //ProPhoto and default primaries - p2 = 0.2653; - p3 = 0.1596; - p4 = 0.8404; - p5 = 0.0366; - p6 = 0.0001; - select_temp = 1; - } - - if(select_temp == 1) { - t50 = 5003; // for Widegamut, Prophoto Best, Beta -> D50 - } else if (select_temp == 2) { - t50 = 6504; // for sRGB, AdobeRGB, Bruce Rec2020 -> D65 + p[0] = 0.7347; //ProPhoto and default primaries + p[1] = 0.2653; + p[2] = 0.1596; + p[3] = 0.8404; + p[4] = 0.0366; + p[5] = 0.0001; } cmsCIExyY xyD; cmsCIExyYTRIPLE Primaries = { - {p1, p2, 1.0}, // red - {p3, p4, 1.0}, // green - {p5, p6, 1.0} // blue + {p[0], p[1], 1.0}, // red + {p[2], p[3], 1.0}, // green + {p[4], p[5], 1.0} // blue }; cmsToneCurve* GammaTRC[3]; - cmsFloat64Number Parameters[7]; // 7 parameters for smoother curves - Parameters[0] = ga[0]; - Parameters[1] = ga[1]; - Parameters[2] = ga[2]; - Parameters[3] = ga[3]; - Parameters[4] = ga[4]; - Parameters[5] = ga[5]; - Parameters[6] = ga[6]; - cmsWhitePointFromTemp(&xyD, t50); - GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters);//5 = more smoother than 4 + // 7 parameters for smoother curves + cmsFloat64Number Parameters[7] = { ga.gamma0, ga.gamma1, ga.gamma2, ga.gamma3, ga.gamma4, ga.gamma5, ga.gamma6 } ; + + cmsWhitePointFromTemp(&xyD, (double)temp); + GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters); //5 = smoother than 4 cmsHPROFILE oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC); //oprofdef become Outputprofile cmsFreeToneCurve(GammaTRC[0]); @@ -544,10 +531,10 @@ cmsHPROFILE ICCStore::createGammaProfile (const procparams::ColorManagementParam return oprofdef; } -cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, double ga[]) { +cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, Color::GammaValues &ga) { bool pro = false; Glib::ustring outProfile; - cmsHPROFILE outputProfile = NULL; + cmsHPROFILE outputProfile = nullptr; if (icm.freegamma && icm.gampos < 1.35) { pro = true; //select profil with gammaTRC modified : @@ -583,7 +570,7 @@ cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorMan printf("\"%s\": unknown working profile! - use LCMS2 substitution\n", icm.working.c_str() ); } - return NULL; + return nullptr; } //begin adaptation rTRC gTRC bTRC @@ -594,16 +581,16 @@ cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorMan outputProfile = iccStore->getProfile(outProfile); //get output profile - if (outputProfile == NULL) { + if (outputProfile == nullptr) { if (settings->verbose) { printf("\"%s\" ICC output profile not found!\n", outProfile.c_str()); } - return NULL; + return nullptr; } // 7 parameters for smoother curves - cmsFloat64Number Parameters[7] = { ga[0], ga[1], ga[2], ga[3], ga[4], ga[5], ga[6] }; + cmsFloat64Number Parameters[7] = { ga.gamma0, ga.gamma1, ga.gamma2, ga.gamma3, ga.gamma4, ga.gamma5, ga.gamma6 }; //change desc Tag , to "free gamma", or "BT709", etc. cmsMLU *mlu; @@ -611,7 +598,7 @@ cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorMan mlu = cmsMLUalloc(ContextID, 1); // instruction with //ICC are used to generate ICC profile - if (mlu == NULL) { + if (mlu == nullptr) { printf("Description error\n"); } else { @@ -663,8 +650,8 @@ cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorMan } // Calculate output profile's rTRC gTRC bTRC - cmsToneCurve* GammaTRC = NULL; - GammaTRC = cmsBuildParametricToneCurve(NULL, 5, Parameters); + cmsToneCurve* GammaTRC = nullptr; + GammaTRC = cmsBuildParametricToneCurve(nullptr, 5, Parameters); cmsWriteTag(outputProfile, cmsSigRedTRCTag, (void*)GammaTRC ); cmsWriteTag(outputProfile, cmsSigGreenTRCTag, (void*)GammaTRC ); cmsWriteTag(outputProfile, cmsSigBlueTRCTag, (void*)GammaTRC ); @@ -680,14 +667,7 @@ bool ICCStore::outputProfileExist (const Glib::ustring& name) const { MyMutex::MyLock lock(mutex_); - - const ProfileMap::const_iterator r = fileProfiles.find (name); - - if (r != fileProfiles.end ()) { - return true; - } - - return false; + return fileProfiles.find(name) != fileProfiles.end(); } cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const @@ -735,7 +715,7 @@ cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const // profile does not exist if (f == fileStdProfilesFileNames.end ()) { - return NULL; + return nullptr; } // but there exists one => load it @@ -761,21 +741,21 @@ ProfileContent ICCStore::getContent (const Glib::ustring& name) const return r != fileProfileContents.end () ? r->second : ProfileContent(); } -std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const +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 +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 +uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const { MyMutex::MyLock lock (mutex_); @@ -792,15 +772,15 @@ void ICCStore::init (const Glib::ustring& usrICCDir, const Glib::ustring& rtICCD profilesDir = Glib::build_filename (rtICCDir, "output"); fileProfiles.clear(); fileProfileContents.clear(); - loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, NULL, false, true); - loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, NULL, false, true); + loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, nullptr, false, true); + loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, nullptr, 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(); - loadProfiles (stdProfilesDir, NULL, NULL, &fileStdProfilesFileNames, true, false); + loadProfiles (stdProfilesDir, nullptr, nullptr, &fileStdProfilesFileNames, true, false); } // Determine the first monitor default profile of operating system, if selected @@ -843,7 +823,7 @@ void ICCStore::findDefaultMonitorProfile () } } -ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(NULL), length(0) +ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(nullptr), length(0) { FILE* f = g_fopen (fileName.c_str (), "rb"); @@ -870,14 +850,14 @@ ProfileContent::ProfileContent (const ProfileContent& other) data = new char[length + 1]; memcpy (data, other.data, length + 1); } else { - data = NULL; + data = nullptr; } } -ProfileContent::ProfileContent (cmsHPROFILE hProfile) : data(NULL), length(0) +ProfileContent::ProfileContent (cmsHPROFILE hProfile) : data(nullptr), length(0) { - if (hProfile != NULL) { + if (hProfile != nullptr) { cmsUInt32Number bytesNeeded = 0; cmsSaveProfileToMem(hProfile, 0, &bytesNeeded); @@ -901,7 +881,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other) data = new char[length + 1]; memcpy (data, other.data, length + 1); } else { - data = NULL; + data = nullptr; } return *this; @@ -913,7 +893,7 @@ cmsHPROFILE ProfileContent::toProfile () const if (data) { return cmsOpenProfileFromMem (data, length); } else { - return NULL; + return nullptr; } } diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 6aa30033e..dc2c5c12b 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -25,6 +25,7 @@ #include #include #include "procparams.h" +#include "color.h" #include "../rtgui/threadutils.h" namespace rtengine @@ -87,11 +88,11 @@ public: void init (const Glib::ustring& usrICCDir, const Glib::ustring& stdICCDir); - static void getGammaArray(const procparams::ColorManagementParams &icm, double ga[]); // ga must be an array of double with 6 elements + static void getGammaArray(const procparams::ColorManagementParams &icm, Color::GammaValues &ga); static cmsHPROFILE makeStdGammaProfile (cmsHPROFILE iprof); static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring()); - static cmsHPROFILE createGammaProfile (const procparams::ColorManagementParams &icm, double ga[]); - static cmsHPROFILE createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, double ga[]); + static cmsHPROFILE createGammaProfile (const procparams::ColorManagementParams &icm, Color::GammaValues &ga); + static cmsHPROFILE createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, Color::GammaValues &ga); // Main monitors standard profile name, from OS void findDefaultMonitorProfile (); @@ -114,19 +115,19 @@ public: 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; + uint8_t getInputIntents (cmsHPROFILE profile) const; + uint8_t getOutputIntents (cmsHPROFILE profile) const; + 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; + uint8_t getInputIntents (const Glib::ustring& name) const; + uint8_t getOutputIntents (const Glib::ustring& name) const; + uint8_t getProofIntents (const Glib::ustring& name) const; }; #define iccStore ICCStore::getInstance() inline ProfileContent::ProfileContent () : - data(NULL), + data(nullptr), length(0) { } @@ -146,17 +147,17 @@ inline Glib::ustring ICCStore::getDefaultMonitorProfileName () const return defaultMonitorProfile; } -inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const +inline uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const { return getInputIntents (getProfile (name)); } -inline std::uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const +inline uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const { return getOutputIntents (getProfile (name)); } -inline std::uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const +inline uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const { return getProofIntents (getProfile (name)); } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 5ba2dc5e1..e823b54a1 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -23,6 +23,7 @@ #include "../rtgui/ppversion.h" #include "colortemp.h" #include "improcfun.h" +#include "iccstore.h" #ifdef _OPENMP #include #endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index c511bf513..283b5007e 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -92,14 +92,14 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con if (softProof) { cmsHPROFILE oprof; if(icm.gamma != "default" || icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 - double ga[7]; + Color::GammaValues ga; iccStore->getGammaArray(icm, ga); oprof = iccStore->createGammaProfile (icm, ga); printf("ImProcFunctions::updateColorProfiles / iccStore->createGammaProfile (icm, ga);\n"); } else if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) { if(icm.gamma != "default" || icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 - double ga[7]; + Color::GammaValues ga; iccStore->getGammaArray(icm, ga); oprof = iccStore->createCustomGammaOutputProfile (icm, ga); printf("ImProcFunctions::updateColorProfiles / iccStore->createCustomGammaOutputProfile (icm, ga);\n"); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 559456c32..ad7d6f56a 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -362,7 +362,7 @@ public: 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, const procparams::ColorManagementParams &icm); - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, double *ga=NULL); + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, Color::GammaValues *ga=NULL); // 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 ee3b35350..eec8987b7 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -280,7 +280,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, * If a custom gamma profile can be created, divide by 327.68, convert to xyz and apply the custom gamma transform * otherwise divide by 327.68, convert to xyz and apply the sRGB transform, before converting with gamma2curve */ -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, double *ga) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, Color::GammaValues *ga) { //gamutmap(lab); @@ -305,9 +305,9 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE oprof = NULL; if (ga) { - iccStore->getGammaArray(icm, ga); - oprof = iccStore->createGammaProfile(icm, ga); - printf("iccStore->createGammaProfile(icm, ga);\n"); + iccStore->getGammaArray(icm, *ga); + oprof = iccStore->createGammaProfile(icm, *ga); + printf("iccStore->createGammaProfile(icm, *ga);\n"); } else { oprof = iccStore->getProfile (icm.output); printf("iccStore->getProfile (%s);\n", icm.output.c_str()); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 0f09f1ddd..7a0509966 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -39,6 +39,7 @@ #include "opthelper.h" #include "median.h" #include "EdgePreservingDecomposition.h" +#include "iccstore.h" #ifdef _OPENMP #include diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index a7ca7d86c..27c129a44 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1973,7 +1973,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar } else if(retinexParams.gammaretinex == "hig") { retinexgamtab = &(Color::gammatab_145_3); } else if(retinexParams.gammaretinex == "fre") { - double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; + Color::GammaValues g_a; double pwr = 1.0 / retinexParams.gam; double gamm = retinexParams.gam; double ts = retinexParams.slope; @@ -1984,21 +1984,21 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar } int mode = 0, imax = 0; - Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope + Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope // printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4); double start; double add; if(gamm2 < 1.) { - start = g_a2; - add = g_a4; + start = g_a.gamma2; + add = g_a.gamma4; } else { - start = g_a3; - add = g_a4; + start = g_a.gamma3; + add = g_a.gamma4; } - double mul = 1. + g_a4; + double mul = 1. + g_a.gamma4; lutTonereti(65536); @@ -2245,7 +2245,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC } else if(deh.gammaretinex == "hig") { retinexigamtab = &(Color::igammatab_145_3); } else if(deh.gammaretinex == "fre") { - double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; + Color::GammaValues g_a; double pwr = 1.0 / deh.gam; double gamm = deh.gam; double gamm2 = gamm; @@ -2256,18 +2256,18 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC std::swap(pwr, gamm); } - Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope + Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope - double mul = 1. + g_a4; + double mul = 1. + g_a.gamma4; double add; double start; if(gamm2 < 1.) { - start = g_a3; - add = g_a3; + start = g_a.gamma3; + add = g_a.gamma3; } else { - add = g_a4; - start = g_a2; + add = g_a.gamma4; + start = g_a.gamma2; } // printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 270661a33..74b8d6f5a 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1162,9 +1162,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 - double ga[7]; + Color::GammaValues ga; // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly, ga); + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly, &ga); customGamma = true; //or selected Free gamma diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index f703169ed..adf950ab0 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -356,7 +356,7 @@ void CurveEditorGroup::setTooltip( Glib::ustring ttip) void CurveEditorGroup::setBatchMode (bool batchMode) { for (std::vector::iterator i = curveEditors.begin(); i != curveEditors.end(); ++i) { - (*i)->curveType->addEntry("curveType-unchanged.png", M("GENERAL_UNCHANGED")); + (*i)->curveType->addEntry("unchanged-18.png", M("GENERAL_UNCHANGED")); (*i)->curveType->show(); } } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index d74d8ee9d..472081c23 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -68,11 +68,12 @@ private: void prepareIntentBox () { - intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + // same order than the enum intentBox.addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); intentBox.addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); - intentBox.setSelected(0); + intentBox.setSelected(1); intentBox.show (); } @@ -146,7 +147,7 @@ private: profile.clear(); intentBox.set_sensitive (false); - intentBox.setSelected (0); + intentBox.setSelected (1); profileBox.set_tooltip_text (""); @@ -158,12 +159,15 @@ private: if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) { intentBox.set_sensitive (true); - intentBox.setItemSensitivity(0, supportsRelativeColorimetric); - intentBox.setItemSensitivity(1, supportsPerceptual); + intentBox.setItemSensitivity(0, supportsPerceptual); + intentBox.setItemSensitivity(1, supportsRelativeColorimetric); intentBox.setItemSensitivity(2, supportsAbsoluteColorimetric); } else { + intentBox.setItemSensitivity(0, true); + intentBox.setItemSensitivity(1, true); + intentBox.setItemSensitivity(2, true); intentBox.set_sensitive (false); - intentBox.setSelected (0); + intentBox.setSelected (1); } profileBox.set_tooltip_text (profileBox.get_active_text ()); @@ -246,10 +250,10 @@ public: switch (options.rtSettings.monitorIntent) { default: - case rtengine::RI_RELATIVE: + case rtengine::RI_PERCEPTUAL: intentBox.setSelected (0); break; - case rtengine::RI_PERCEPTUAL: + case rtengine::RI_RELATIVE: intentBox.setSelected (1); break; case rtengine::RI_ABSOLUTE: @@ -806,8 +810,6 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) } history->resetSnapShotNumber(); - - colorMgmtToolBar->reset (); } void EditorPanel::close () diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 9c8163c8e..4c6d4f4c0 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -26,9 +26,9 @@ #include "../rtengine/improccoordinator.h" #include "../rtengine/color.h" #include "../rtengine/opthelper.h" +#include "../rtengine/iccstore.h" using namespace rtengine; -extern Glib::ustring argv0; extern Options options; diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index e1fc802d6..dcb8b30ce 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -193,13 +193,14 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch 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 ()); - 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 (1); + ointent = Gtk::manage (new PopUpButton ()); + ointent->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + ointent->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + ointent->addEntry("intent-saturation.png", M("PREFERENCES_INTENT_SATURATION")); + ointent->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); + ointent->setSelected (1); + ointent->show(); + riHBox->pack_start (*ointent->buttonGroup, Gtk::PACK_EXPAND_PADDING); oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK); // Black Point Compensation @@ -319,6 +320,29 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch show_all (); } +void ICMPanel::updateRenderingIntent (const Glib::ustring &profile) { + const uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const bool supportsRelative = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + const bool supportsSaturation = supportedIntents & 1 << INTENT_SATURATION; + const bool supportsAbsolute = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC; + + if (!profile.empty() && (supportsPerceptual || supportsRelative || supportsSaturation || supportsAbsolute)) { + ointent->set_sensitive (true); + ointent->setItemSensitivity(0, supportsPerceptual); + ointent->setItemSensitivity(1, supportsRelative); + ointent->setItemSensitivity(2, supportsSaturation); + ointent->setItemSensitivity(3, supportsAbsolute); + } else { + ointent->setItemSensitivity(0, true); + ointent->setItemSensitivity(1, true); + ointent->setItemSensitivity(2, true); + ointent->setItemSensitivity(3, true); + ointent->set_sensitive (false); + ointent->setSelected (1); + } +} + void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name) { @@ -535,7 +559,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); + ointent->setSelected (pp->icm.outputIntent); obpc->set_active (pp->icm.outputBPC); ckbToneCurve->set_active (pp->icm.toneCurve); @@ -558,6 +582,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) wgamma->set_sensitive(!pp->icm.freegamma); gampos->set_sensitive(pp->icm.freegamma); slpos->set_sensitive(pp->icm.freegamma); + updateRenderingIntent(pp->icm.output); } gampos->setValue (pp->icm.gampos); @@ -582,7 +607,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) } if (!pedited->icm.outputIntent) { - ointent->set_active_text(M("GENERAL_UNCHANGED")); + ointent->setSelected (4); } if (!pedited->icm.dcpIlluminant) { @@ -646,7 +671,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pp->icm.output = onames->get_active_text(); } - int ointentVal = ointent->get_active_row_number(); + int ointentVal = ointent->getSelected (); if (ointentVal >= 0 && ointentVal < RI__COUNT) { pp->icm.outputIntent = static_cast(ointentVal); } else { @@ -690,7 +715,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.outputIntent = ointent->getSelected () < 4; pedited->icm.outputBPC = !obpc->get_inconsistent (); pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent (); @@ -966,17 +991,37 @@ void ICMPanel::GamChanged() void ICMPanel::opChanged () { + updateRenderingIntent(onames->get_active_text()); if (listener) { listener->panelChanged (EvOProfile, onames->get_active_text()); } } -void ICMPanel::oiChanged () +void ICMPanel::oiChanged (int n) { if (listener) { - listener->panelChanged (EvOIntent, ointent->get_active_text()); + Glib::ustring str; + switch (n) { + case 0: + str = M("PREFERENCES_INTENT_PERCEPTUAL"); + break; + case 1: + str = M("PREFERENCES_INTENT_RELATIVE"); + break; + case 2: + str = M("PREFERENCES_INTENT_SATURATION"); + break; + case 3: + str = M("PREFERENCES_INTENT_ABSOLUTE"); + break; + case 4: + default: + str = M("GENERAL_UNCHANGED"); + break; + } + listener->panelChanged (EvOIntent, str); } } @@ -1104,7 +1149,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")); + ointent->addEntry("unchanged-22.png", 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 03c894017..9ce31fbe0 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -25,6 +25,7 @@ #include "guiutils.h" #include "toolpanel.h" +#include "popupbutton.h" #include "../rtengine/imagedata.h" class ICMPanelListener @@ -81,7 +82,7 @@ private: MyComboBoxText* wgamma; MyComboBoxText* onames; - MyComboBoxText* ointent; + PopUpButton* ointent; Gtk::RadioButton* ofromdir; Gtk::RadioButton* ofromfile; Gtk::RadioButton* iunchanged; @@ -98,6 +99,7 @@ private: Glib::ustring lastRefFilename; Glib::ustring camName; void updateDCP(int dcpIlluminant, Glib::ustring dcp_name); + void updateRenderingIntent (const Glib::ustring &profile); public: ICMPanel (); @@ -110,7 +112,7 @@ public: void wpChanged (); void opChanged (); - void oiChanged (); + void oiChanged (int n); void oBPCChanged (); void ipChanged (); void gpChanged (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 9ba8b175a..b1d68560a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -636,7 +636,6 @@ void Options::setDefaults () rtSettings.monitorProfile = Glib::ustring(); rtSettings.monitorIntent = rtengine::RI_RELATIVE; rtSettings.monitorBPC = true; - rtSettings.monitorBPC = true; 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/preferences.cc b/rtgui/preferences.cc index 7c325033b..c47b58b7d 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -702,8 +702,9 @@ Gtk::Widget* Preferences::getColorManagementPanel () for (std::vector::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) monProfile->append_text (*profile); - monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + // same order than enum monIntent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE")); monIntent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); monIntent->set_active (1); @@ -1454,10 +1455,10 @@ void Preferences::storePreferences () switch (monIntent->get_active_row_number ()) { default: case 0: - moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE; + moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; break; case 1: - moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; + moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE; break; case 2: moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; @@ -1584,10 +1585,10 @@ void Preferences::fillPreferences () setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); switch (moptions.rtSettings.monitorIntent) { default: - case rtengine::RI_RELATIVE: + case rtengine::RI_PERCEPTUAL: monIntent->set_active (0); break; - case rtengine::RI_PERCEPTUAL: + case rtengine::RI_RELATIVE: monIntent->set_active (1); break; case rtengine::RI_ABSOLUTE: diff --git a/tools/source_icons/scalable/spGamutCheck.file b/tools/source_icons/scalable/spGamutCheck.file new file mode 100644 index 000000000..f8b0d6338 --- /dev/null +++ b/tools/source_icons/scalable/spGamutCheck.file @@ -0,0 +1 @@ +spGamutCheck.png,w22,actions diff --git a/tools/source_icons/scalable/spGamutCheck.svg b/tools/source_icons/scalable/spGamutCheck.svg new file mode 100644 index 000000000..9748e3916 --- /dev/null +++ b/tools/source_icons/scalable/spGamutCheck.svg @@ -0,0 +1,1344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + ! + diff --git a/tools/source_icons/scalable/unchanged.file b/tools/source_icons/scalable/unchanged.file new file mode 100644 index 000000000..bfeb052cd --- /dev/null +++ b/tools/source_icons/scalable/unchanged.file @@ -0,0 +1,2 @@ +unchanged-22.png,w22,actions +unchanged-18.png,w18,actions diff --git a/tools/source_icons/scalable/unchanged.svg b/tools/source_icons/scalable/unchanged.svg new file mode 100644 index 000000000..f0178a78a --- /dev/null +++ b/tools/source_icons/scalable/unchanged.svg @@ -0,0 +1,1357 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + +