diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index d35371458..139584785 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -632,6 +632,7 @@ HISTORY_MSG_403;O - NB - Sensibilité des bords
HISTORY_MSG_404;O - NB - Base amplification
HISTORY_MSG_405;O - Débruitage - Niveau 4
HISTORY_MSG_406;O - NB - Pixels voisins
+HISTORY_MSG_443;Compensation du Point Noir de Sortie
HISTORY_NEWSNAPSHOT;Ajouter
HISTORY_NEWSNAPSHOT_TOOLTIP;Raccourci: Alt-s
HISTORY_SNAPSHOT;Capture
@@ -953,6 +954,7 @@ PREFERENCES_MENUGROUPPROFILEOPERATIONS;Opérations sur les profils
PREFERENCES_MENUGROUPRANK;Classement
PREFERENCES_MENUOPTIONS;Options du menu
PREFERENCES_METADATA;Metadonnées
+PREFERENCES_MONBPC;Compensation du Point Noir pour la transformation L*a*b*->Moniteur
PREFERENCES_MIN;Mini (100x115)
PREFERENCES_MULTITAB;Éditeurs multiple
PREFERENCES_MULTITABDUALMON;Éditeurs multiple, si possible sur un second moniteur
@@ -1082,6 +1084,8 @@ SAVEDLG_SUBSAMP_3;Meilleure qualité
SAVEDLG_TIFFUNCOMPRESSED;TIFF non compressé
SAVEDLG_WARNFILENAME;Le fichier sera nommé
SHCSELECTOR_TOOLTIP;Cliquez le bouton droit de la souris\npour réinitialiser la position de ces 3 curseurs
+SOFTPROOF_GAMUTCHECK_TOOLTIP;Si activé, indique en gris les pixels dont la couleurs est en dehors du gamut du profile de sortie
+SOFTPROOF_TOOLTIP;Épreuvage écran\nSi activé, simule le rendu généré par le profiles de sortie de l'outil ICM. Particulièrement utile pour simuler le rendu en sortie d'imprimante.
THRESHOLDSELECTOR_B;Bas
THRESHOLDSELECTOR_BL;Bas-gauche
THRESHOLDSELECTOR_BR;Bas-droite
@@ -1462,6 +1466,8 @@ TP_ICM_APPLYLOOKTABLE;Table de recherche
TP_ICM_APPLYLOOKTABLE_TOOLTIP;Utilise la table de recherche (LUT) contenu dans le profil DCP. Ce réglage n'est possible que si le profil DCP sélectionné en contient une.
TP_ICM_BLENDCMSMATRIX;Mélange des hautes lumières\ndu profil ICC avec la matrice
TP_ICM_BLENDCMSMATRIX_TOOLTIP;Activer la récupération des zones brûlées lorsque les profils ICC basés sur la LUT sont utilisés
+TP_ICM_BPC;Compensation du Point Noir
+TP_ICM_BPC_TOOLTIP;Activez ceci pour faire correspondre le canal Luminosité à l'espace couleur de sortie avec un Point Blanc fixe
TP_ICM_DCPILLUMINANT;Illuminant
TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolé
TP_ICM_DCPILLUMINANT_TOOLTIP;Sélectionne quel illuminant DCP inclus utiliser. La valeur par défaut est "Interpolé", qui est un mix entre les 2 profils inclus basé sur la Balance des Blancs choisie. Ce paramètre n'est actif que si un fichier DCP Bi-Illuminant avec support de l'interpolation est choisi.
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 5998c585d..fa324db86 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -672,6 +672,7 @@ HISTORY_MSG_439;Retinex - Process
HISTORY_MSG_440;CbDL - Method
HISTORY_MSG_441;Retinex - Gain transmission
HISTORY_MSG_442;Retinex - Scale
+HISTORY_MSG_443;Output Black Point Compensation
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
@@ -998,6 +999,7 @@ PREFERENCES_MENUGROUPRANK;Group "Rank"
PREFERENCES_MENUOPTIONS;Context Menu Options
PREFERENCES_METADATA;Metadata
PREFERENCES_MIN;Mini (100x115)
+PREFERENCES_MONBPC;Black Point Compensation for the L*a*b*->Monitor transform
PREFERENCES_MONINTENT;Default monitor intent
PREFERENCES_MONPROFILE;Default monitor profile
PREFERENCES_MULTITAB;Multiple Editor Tabs Mode
@@ -1133,6 +1135,8 @@ SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved h
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
SAVEDLG_WARNFILENAME;File will be named
SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders.
+SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile.
+SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs.
THRESHOLDSELECTOR_B;Bottom
THRESHOLDSELECTOR_BL;Bottom-left
THRESHOLDSELECTOR_BR;Bottom-right
@@ -1519,6 +1523,8 @@ TP_ICM_APPLYLOOKTABLE;Look table
TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only enabled if the selected DCP has one.
TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix
TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles.
+TP_ICM_BPC;Black Point Compensation
+TP_ICM_BPC_TOOLTIP;Enable this to fit the Luminosity channel to the output color space with a fix White Point
TP_ICM_DCPILLUMINANT;Illuminant
TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated
TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected.
diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc
index 577a3f4a6..129f44de8 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -989,24 +989,14 @@ void Crop::update (int todo)
// all pipette buffer processing should be finished now
PipetteBuffer::setReady();
- // switch back to rgb
+ // Computing the preview image, i.e. converting from lab->Monitor color space (soft-proofing disabled) or lab->Output profile->Monitor color space (soft-proofing enabled)
parent->ipf.lab2monitorRgb (labnCrop, cropImg);
if (cropImageListener) {
- // this in output space held in parallel to allow analysis like shadow/highlight
- Glib::ustring outProfile = params.icm.output;
- Glib::ustring workProfile = params.icm.working;
- Image8 *cropImgtrue;
+ // Computing the internal image for analysis, i.e. conversion from lab->Output profile (rtSettings.HistogramWorking disabled) or lab->WCS (rtSettings.HistogramWorking enabled)
- if(settings->HistogramWorking) {
- 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, params.icm.outputIntent, false);
- }
+ // internal image in output color space for analysis
+ Image8 *cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, params.icm);
int finalW = rqcropw;
diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h
index f1230bf01..450c659f0 100644
--- a/rtengine/dcrop.h
+++ b/rtengine/dcrop.h
@@ -44,7 +44,7 @@ protected:
Imagefloat* origCrop; // "one chunk" allocation
LabImage* laboCrop; // "one chunk" allocation
LabImage* labnCrop; // "one chunk" allocation
- Image8* cropImg; // "one chunk" allocation
+ Image8* cropImg; // "one chunk" allocation ; displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not
float * cbuf_real; // "one chunk" allocation
SHMap* cshmap; // per line allocation
diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc
index 82f280e54..14b5dbc3c 100644
--- a/rtengine/iccstore.cc
+++ b/rtengine/iccstore.cc
@@ -32,12 +32,13 @@
#include "../rtgui/options.h"
-namespace
+namespace rtengine
{
+extern const Settings* settings;
void loadProfiles (const Glib::ustring& dirName,
std::map* profiles,
- std::map* profileContents,
+ std::map* profileContents,
std::map* profileNames,
bool nameUpper, bool onlyRgb)
{
@@ -76,7 +77,7 @@ void loadProfiles (const Glib::ustring& dirName,
}
if (profiles) {
- const rtengine::ProfileContent content (filePath);
+ const ProfileContent content (filePath);
const cmsHPROFILE profile = content.toProfile ();
if (profile && (!onlyRgb || cmsGetColorSpace (profile) == cmsSigRgbData)) {
@@ -121,7 +122,7 @@ inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number di
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");
+ return ICCStore::createFromMatrix (mat, false, "XYZ");
}
const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best, xyz_rec2020};
@@ -362,6 +363,333 @@ cmsHPROFILE ICCStore::workingSpaceGamma (const Glib::ustring& name) const
}
}
+void ICCStore::getGammaArray(const procparams::ColorManagementParams &icm, double *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;
+ } 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;
+ } 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;
+ } 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;
+ } 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;
+ } 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;
+ } 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;
+ }
+ } else { //free gamma selected
+ double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; //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;
+ //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;
+
+ int t50;
+ int select_temp = 1; //5003K
+
+ //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;
+ } 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;
+ } 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;
+ } 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;
+ } 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;
+ } 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;
+ } 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;
+ } 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
+ }
+
+ cmsCIExyY xyD;
+ cmsCIExyYTRIPLE Primaries = {
+ {p1, p2, 1.0}, // red
+ {p3, p4, 1.0}, // green
+ {p5, p6, 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
+ cmsHPROFILE oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC); //oprofdef become Outputprofile
+
+ cmsFreeToneCurve(GammaTRC[0]);
+
+ return oprofdef;
+}
+
+cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, double ga[]) {
+ bool pro = false;
+ Glib::ustring outProfile;
+ cmsHPROFILE outputProfile = NULL;
+
+ if (icm.freegamma && icm.gampos < 1.35) {
+ pro = true; //select profil with gammaTRC modified :
+ } else if (icm.gamma == "linear_g1.0" || (icm.gamma == "High_g1.3_s3.35")) {
+ 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" && iccStore->outputProfileExist(options.rtSettings.prophoto) && !pro) {
+ outProfile = options.rtSettings.prophoto;
+ } else if (icm.working == "Adobe RGB" && iccStore->outputProfileExist(options.rtSettings.adobe) ) {
+ outProfile = options.rtSettings.adobe;
+ } else if (icm.working == "WideGamut" && iccStore->outputProfileExist(options.rtSettings.widegamut) ) {
+ outProfile = options.rtSettings.widegamut;
+ } else if (icm.working == "Beta RGB" && iccStore->outputProfileExist(options.rtSettings.beta) ) {
+ outProfile = options.rtSettings.beta;
+ } else if (icm.working == "BestRGB" && iccStore->outputProfileExist(options.rtSettings.best) ) {
+ outProfile = options.rtSettings.best;
+ } else if (icm.working == "BruceRGB" && iccStore->outputProfileExist(options.rtSettings.bruce) ) {
+ outProfile = options.rtSettings.bruce;
+ } else if (icm.working == "sRGB" && iccStore->outputProfileExist(options.rtSettings.srgb) && !pro) {
+ outProfile = options.rtSettings.srgb;
+ } else if (icm.working == "sRGB" && iccStore->outputProfileExist(options.rtSettings.srgb10) && pro) {
+ outProfile = options.rtSettings.srgb10;
+ } else if (icm.working == "ProPhoto" && iccStore->outputProfileExist(options.rtSettings.prophoto10) && pro) {
+ outProfile = options.rtSettings.prophoto10;
+ } else if (icm.working == "Rec2020" && iccStore->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 NULL;
+ }
+
+ //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()
+ }
+
+ outputProfile = iccStore->getProfile(outProfile); //get output profile
+
+ if (outputProfile == NULL) {
+
+ if (settings->verbose) {
+ printf("\"%s\" ICC output profile not found!\n", outProfile.c_str());
+ }
+ return NULL;
+ }
+
+ // 7 parameters for smoother curves
+ cmsFloat64Number Parameters[7] = { ga[0], ga[1], ga[2], ga[3], ga[4], ga[5], ga[6] };
+
+ //change desc Tag , to "free gamma", or "BT709", etc.
+ cmsMLU *mlu;
+ cmsContext ContextID = cmsGetProfileContextID(outputProfile); // create context to modify some TAGs
+ mlu = cmsMLUalloc(ContextID, 1);
+
+ // instruction with //ICC are used to generate ICC profile
+ if (mlu == NULL) {
+ printf("Description error\n");
+ } else {
+
+ // Description TAG : selection of gamma and Primaries
+ if (!icm.freegamma) {
+ std::wstring gammaStr;
+
+ if(icm.gamma == "High_g1.3_s3.35") {
+ gammaStr = std::wstring(L"GammaTRC: High g=1.3 s=3.35");
+ } else if (icm.gamma == "Low_g2.6_s6.9") {
+ gammaStr = std::wstring(L"GammaTRC: Low g=2.6 s=6.9");
+ } else if (icm.gamma == "sRGB_g2.4_s12.92") {
+ gammaStr = std::wstring(L"GammaTRC: sRGB g=2.4 s=12.92");
+ } else if (icm.gamma == "BT709_g2.2_s4.5") {
+ gammaStr = std::wstring(L"GammaTRC: BT709 g=2.2 s=4.5");
+ } else if (icm.gamma == "linear_g1.0") {
+ gammaStr = std::wstring(L"GammaTRC: Linear g=1.0");
+ } else if (icm.gamma == "standard_g2.2") {
+ gammaStr = std::wstring(L"GammaTRC: g=2.2");
+ } else if (icm.gamma == "standard_g1.8") {
+ gammaStr = std::wstring(L"GammaTRC: g=1.8");
+ }
+
+ cmsMLUsetWide(mlu, "en", "US", gammaStr.c_str());
+ } else {
+ // create description with gamma + slope + primaries
+ std::wostringstream gammaWs;
+ gammaWs.precision(2);
+ gammaWs << "Manual GammaTRC: g=" << (float)icm.gampos << " s=" << (float)icm.slpos;
+
+ cmsMLUsetWide(mlu, "en", "US", gammaWs.str().c_str());
+ }
+
+ cmsWriteTag(outputProfile, cmsSigProfileDescriptionTag, mlu);//desc changed
+
+ /*
+ cmsMLUsetWide(mlu, "en", "US", L"General Public License - AdobeRGB compatible");//adapt to profil
+ cmsWriteTag(outputProfile, cmsSigCopyrightTag, mlu);
+
+ cmsMLUsetWide(mlu, "en", "US", L"RawTherapee");
+ cmsWriteTag(outputProfile, cmsSigDeviceMfgDescTag, mlu);
+
+ cmsMLUsetWide(mlu, "en", "US", L"RTMedium"); //adapt to profil
+ cmsWriteTag(outputProfile, cmsSigDeviceModelDescTag, mlu);
+
+ */
+
+ cmsMLUfree (mlu);
+ }
+
+ // Calculate output profile's rTRC gTRC bTRC
+ cmsToneCurve* GammaTRC = NULL;
+ GammaTRC = cmsBuildParametricToneCurve(NULL, 5, Parameters);
+ cmsWriteTag(outputProfile, cmsSigRedTRCTag, (void*)GammaTRC );
+ cmsWriteTag(outputProfile, cmsSigGreenTRCTag, (void*)GammaTRC );
+ cmsWriteTag(outputProfile, cmsSigBlueTRCTag, (void*)GammaTRC );
+
+ if (GammaTRC) {
+ cmsFreeToneCurve(GammaTRC);
+ }
+
+ return outputProfile;
+}
+
+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;
+}
+
cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const
{
diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h
index 8b6e6465c..6aa30033e 100644
--- a/rtengine/iccstore.h
+++ b/rtengine/iccstore.h
@@ -23,6 +23,8 @@
#include
#include