Introducting soft-proofing and Black Point Compensation, simplify the
CMM at the end of the pipeline + sparse code refactoring A new BPC checkbutton has been created in 'Preferences/Color Management' and in the ICM tool. Better hanbling of widget sensitivity of the output profile / gamma part of the ICM tool.
This commit is contained in:
parent
b710595335
commit
5affa18341
@ -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: <b>Alt-s</b>
|
||||
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.
|
||||
|
@ -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: <b>Alt-s</b>
|
||||
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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -32,12 +32,13 @@
|
||||
|
||||
#include "../rtgui/options.h"
|
||||
|
||||
namespace
|
||||
namespace rtengine
|
||||
{
|
||||
extern const Settings* settings;
|
||||
|
||||
void loadProfiles (const Glib::ustring& dirName,
|
||||
std::map<Glib::ustring, cmsHPROFILE>* profiles,
|
||||
std::map<Glib::ustring, rtengine::ProfileContent>* profileContents,
|
||||
std::map<Glib::ustring, ProfileContent>* profileContents,
|
||||
std::map<Glib::ustring, Glib::ustring>* 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
|
||||
{
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <glibmm.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "procparams.h"
|
||||
#include "../rtgui/threadutils.h"
|
||||
|
||||
namespace rtengine
|
||||
@ -85,8 +87,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 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[]);
|
||||
|
||||
// Main monitors standard profile name, from OS
|
||||
void findDefaultMonitorProfile ();
|
||||
@ -98,9 +103,10 @@ public:
|
||||
TMatrix workingSpaceMatrix (const Glib::ustring& name) const;
|
||||
TMatrix workingSpaceInverseMatrix (const Glib::ustring& name) const;
|
||||
|
||||
cmsHPROFILE getProfile (const Glib::ustring& name) const;
|
||||
cmsHPROFILE getStdProfile (const Glib::ustring& name) const;
|
||||
ProfileContent getContent (const Glib::ustring& name) const;
|
||||
bool outputProfileExist (const Glib::ustring& name) const;
|
||||
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;
|
||||
|
@ -326,17 +326,16 @@ Image16::tofloat()
|
||||
}
|
||||
|
||||
// Parallized transformation; create transform with cmsFLAGS_NOCACHE!
|
||||
void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform)
|
||||
void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage)
|
||||
{
|
||||
//cmsDoTransform(hTransform, data, data, planestride);
|
||||
|
||||
// LittleCMS cannot parallelize planar setups -- Hombre: LCMS2.4 can! But it we use this new feature, memory allocation have to be modified too
|
||||
// LittleCMS cannot parallelize planar Lab float images
|
||||
// so build temporary buffers to allow multi processor execution
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
AlignedBuffer<unsigned short> buffer(width * 3);
|
||||
AlignedBuffer<float> bufferLab(width * 3);
|
||||
AlignedBuffer<unsigned short> bufferRGB(width * 3);
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(static)
|
||||
@ -344,25 +343,31 @@ void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform)
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
unsigned short *p = buffer.data, *pR = r(y), *pG = g(y), *pB = b(y);
|
||||
unsigned short *pRGB, *pR, *pG, *pB;
|
||||
float *pLab, *pL, *pa, *pb;
|
||||
|
||||
pLab= bufferLab.data;
|
||||
pL = labImage.L[y];
|
||||
pa = labImage.a[y];
|
||||
pb = labImage.b[y];
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
*(p++) = *(pR++);
|
||||
*(p++) = *(pG++);
|
||||
*(p++) = *(pB++);
|
||||
*(pLab++) = *(pL++) / 327.68f;
|
||||
*(pLab++) = *(pa++) / 327.68f;
|
||||
*(pLab++) = *(pb++) / 327.68f;
|
||||
}
|
||||
|
||||
cmsDoTransform (hTransform, buffer.data, buffer.data, width);
|
||||
cmsDoTransform (hTransform, bufferLab.data, bufferRGB.data, width);
|
||||
|
||||
p = buffer.data;
|
||||
pRGB = bufferRGB.data;
|
||||
pR = r(y);
|
||||
pG = g(y);
|
||||
pB = b(y);
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
*(pR++) = *(p++);
|
||||
*(pG++) = *(p++);
|
||||
*(pB++) = *(p++);
|
||||
*(pR++) = *(pRGB++);
|
||||
*(pG++) = *(pRGB++);
|
||||
*(pB++) = *(pRGB++);
|
||||
}
|
||||
} // End of parallelization
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ExecCMSTransform(cmsHTRANSFORM hTransform);
|
||||
void ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -33,9 +33,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), monitorIntent(RI_RELATIVE), 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_RELATIVE),
|
||||
softProof(false), gamutCheck(false), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false),
|
||||
allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.),
|
||||
|
||||
hltonecurve(65536),
|
||||
shtonecurve(65536),
|
||||
@ -774,7 +774,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
|
||||
|
||||
// Update the monitor color transform if necessary
|
||||
if (todo & M_MONITOR) {
|
||||
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent);
|
||||
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProof, gamutCheck);
|
||||
}
|
||||
|
||||
// process crop, if needed
|
||||
@ -794,20 +794,12 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
|
||||
MyMutex::MyLock prevImgLock(previmg->getMutex());
|
||||
|
||||
try {
|
||||
// Computing the preview image, i.e. converting from WCS->Monitor color space (soft-proofing disabled) or WCS->Output profile->Monitor color space (soft-proofing enabled)
|
||||
ipf.lab2monitorRgb (nprevl, previmg);
|
||||
|
||||
// Computing the internal image for analysis, i.e. conversion from WCS->Output profile
|
||||
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, 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.empty() || params.icm.output == ColorManagementParams::NoICMString) {
|
||||
outProfile = "sRGB";
|
||||
}
|
||||
|
||||
workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, params.icm.outputIntent, false);
|
||||
}
|
||||
workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, params.icm);
|
||||
} catch(char * str) {
|
||||
progress ("Error converting file...", 0);
|
||||
return;
|
||||
@ -1134,6 +1126,18 @@ void ImProcCoordinator::getMonitorProfile (Glib::ustring& profile, RenderingInte
|
||||
intent = monitorIntent;
|
||||
}
|
||||
|
||||
void ImProcCoordinator::setSoftProofing (bool softProof, bool gamutCheck)
|
||||
{
|
||||
this->softProof = softProof;
|
||||
this->gamutCheck = gamutCheck;
|
||||
}
|
||||
|
||||
void ImProcCoordinator::getSoftProofing (bool &softProof, bool &gamutCheck)
|
||||
{
|
||||
softProof = this->softProof;
|
||||
gamutCheck = this->gamutCheck;
|
||||
}
|
||||
|
||||
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb)
|
||||
{
|
||||
|
||||
|
@ -57,8 +57,8 @@ protected:
|
||||
Imagefloat *oprevi;
|
||||
LabImage *oprevl;
|
||||
LabImage *nprevl;
|
||||
Image8 *previmg;
|
||||
Image8 *workimg;
|
||||
Image8 *previmg; // displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not
|
||||
Image8 *workimg; // internal image in output color space for analysis
|
||||
CieImage *ncie;
|
||||
|
||||
ImageSource* imgsrc;
|
||||
@ -73,8 +73,9 @@ protected:
|
||||
ImProcFunctions ipf;
|
||||
|
||||
Glib::ustring monitorProfile;
|
||||
|
||||
RenderingIntent monitorIntent;
|
||||
bool softProof;
|
||||
bool gamutCheck;
|
||||
|
||||
int scale;
|
||||
bool highDetailPreprocessComputed;
|
||||
@ -254,6 +255,8 @@ public:
|
||||
|
||||
void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent);
|
||||
void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const;
|
||||
void setSoftProofing (bool softProof, bool gamutCheck);
|
||||
void getSoftProofing (bool &softProof, bool &gamutCheck);
|
||||
|
||||
bool updateTryLock ()
|
||||
{
|
||||
|
@ -61,14 +61,6 @@ ImProcFunctions::~ImProcFunctions ()
|
||||
if (monitorTransform) {
|
||||
cmsDeleteTransform (monitorTransform);
|
||||
}
|
||||
|
||||
if (output2monitorTransform) {
|
||||
cmsDeleteTransform (output2monitorTransform);
|
||||
}
|
||||
|
||||
if (lab2outputTransform) {
|
||||
cmsDeleteTransform (lab2outputTransform);
|
||||
}
|
||||
}
|
||||
|
||||
void ImProcFunctions::setScale (double iscale)
|
||||
@ -76,24 +68,14 @@ void ImProcFunctions::setScale (double iscale)
|
||||
scale = iscale;
|
||||
}
|
||||
|
||||
void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent)
|
||||
void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck)
|
||||
{
|
||||
// set up monitor transform
|
||||
if (monitorTransform) {
|
||||
cmsDeleteTransform (monitorTransform);
|
||||
}
|
||||
|
||||
if (output2monitorTransform) {
|
||||
cmsDeleteTransform (output2monitorTransform);
|
||||
}
|
||||
|
||||
if (lab2outputTransform) {
|
||||
cmsDeleteTransform (lab2outputTransform);
|
||||
}
|
||||
|
||||
monitorTransform = nullptr;
|
||||
output2monitorTransform = nullptr;
|
||||
lab2outputTransform = nullptr;
|
||||
|
||||
#if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB
|
||||
|
||||
@ -101,20 +83,60 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con
|
||||
|
||||
if (monitor) {
|
||||
MyMutex::MyLock lcmsLock (*lcmsMutex);
|
||||
|
||||
cmsUInt32Number flags;
|
||||
cmsHPROFILE iprof = cmsCreateLab4Profile(nullptr);
|
||||
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;
|
||||
bool softProofCreated = false;
|
||||
|
||||
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, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
|
||||
output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
|
||||
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];
|
||||
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];
|
||||
iccStore->getGammaArray(icm, ga);
|
||||
oprof = iccStore->createCustomGammaOutputProfile (icm, ga);
|
||||
printf("ImProcFunctions::updateColorProfiles / iccStore->createCustomGammaOutputProfile (icm, ga);\n");
|
||||
} else {
|
||||
oprof = iccStore->getProfile(icm.output);
|
||||
printf("ImProcFunctions::updateColorProfiles / iccStore->getProfile(%s);\n", icm.output.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (oprof) {
|
||||
// NOCACHE is for thread safety, NOOPTIMIZE for precision
|
||||
flags = cmsFLAGS_SOFTPROOFING | cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||
if (icm.outputBPC) {
|
||||
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
|
||||
}
|
||||
if (gamutCheck) {
|
||||
flags |= cmsFLAGS_GAMUTCHECK;
|
||||
}
|
||||
monitorTransform = cmsCreateProofingTransform(
|
||||
iprof, TYPE_Lab_FLT,
|
||||
monitor, TYPE_RGB_8,
|
||||
oprof,
|
||||
monitorIntent, icm.outputIntent,
|
||||
flags
|
||||
);
|
||||
if (monitorTransform) {
|
||||
softProofCreated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!softProofCreated) {
|
||||
flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||
if (settings->monitorBPC) {
|
||||
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
|
||||
}
|
||||
monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, flags);
|
||||
}
|
||||
|
||||
cmsCloseProfile(iprof);
|
||||
|
@ -223,7 +223,7 @@ public:
|
||||
bool needsPCVignetting ();
|
||||
|
||||
void firstAnalysis (const Imagefloat* const working, const ProcParams ¶ms, LUTu & vhist16);
|
||||
void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent);
|
||||
void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck);
|
||||
void rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, 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, const DCPProfile::ApplyState &asIn );
|
||||
@ -361,9 +361,8 @@ 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, 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
|
||||
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);
|
||||
// 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);
|
||||
|
@ -32,6 +32,12 @@ namespace rtengine
|
||||
|
||||
extern const Settings* settings;
|
||||
|
||||
// Used in ImProcCoordinator::updatePreviewImage (rtengine/improccoordinator.cc)
|
||||
// Crop::update (rtengine/dcrop.cc)
|
||||
// Thumbnail::processImage (rtengine/rtthumbnail.cc)
|
||||
//
|
||||
// If monitorTransform, divide by 327.68 then apply monitorTransform (which can integrate soft-proofing)
|
||||
// otherwise divide by 327.68, convert to xyz and apply the sRGB transform, before converting with gamma2curve
|
||||
void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
|
||||
{
|
||||
if (monitorTransform) {
|
||||
@ -61,21 +67,13 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
|
||||
float fy, fx, fz, x_, y_, z_, LL;
|
||||
|
||||
for (int j = 0; j < W; j++) {
|
||||
buffer[iy++] = rL[j] / 327.68f;
|
||||
buffer[iy++] = ra[j] / 327.68f;
|
||||
buffer[iy++] = rb[j] / 327.68f;
|
||||
}
|
||||
|
||||
if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) {
|
||||
AlignedBuffer<float> buf(3 * W);
|
||||
cmsDoTransform (lab2outputTransform, buffer, buf.data, W);
|
||||
cmsDoTransform (output2monitorTransform, buf.data, data + ix, W);
|
||||
} else {
|
||||
cmsDoTransform (monitorTransform, buffer, data + ix, W);
|
||||
}
|
||||
cmsDoTransform (monitorTransform, buffer, data + ix, W);
|
||||
}
|
||||
|
||||
} // End of parallelization
|
||||
@ -111,7 +109,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
|
||||
x_ = 65535.0 * Color::f2xyz(fx) * Color::D50x;
|
||||
// y_ = 65535.0 * Color::f2xyz(fy);
|
||||
z_ = 65535.0 * Color::f2xyz(fz) * Color::D50z;
|
||||
y_ = (LL > Color::epskap) ? 65535.0 * fy * fy * fy : 65535.0 * LL / Color::kappa;
|
||||
y_ = (LL > (float)Color::epskap) ? 65535.0 * fy * fy * fy : 65535.0 * LL / (float)Color::kappa;
|
||||
|
||||
Color::xyz2srgb(x_, y_, z_, R, G, B);
|
||||
|
||||
@ -125,7 +123,16 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
|
||||
}
|
||||
}
|
||||
|
||||
Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma)
|
||||
|
||||
|
||||
// Used in ImProcCoordinator::updatePreviewImage (rtengine/improccoordinator.cc)
|
||||
// Crop::update (rtengine/dcrop.cc)
|
||||
//
|
||||
// Generate an Image8
|
||||
//
|
||||
// If output profile used, divide by 327.68 then apply the "profile" profile (eventually with a standard gamma)
|
||||
// otherwise divide by 327.68, convert to xyz and apply the RGB transform, before converting with gamma2curve
|
||||
Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm)
|
||||
{
|
||||
//gamutmap(lab);
|
||||
|
||||
@ -146,9 +153,22 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
||||
}
|
||||
|
||||
Image8* image = new Image8 (cw, ch);
|
||||
|
||||
Glib::ustring profile;
|
||||
cmsHPROFILE oprof = iccStore->getProfile (profile);
|
||||
|
||||
bool standard_gamma;
|
||||
|
||||
if(settings->HistogramWorking) {
|
||||
profile = icm.working;
|
||||
standard_gamma = true;
|
||||
} else {
|
||||
profile = icm.output;
|
||||
if (icm.output.empty() || icm.output == ColorManagementParams::NoICMString) {
|
||||
profile = "sRGB";
|
||||
}
|
||||
standard_gamma = false;
|
||||
}
|
||||
|
||||
if (oprof) {
|
||||
cmsHPROFILE oprofG = oprof;
|
||||
|
||||
@ -156,11 +176,16 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
||||
oprofG = ICCStore::makeStdGammaProfile(oprof);
|
||||
}
|
||||
|
||||
cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||
if (icm.outputBPC) {
|
||||
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
|
||||
printf("lab2rgb / bpc=true\n");
|
||||
}
|
||||
else printf("lab2rgb / bpc=false\n");
|
||||
lcmsMutex->lock ();
|
||||
cmsHPROFILE hLab = cmsCreateLab4Profile(NULL);
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent,
|
||||
cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety
|
||||
cmsCloseProfile(hLab);
|
||||
cmsHPROFILE LabIProf = cmsCreateLab4Profile(NULL);
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (LabIProf, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, icm.outputIntent, flags); // NOCACHE is important for thread safety
|
||||
cmsCloseProfile(LabIProf);
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
unsigned char *data = image->data;
|
||||
@ -213,33 +238,49 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
||||
float* rL = lab->L[i];
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
int ix = 3 * i * cw;
|
||||
uint8_t* dest = image->r(i - cy) + cx;
|
||||
|
||||
for (int j = cx; j < cx + cw; j++) {
|
||||
|
||||
float fy = (0.00862069 * rL[j]) / 327.68 + 0.137932; // (L+16)/116
|
||||
float fx = (0.002 * ra[j]) / 327.68 + fy;
|
||||
float fz = fy - (0.005 * rb[j]) / 327.68;
|
||||
float LL = rL[j] / 327.68;
|
||||
float fy = (0.0086206897f * (*rL)) / 327.68f + 0.1379310345f; // (L+16)/116
|
||||
float fx = (0.002f * *(ra++)) / 327.68f + fy;
|
||||
float fz = fy - (0.005f * *(rb++)) / 327.68f;
|
||||
float LL = *(rL++) / 327.68f;
|
||||
|
||||
float x_ = 65535.0 * Color::f2xyz(fx) * Color::D50x;
|
||||
//float y_ = 65535.0 * Color::f2xyz(fy);
|
||||
float z_ = 65535.0 * Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > Color::epskap) ? 65535.0 * fy * fy * fy : 65535.0 * LL / Color::kappa;
|
||||
float x_ = 65535.0f * Color::f2xyz(fx) * Color::D50x;
|
||||
//float y_ = 65535.0f * Color::f2xyz(fy);
|
||||
float z_ = 65535.0f * Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > (float)Color::epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / (float)Color::kappa;
|
||||
|
||||
Color::xyz2rgb(x_, y_, z_, R, G, B, xyz_rgb);
|
||||
|
||||
image->data[ix++] = (int)Color::gamma2curve[R] >> 8;
|
||||
image->data[ix++] = (int)Color::gamma2curve[G] >> 8;
|
||||
image->data[ix++] = (int)Color::gamma2curve[B] >> 8;
|
||||
*(dest++) = (int)Color::gamma2curve[CLIP(R)] >> 8;
|
||||
*(dest++) = (int)Color::gamma2curve[CLIP(G)] >> 8;
|
||||
*(dest++) = (int)Color::gamma2curve[CLIP(B)] >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
// for default (not gamma)
|
||||
Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw)
|
||||
|
||||
|
||||
/** @brief Convert the final Lab image to the output RGB color space
|
||||
*
|
||||
* Used in processImage (rtengine/simpleprocess.cc)
|
||||
*
|
||||
* Provide a pointer to a 7 floats array for "ga" (uninitialized ; this array will be filled with the gamma values) if you want
|
||||
* to use the custom gamma scenario. Thoses gamma values will correspond to the ones of the chosen standard output profile
|
||||
* (Prophoto if non standard output profile given)
|
||||
*
|
||||
* If "ga" is NULL, then we're considering standard gamma with the chosen output profile.
|
||||
*
|
||||
* Generate an Image16
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
|
||||
//gamutmap(lab);
|
||||
@ -261,357 +302,120 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
|
||||
}
|
||||
|
||||
Image16* image = new Image16 (cw, ch);
|
||||
cmsHPROFILE oprof = iccStore->getProfile (profile);
|
||||
|
||||
|
||||
cmsHPROFILE oprof = NULL;
|
||||
if (ga) {
|
||||
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());
|
||||
}
|
||||
|
||||
if (oprof) {
|
||||
#pragma omp parallel for if (multiThread)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic,16) if (multiThread)
|
||||
#endif
|
||||
|
||||
for (int i = cy; i < cy + ch; i++) {
|
||||
float* rL = lab->L[i];
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
short* xa = (short*)image->r(i - cy);
|
||||
short* ya = (short*)image->g(i - cy);
|
||||
short* za = (short*)image->b(i - cy);
|
||||
short* xa = (short*)image->r(i - cy) + cx;
|
||||
short* ya = (short*)image->g(i - cy) + cx;
|
||||
short* za = (short*)image->b(i - cy) + cx;
|
||||
|
||||
for (int j = cx; j < cx + cw; j++) {
|
||||
for (int j = 0; j < cw; j++) {
|
||||
|
||||
float fy = (0.0086206897f * rL[j]) / 327.68f + 0.1379310345f; // (L+16)/116
|
||||
float fx = (0.002 * ra[j]) / 327.68f + fy;
|
||||
float fz = fy - (0.005f * rb[j]) / 327.68f;
|
||||
float LL = rL[j] / 327.68f;
|
||||
float fy = (0.0086206897f * *rL) / 327.68f + 0.1379310345f; // (L+16)/116
|
||||
float fx = (0.002f * *(ra++)) / 327.68f + fy;
|
||||
float fz = fy - (0.005f * *(rb++)) / 327.68f;
|
||||
float LL = *(rL++) / 327.68f;
|
||||
|
||||
float x_ = 65535.0f * (float) Color::f2xyz(fx) * Color::D50x;
|
||||
//float y_ = 65535.0 * Color::f2xyz(fy);
|
||||
float z_ = 65535.0f * (float) Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > Color::epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / Color::kappa;
|
||||
float x_ = 65535.0f * Color::f2xyz(fx) * Color::D50x;
|
||||
//float y_ = 65535.0f * Color::f2xyz(fy);
|
||||
float z_ = 65535.0f * Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > (float)Color::epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / (float)Color::kappa;
|
||||
|
||||
xa[j - cx] = CLIP((int) round(x_));
|
||||
ya[j - cx] = CLIP((int) round(y_));
|
||||
za[j - cx] = CLIP((int) round(z_));
|
||||
|
||||
if(bw && y_ < 65535.f ) { //force Bw value and take highlight into account
|
||||
xa[j - cx] = (int) round(y_ * Color::D50x );
|
||||
za[j - cx] = (int) round(y_ * Color::D50z);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
||||
lcmsMutex->lock ();
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
image->ExecCMSTransform(hTransform);
|
||||
|
||||
cmsDeleteTransform(hTransform);
|
||||
} else {
|
||||
#pragma omp parallel for if (multiThread)
|
||||
|
||||
for (int i = cy; i < cy + ch; i++) {
|
||||
float R, G, B;
|
||||
float* rL = lab->L[i];
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
|
||||
for (int j = cx; j < cx + cw; j++) {
|
||||
|
||||
float fy = (0.0086206897f * rL[j]) / 327.68f + 0.1379310345f; // (L+16)/116
|
||||
float fx = (0.002f * ra[j]) / 327.68f + fy;
|
||||
float fz = fy - (0.005f * rb[j]) / 327.68f;
|
||||
float LL = rL[j] / 327.68f;
|
||||
|
||||
float x_ = 65535.0f * (float) Color::f2xyz(fx) * Color::D50x;
|
||||
//float y_ = 65535.0 * Color::f2xyz(fy);
|
||||
float z_ = 65535.0f * (float) Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > Color::epskap) ? (float) 65535.0f * fy * fy * fy : 65535.0f * LL / Color::kappa;
|
||||
|
||||
Color::xyz2srgb(x_, y_, z_, R, G, B);
|
||||
|
||||
image->r(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(R)];
|
||||
image->g(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(G)];
|
||||
image->b(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(B)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
// for gamma options (BT709...sRGB linear...)
|
||||
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);
|
||||
|
||||
if (cx < 0) {
|
||||
cx = 0;
|
||||
}
|
||||
|
||||
if (cy < 0) {
|
||||
cy = 0;
|
||||
}
|
||||
|
||||
if (cx + cw > lab->W) {
|
||||
cw = lab->W - cx;
|
||||
}
|
||||
|
||||
if (cy + ch > lab->H) {
|
||||
ch = lab->H - cy;
|
||||
}
|
||||
|
||||
Image16* image = new Image16 (cw, ch);
|
||||
float p1, p2, p3, p4, p5, p6; //primaries
|
||||
|
||||
double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; //gamma parameters
|
||||
double pwr;
|
||||
double ts;
|
||||
ga6 = 0.0;
|
||||
pwr = 1.0 / gampos;
|
||||
ts = slpos;
|
||||
int mode = 0, imax = 0;
|
||||
|
||||
int t50;
|
||||
int select_temp = 1; //5003K
|
||||
const double eps = 0.000000001; // not divide by zero
|
||||
|
||||
//primaries for 7 working profiles ==> output profiles
|
||||
// eventually to adapt primaries if RT used special profiles !
|
||||
if (profi == "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 (profi == "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 (profi == "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 (profi == "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 (profi == "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 (profi == "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 (profi == "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 (!freegamma) {//if Free gamma not selected
|
||||
// gamma : ga0,ga1,ga2,ga3,ga4,ga5 by calcul
|
||||
if(gam == "BT709_g2.2_s4.5") {
|
||||
ga0 = 2.22; //BT709 2.2 4.5 - my prefered as D.Coffin
|
||||
ga1 = 0.909995;
|
||||
ga2 = 0.090005;
|
||||
ga3 = 0.222222;
|
||||
ga4 = 0.081071;
|
||||
ga5 = 0.0;
|
||||
} else if (gam == "sRGB_g2.4_s12.92") {
|
||||
ga0 = 2.40; //sRGB 2.4 12.92 - RT default as Lightroom
|
||||
ga1 = 0.947858;
|
||||
ga2 = 0.052142;
|
||||
ga3 = 0.077399;
|
||||
ga4 = 0.039293;
|
||||
ga5 = 0.0;
|
||||
} else if (gam == "High_g1.3_s3.35") {
|
||||
ga0 = 1.3 ; //for high dynamic images
|
||||
ga1 = 0.998279;
|
||||
ga2 = 0.001721;
|
||||
ga3 = 0.298507;
|
||||
ga4 = 0.005746;
|
||||
ga5 = 0.0;
|
||||
} else if (gam == "Low_g2.6_s6.9") {
|
||||
ga0 = 2.6 ; //gamma 2.6 variable : for low contrast images
|
||||
ga1 = 0.891161;
|
||||
ga2 = 0.108839;
|
||||
ga3 = 0.144928;
|
||||
ga4 = 0.076332;
|
||||
ga5 = 0.0;
|
||||
} else if (gam == "linear_g1.0") {
|
||||
ga0 = 1.0; //gamma=1 linear : for high dynamic images (cf : D.Coffin...)
|
||||
ga1 = 1.;
|
||||
ga2 = 0.;
|
||||
ga3 = 1. / eps;
|
||||
ga4 = 0.;
|
||||
ga5 = 0.0;
|
||||
} else if (gam == "standard_g2.2") {
|
||||
ga0 = 2.2; //gamma=2.2 (as gamma of Adobe, Widegamut...)
|
||||
ga1 = 1.;
|
||||
ga2 = 0.;
|
||||
ga3 = 1. / eps;
|
||||
ga4 = 0.;
|
||||
ga5 = 0.0;
|
||||
} else if (gam == "standard_g1.8") {
|
||||
ga0 = 1.8; //gamma=1.8 (as gamma of Prophoto)
|
||||
ga1 = 1.;
|
||||
ga2 = 0.;
|
||||
ga3 = 1. / eps;
|
||||
ga4 = 0.;
|
||||
ga5 = 0.0;
|
||||
}
|
||||
} else { //free gamma selected
|
||||
if(slpos == 0) {
|
||||
slpos = eps;
|
||||
}
|
||||
|
||||
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
|
||||
ga4 = 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);
|
||||
ga0 = gampos;
|
||||
ga1 = 1. / (1.0 + g_a4);
|
||||
ga2 = g_a4 / (1.0 + g_a4);
|
||||
ga3 = 1. / slpos;
|
||||
ga5 = 0.0;
|
||||
//printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", ga0,ga1,ga2,ga3,ga4);
|
||||
|
||||
}
|
||||
|
||||
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 primaries
|
||||
{p3, p4, 1.0}, // green
|
||||
{p5, p6, 1.0} //blue
|
||||
};
|
||||
cmsToneCurve* GammaTRC[3];
|
||||
cmsFloat64Number Parameters[7];
|
||||
Parameters[0] = ga0;
|
||||
Parameters[1] = ga1;
|
||||
Parameters[2] = ga2;
|
||||
Parameters[3] = ga3;
|
||||
Parameters[4] = ga4;
|
||||
Parameters[5] = ga5;
|
||||
Parameters[6] = ga6;
|
||||
// 7 parameters for smoother curves
|
||||
cmsWhitePointFromTemp(&xyD, t50);
|
||||
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters);//5 = more smoother than 4
|
||||
cmsHPROFILE oprofdef = cmsCreateRGBProfileTHR(NULL, &xyD, &Primaries, GammaTRC); //oprofdef become Outputprofile
|
||||
|
||||
cmsFreeToneCurve(GammaTRC[0]);
|
||||
|
||||
|
||||
if (oprofdef) {
|
||||
#pragma omp parallel for if (multiThread)
|
||||
|
||||
for (int i = cy; i < cy + ch; i++) {
|
||||
float* rL = lab->L[i];
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
short* xa = (short*)image->r(i - cy);
|
||||
short* ya = (short*)image->g(i - cy);
|
||||
short* za = (short*)image->b(i - cy);
|
||||
|
||||
for (int j = cx; j < cx + cw; j++) {
|
||||
|
||||
float fy = (0.0086206897f * rL[j]) / 327.68f + 0.1379310345f; // (L+16)/116
|
||||
float fx = (0.002f * ra[j]) / 327.68f + fy;
|
||||
float fz = fy - (0.005f * rb[j]) / 327.68f;
|
||||
float LL = rL[j] / 327.68f;
|
||||
|
||||
float x_ = 65535.0f * (float)Color::f2xyz(fx) * Color::D50x;
|
||||
// float y_ = 65535.0 * Color::f2xyz(fy);
|
||||
float z_ = 65535.0f * (float)Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > Color::epskap) ? (float) 65535.0 * fy * fy * fy : 65535.0f * LL / Color::kappa;
|
||||
|
||||
xa[j - cx] = CLIP((int) round(x_)) ;
|
||||
ya[j - cx] = CLIP((int) round(y_));
|
||||
za[j - cx] = CLIP((int) round(z_));
|
||||
*xa = CLIP((int) round(x_)) ;
|
||||
*(ya++) = CLIP((int) round(y_));
|
||||
*za = CLIP((int) round(z_));
|
||||
|
||||
if(bw && y_ < 65535.f) { //force Bw value and take highlight into account
|
||||
xa[j - cx] = (int) round(y_ * Color::D50x);
|
||||
za[j - cx] = (int) round(y_ * Color::D50z);
|
||||
*xa = (int) round(y_ * Color::D50x);
|
||||
*za = (int) round(y_ * Color::D50z);
|
||||
}
|
||||
|
||||
++xa;
|
||||
++za;
|
||||
}
|
||||
}
|
||||
|
||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
||||
|
||||
|
||||
*/
|
||||
|
||||
cmsHPROFILE iprof = cmsCreateLab4Profile(nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||
if (icm.outputBPC) {
|
||||
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
|
||||
printf("lab2rgb16 / icm.outputBPC=true / outputIntent=%d\n", icm.outputIntent);
|
||||
}
|
||||
else printf("lab2rgb16 / icm.outputBPC=false / outputIntent=%d\n", icm.outputIntent);
|
||||
lcmsMutex->lock ();
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
|
||||
//cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, icm.outputIntent, flags);
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, oprof, TYPE_RGB_16, icm.outputIntent, flags);
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
image->ExecCMSTransform(hTransform);
|
||||
//image->ExecCMSTransform(hTransform);
|
||||
image->ExecCMSTransform(hTransform, *lab);
|
||||
cmsDeleteTransform(hTransform);
|
||||
} else {
|
||||
//
|
||||
#pragma omp parallel for if (multiThread)
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic,16) if (multiThread)
|
||||
#endif
|
||||
for (int i = cy; i < cy + ch; i++) {
|
||||
float R, G, B;
|
||||
float* rL = lab->L[i];
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
uint16_t* rR = image->r(i - cy) + cx;
|
||||
uint16_t* rG = image->g(i - cy) + cx;
|
||||
uint16_t* rB = image->b(i - cy) + cx;
|
||||
|
||||
for (int j = cx; j < cx + cw; j++) {
|
||||
for (int j = 0; j < cw; j++) {
|
||||
|
||||
float fy = (0.0086206897f * rL[j]) / 327.68f + 0.1379310345f; // (L+16)/116
|
||||
float fx = (0.002f * ra[j]) / 327.68f + fy;
|
||||
float fz = fy - (0.005f * rb[j]) / 327.68f;
|
||||
float LL = rL[j] / 327.68f;
|
||||
float fy = (0.0086206897f * *rL) / 327.68f + 0.1379310345f; // (L+16)/116
|
||||
float fx = (0.002f * *(ra++)) / 327.68f + fy;
|
||||
float fz = fy - (0.005f * *(rb++)) / 327.68f;
|
||||
float LL = *(rL++) / 327.68f;
|
||||
|
||||
float x_ = 65535.0f * (float) Color::f2xyz(fx) * Color::D50x;
|
||||
float x_ = 65535.0f * Color::f2xyz(fx) * Color::D50x;
|
||||
//float y_ = 65535.0 * Color::f2xyz(fy);
|
||||
float z_ = 65535.0f * (float) Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > Color::epskap) ? (float) 65535.0 * fy * fy * fy : 65535.0f * LL / Color::kappa;
|
||||
float z_ = 65535.0f * Color::f2xyz(fz) * Color::D50z;
|
||||
float y_ = (LL > (float)Color::epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / (float)Color::kappa;
|
||||
|
||||
Color::xyz2srgb(x_, y_, z_, R, G, B);
|
||||
|
||||
image->r(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(R)];
|
||||
image->g(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(G)];
|
||||
image->b(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(B)];
|
||||
*(rR++) = (int)Color::gamma2curve[CLIP(R)];
|
||||
*(rG++) = (int)Color::gamma2curve[CLIP(G)];
|
||||
*(rB++) = (int)Color::gamma2curve[CLIP(B)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,6 +469,7 @@ enum ProcEvent {
|
||||
EvcbdlMethod = 439,
|
||||
EvRetinexgaintransmission = 440,
|
||||
EvLskal = 441,
|
||||
EvOBPCompens = 442,
|
||||
NUMOFEVENTS
|
||||
|
||||
};
|
||||
|
@ -927,6 +927,7 @@ void ColorManagementParams::setDefaults()
|
||||
working = "ProPhoto";
|
||||
output = "RT_sRGB";
|
||||
outputIntent = RI_RELATIVE;
|
||||
outputBPC = true;
|
||||
gamma = "default";
|
||||
gampos = 2.22;
|
||||
slpos = 4.5;
|
||||
@ -2662,6 +2663,10 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
|
||||
keyFile.set_string ("Color Management", "OutputProfileIntent", intent);
|
||||
}
|
||||
|
||||
if (!pedited || pedited->icm.outputBPC) {
|
||||
keyFile.set_boolean ("Color Management", "OutputBPC", icm.outputBPC);
|
||||
}
|
||||
|
||||
if (!pedited || pedited->icm.gamma) {
|
||||
keyFile.set_string ("Color Management", "Gammafree", icm.gamma);
|
||||
}
|
||||
@ -5921,6 +5926,14 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited)
|
||||
}
|
||||
}
|
||||
|
||||
if (keyFile.has_key ("Color Management", "OutputBPC")) {
|
||||
icm.outputBPC = keyFile.get_boolean ("Color Management", "OutputBPC");
|
||||
|
||||
if (pedited) {
|
||||
pedited->icm.gamfree = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyFile.has_key ("Color Management", "Gammafree")) {
|
||||
icm.gamma = keyFile.get_string ("Color Management", "Gammafree");
|
||||
|
||||
|
@ -967,6 +967,7 @@ public:
|
||||
Glib::ustring working;
|
||||
Glib::ustring output;
|
||||
RenderingIntent outputIntent;
|
||||
bool outputBPC;
|
||||
static const Glib::ustring NoICMString;
|
||||
|
||||
Glib::ustring gamma;
|
||||
|
@ -119,8 +119,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
||||
ALLNORAW, // EvDPDNLuma,
|
||||
ALLNORAW, // EvDPDNChroma,
|
||||
ALLNORAW, // EvDPDNGamma,
|
||||
ALLNORAW, // EvDirPyrEqualizer,
|
||||
ALLNORAW, // EvDirPyrEqlEnabled,
|
||||
ALLNORAW, // EvDirPyrEqualizer,
|
||||
ALLNORAW, // EvDirPyrEqlEnabled,
|
||||
LUMINANCECURVE, // EvLSaturation,
|
||||
LUMINANCECURVE, // EvLaCurve,
|
||||
LUMINANCECURVE, // EvLbCurve,
|
||||
@ -275,12 +275,12 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
||||
LUMINANCECURVE, // EvLCLCurve
|
||||
LUMINANCECURVE, // EvLLHCurve
|
||||
LUMINANCECURVE, // EvLHHCurve
|
||||
ALLNORAW, // EvDirPyrEqualizerThreshold
|
||||
ALLNORAW, // EvDirPyrEqualizerThreshold
|
||||
ALLNORAW, // EvDPDNenhance
|
||||
RGBCURVE, // EvBWMethodalg
|
||||
ALLNORAW, // EvDirPyrEqualizerSkin
|
||||
ALLNORAW, // EvDirPyrEqlgamutlab
|
||||
ALLNORAW, // EvDirPyrEqualizerHueskin
|
||||
ALLNORAW, // EvDirPyrEqualizerSkin
|
||||
ALLNORAW, // EvDirPyrEqlgamutlab
|
||||
ALLNORAW, // EvDirPyrEqualizerHueskin
|
||||
ALLNORAW, // EvDPDNmedian
|
||||
ALLNORAW, // EvDPDNmedmet
|
||||
RGBCURVE, // EvColorToningEnabled
|
||||
@ -453,7 +453,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
||||
RETINEX, // EvLhighl
|
||||
DEMOSAIC, // EvLbaselog
|
||||
DEMOSAIC, // EvRetinexlhcurve
|
||||
ALLNORAW, // EvOIntent
|
||||
OUTPUTPROFILE, // EvOIntent
|
||||
MONITORTRANSFORM, // EvMonitorTransform: no history message
|
||||
RETINEX, // EvLiter
|
||||
RETINEX, // EvLgrad
|
||||
@ -465,10 +465,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
||||
RETINEX, // EvLradius
|
||||
RETINEX, // EvmapMethod
|
||||
DEMOSAIC, // EvRetinexmapcurve
|
||||
DEMOSAIC, // EvviewMethod
|
||||
ALLNORAW, // EvcbdlMethod
|
||||
DEMOSAIC, // EvviewMethod
|
||||
ALLNORAW, // EvcbdlMethod
|
||||
RETINEX, // EvRetinexgaintransmission
|
||||
RETINEX //EvLskal
|
||||
RETINEX, // EvLskal
|
||||
OUTPUTPROFILE // EvOBPCompens
|
||||
|
||||
};
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
// 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 FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR|M_MONITOR) // 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)
|
||||
@ -61,7 +61,7 @@
|
||||
#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 GAMMA M_MONITOR
|
||||
#define CROP M_CROP
|
||||
#define RESIZE M_VOID
|
||||
#define EXIF M_VOID
|
||||
@ -69,7 +69,7 @@
|
||||
#define MINUPDATE M_MINUPDATE
|
||||
#define RETINEX (M_RETINEX|ALLNORAW)
|
||||
#define MONITORTRANSFORM M_MONITOR
|
||||
#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM)
|
||||
#define OUTPUTPROFILE M_MONITOR
|
||||
|
||||
extern int refreshmap[];
|
||||
#endif
|
||||
|
@ -418,6 +418,8 @@ public:
|
||||
|
||||
virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0;
|
||||
virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0;
|
||||
virtual void setSoftProofing (bool softProof, bool gamutCheck) = 0;
|
||||
virtual void getSoftProofing (bool &softProof, bool &gamutCheck) = 0;
|
||||
|
||||
virtual ~StagedImageProcessor () {}
|
||||
|
||||
|
@ -906,7 +906,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
||||
|
||||
ImProcFunctions ipf (¶ms, false);
|
||||
ipf.setScale (sqrt(double(fw * fw + fh * fh)) / sqrt(double(thumbImg->width * thumbImg->width + thumbImg->height * thumbImg->height))*scale);
|
||||
ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent);
|
||||
ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent, false, false);
|
||||
|
||||
LUTu hist16 (65536);
|
||||
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
|
||||
Glib::ustring monitorProfile; ///< ICC profile name used for the monitor
|
||||
RenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile
|
||||
bool monitorBPC; ///< Black Point Compensation for the WCS->Monitor transform (directly, i.e. not soft-proofing)
|
||||
bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile
|
||||
bool autocielab;
|
||||
bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode
|
||||
|
@ -1158,211 +1158,27 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
cmsHPROFILE jprof = NULL;
|
||||
bool customGamma = false;
|
||||
bool useLCMS = false;
|
||||
bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili ;
|
||||
|
||||
if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8
|
||||
cmsMLU *DescriptionMLU, *CopyrightMLU, *DmndMLU, *DmddMLU;// for modification TAG
|
||||
|
||||
cmsToneCurve* GammaTRC[3] = { NULL, NULL, NULL };
|
||||
cmsFloat64Number Parameters[7];
|
||||
double ga0, ga1, ga2, ga3, ga4, ga5, ga6;
|
||||
double ga[7];
|
||||
// if(params.blackwhite.enabled) params.toneCurve.hrenabled=false;
|
||||
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 );
|
||||
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly, ga);
|
||||
customGamma = true;
|
||||
|
||||
//or selected Free gamma
|
||||
useLCMS = false;
|
||||
bool pro = false;
|
||||
Glib::ustring chpro, outProfile;
|
||||
bool present_space[10] = {false, false, false, false, false, false, false, false, false, false};
|
||||
std::vector<Glib::ustring> opnames = iccStore->getProfiles ();
|
||||
|
||||
//test if files are in system
|
||||
for (int j = 0; j < 10; j++) {
|
||||
// one can modify "option" [Color Management] to adapt the profile's name if they are different for windows, MacOS, Linux ??
|
||||
// some of them are actually provided by RT, thanks to Jacques Desmis
|
||||
if (j == 0) {
|
||||
chpro = options.rtSettings.prophoto;
|
||||
} else if(j == 1) {
|
||||
chpro = options.rtSettings.adobe;
|
||||
} else if(j == 2) {
|
||||
chpro = options.rtSettings.widegamut;
|
||||
} else if(j == 3) {
|
||||
chpro = options.rtSettings.beta;
|
||||
} else if(j == 4) {
|
||||
chpro = options.rtSettings.best;
|
||||
} else if(j == 5) {
|
||||
chpro = options.rtSettings.bruce;
|
||||
} else if(j == 6) {
|
||||
chpro = options.rtSettings.srgb;
|
||||
} else if(j == 7) {
|
||||
chpro = options.rtSettings.srgb10; //gamma 1.0
|
||||
} else if(j == 8) {
|
||||
chpro = options.rtSettings.prophoto10; //gamma 1.0
|
||||
} else if(j == 9) {
|
||||
chpro = options.rtSettings.rec2020;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < opnames.size(); i++) {
|
||||
if(chpro.compare(opnames[i]) == 0) {
|
||||
present_space[j] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!present_space[j] && settings->verbose) {
|
||||
printf("Missing file: %s\n", chpro.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (params.icm.freegamma && params.icm.gampos < 1.35) {
|
||||
pro = true; //select profil with gammaTRC modified :
|
||||
} else if (params.icm.gamma == "linear_g1.0" || (params.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 (params.icm.working == "ProPhoto" && present_space[0] && !pro) {
|
||||
outProfile = options.rtSettings.prophoto;
|
||||
} else if (params.icm.working == "Adobe RGB" && present_space[1] ) {
|
||||
outProfile = options.rtSettings.adobe;
|
||||
} else if (params.icm.working == "WideGamut" && present_space[2] ) {
|
||||
outProfile = options.rtSettings.widegamut;
|
||||
} else if (params.icm.working == "Beta RGB" && present_space[3] ) {
|
||||
outProfile = options.rtSettings.beta;
|
||||
} else if (params.icm.working == "BestRGB" && present_space[4] ) {
|
||||
outProfile = options.rtSettings.best;
|
||||
} else if (params.icm.working == "BruceRGB" && present_space[5] ) {
|
||||
outProfile = options.rtSettings.bruce;
|
||||
} else if (params.icm.working == "sRGB" && present_space[6] && !pro) {
|
||||
outProfile = options.rtSettings.srgb;
|
||||
} else if (params.icm.working == "sRGB" && present_space[7] && pro) {
|
||||
outProfile = options.rtSettings.srgb10;
|
||||
} else if (params.icm.working == "ProPhoto" && present_space[8] && pro) {
|
||||
outProfile = options.rtSettings.prophoto10;
|
||||
} else if (params.icm.working == "Rec2020" && present_space[9]) {
|
||||
outProfile = options.rtSettings.rec2020;
|
||||
} else {
|
||||
// Should not occurs
|
||||
if (settings->verbose) {
|
||||
printf("\"%s\": unknown working profile! - use LCMS2 substitution\n", params.icm.working.c_str() );
|
||||
}
|
||||
|
||||
if ((jprof = iccStore->createCustomGammaOutputProfile (params.icm, ga)) == NULL) {
|
||||
useLCMS = true;
|
||||
}
|
||||
|
||||
//begin adaptation rTRC gTRC bTRC
|
||||
//"jprof" profile has the same characteristics than RGB values, but TRC are adapted... for applying profile
|
||||
if (!useLCMS) {
|
||||
if (settings->verbose) {
|
||||
printf("Output Gamma - profile: \"%s\"\n", outProfile.c_str() ); //c_str()
|
||||
}
|
||||
|
||||
jprof = iccStore->getProfile(outProfile); //get output profile
|
||||
|
||||
if (jprof == NULL) {
|
||||
useLCMS = true;
|
||||
|
||||
if (settings->verbose) {
|
||||
printf("\"%s\" ICC output profile not found!\n", outProfile.c_str());
|
||||
}
|
||||
} else {
|
||||
Parameters[0] = ga0;
|
||||
Parameters[1] = ga1;
|
||||
Parameters[2] = ga2;
|
||||
Parameters[3] = ga3;
|
||||
Parameters[4] = ga4;
|
||||
Parameters[5] = ga5;
|
||||
Parameters[6] = ga6;
|
||||
// 7 parameters for smoother curves
|
||||
//change desc Tag , to "free gamma", or "BT709", etc.
|
||||
cmsContext ContextID = cmsGetProfileContextID(jprof);//modification TAG
|
||||
DescriptionMLU = cmsMLUalloc(ContextID, 1);
|
||||
CopyrightMLU = cmsMLUalloc(ContextID, 1);//for ICC
|
||||
DmndMLU = cmsMLUalloc(ContextID, 1); //for ICC
|
||||
DmddMLU = cmsMLUalloc(ContextID, 1); // for ICC
|
||||
|
||||
|
||||
// instruction with //ICC are used for generate icc profile
|
||||
if (DescriptionMLU == NULL) {
|
||||
printf("Description error\n");
|
||||
}
|
||||
|
||||
cmsMLUsetWide(CopyrightMLU, "en", "US", L"General Public License - AdobeRGB compatible") ;//adapt to profil
|
||||
cmsMLUsetWide(DmndMLU, "en", "US", L"RawTherapee") ;
|
||||
cmsMLUsetWide(DmddMLU, "en", "US", L"RTMedium") ; //adapt to profil
|
||||
|
||||
//display Tag desc with : selection of gamma and Primaries
|
||||
if (!params.icm.freegamma) {
|
||||
std::wstring gammaStr;
|
||||
|
||||
if(params.icm.gamma == "High_g1.3_s3.35") {
|
||||
gammaStr = std::wstring(L"GammaTRC: High g=1.3 s=3.35");
|
||||
} else if (params.icm.gamma == "Low_g2.6_s6.9") {
|
||||
gammaStr = std::wstring(L"GammaTRC: Low g=2.6 s=6.9");
|
||||
} else if (params.icm.gamma == "sRGB_g2.4_s12.92") {
|
||||
gammaStr = std::wstring(L"GammaTRC: sRGB g=2.4 s=12.92");
|
||||
} else if (params.icm.gamma == "BT709_g2.2_s4.5") {
|
||||
gammaStr = std::wstring(L"GammaTRC: BT709 g=2.2 s=4.5");
|
||||
} else if (params.icm.gamma == "linear_g1.0") {
|
||||
gammaStr = std::wstring(L"GammaTRC: Linear g=1.0");
|
||||
} else if (params.icm.gamma == "standard_g2.2") {
|
||||
gammaStr = std::wstring(L"GammaTRC: g=2.2");
|
||||
} else if (params.icm.gamma == "standard_g1.8") {
|
||||
gammaStr = std::wstring(L"GammaTRC: g=1.8");
|
||||
}
|
||||
|
||||
cmsMLUsetWide(DescriptionMLU, "en", "US", gammaStr.c_str());
|
||||
|
||||
//for elaboration ICC profiles
|
||||
// else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Medium gamma sRGB(AdobeRGB compatible)");
|
||||
// else if (params.icm.gamma== "BT709_g2.2_s4.5" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma BT709(IEC61966 equivalent)");
|
||||
// else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma sRGB(IEC61966 equivalent)");
|
||||
// else if (params.icm.gamma== "linear_g1.0" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma Linear1.0(IEC61966 equivalent)");
|
||||
//else if (params.icm.gamma== "BT709_g2.2_s4.5" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma BT709(Prophoto compatible)");
|
||||
// else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma sRGB(Prophoto compatible)");
|
||||
// else if (params.icm.gamma== "linear_g1.0" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma Linear1.0(Prophoto compatible)");
|
||||
} else {
|
||||
// create description with gamma + slope + primaries
|
||||
std::wostringstream gammaWs;
|
||||
gammaWs.precision(2);
|
||||
gammaWs << "Manual GammaTRC: g=" << (float)params.icm.gampos << " s=" << (float)params.icm.slpos;
|
||||
cmsMLUsetWide(DescriptionMLU, "en", "US", gammaWs.str().c_str());
|
||||
}
|
||||
|
||||
cmsWriteTag(jprof, cmsSigProfileDescriptionTag, DescriptionMLU);//desc changed
|
||||
// cmsWriteTag(jprof, cmsSigCopyrightTag, CopyrightMLU);
|
||||
// cmsWriteTag(jprof, cmsSigDeviceMfgDescTag, DmndMLU);
|
||||
// cmsWriteTag(jprof, cmsSigDeviceModelDescTag, DmddMLU);
|
||||
|
||||
// Calculate output profile's rTRC bTRC gTRC
|
||||
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters);
|
||||
cmsWriteTag(jprof, cmsSigGreenTRCTag, (void*)GammaTRC[1] );
|
||||
cmsWriteTag(jprof, cmsSigRedTRCTag, (void*)GammaTRC[0] );
|
||||
cmsWriteTag(jprof, cmsSigBlueTRCTag, (void*)GammaTRC[2] );
|
||||
//for generation ICC profiles : here Prophoto ==> Large
|
||||
// if(params.icm.gamma== "BT709_g2.2_s4.5") cmsSaveProfileToFile(jprof, "RT_sRGB_gBT709.icm");
|
||||
// else if (params.icm.gamma== "sRGB_g2.4_s12.92") cmsSaveProfileToFile(jprof, "RT_Medium_gsRGB.icc");
|
||||
// else if (params.icm.gamma== "linear_g1.0") cmsSaveProfileToFile(jprof, "RT_Large_g10.icc");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (GammaTRC[0]) {
|
||||
cmsFreeToneCurve(GammaTRC[0]);
|
||||
}
|
||||
} else {
|
||||
// if Default gamma mode: we use the profile selected in the "Output profile" combobox;
|
||||
// gamma come from the selected profile, otherwise it comes from "Free gamma" tool
|
||||
|
||||
// readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.blackwhite.enabled);
|
||||
bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled ;
|
||||
|
||||
if(autili || butili ) {
|
||||
bwonly = false;
|
||||
}
|
||||
|
||||
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, bwonly);
|
||||
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly);
|
||||
|
||||
if (settings->verbose) {
|
||||
printf("Output profile_: \"%s\"\n", params.icm.output.c_str());
|
||||
@ -1374,17 +1190,15 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
|
||||
|
||||
|
||||
if(!autili && !butili ) {
|
||||
if(params.blackwhite.enabled && !params.colorToning.enabled ) {//force BW r=g=b
|
||||
if (settings->verbose) {
|
||||
printf("Force BW\n");
|
||||
}
|
||||
if(bwonly) { //force BW r=g=b
|
||||
if (settings->verbose) {
|
||||
printf("Force BW\n");
|
||||
}
|
||||
|
||||
for (int ccw = 0; ccw < cw; ccw++) {
|
||||
for (int cch = 0; cch < ch; cch++) {
|
||||
readyImg->r(cch, ccw) = readyImg->g(cch, ccw);
|
||||
readyImg->b(cch, ccw) = readyImg->g(cch, ccw);
|
||||
}
|
||||
for (int ccw = 0; ccw < cw; ccw++) {
|
||||
for (int cch = 0; cch < ch; cch++) {
|
||||
readyImg->r(cch, ccw) = readyImg->g(cch, ccw);
|
||||
readyImg->b(cch, ccw) = readyImg->g(cch, ccw);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1410,37 +1224,28 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
// Setting the output curve to readyImg
|
||||
if (customGamma) {
|
||||
if (!useLCMS) {
|
||||
// use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16b
|
||||
// use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16 w/ gamma
|
||||
ProfileContent pc(jprof);
|
||||
readyImg->setOutputProfile (pc.data, pc.length);
|
||||
}
|
||||
} else {
|
||||
// use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b
|
||||
Glib::ustring outputProfile;
|
||||
// use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma
|
||||
|
||||
if (params.icm.output != "" && params.icm.output != ColorManagementParams::NoICMString) {
|
||||
outputProfile = params.icm.output;
|
||||
|
||||
/* if we'd wanted the RT_sRGB profile we would have selected it
|
||||
else {
|
||||
// use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b
|
||||
if (settings->verbose) printf("No output profiles set ; looking for the default sRGB profile (\"%s\")...\n", options.rtSettings.srgb.c_str());
|
||||
outputProfile = options.rtSettings.srgb;
|
||||
}*/
|
||||
|
||||
// if iccStore->getProfile send back an object, then iccStore->getContent will do too
|
||||
cmsHPROFILE jprof = iccStore->getProfile(outputProfile); //get outProfile
|
||||
cmsHPROFILE jprof = iccStore->getProfile(params.icm.output); //get outProfile
|
||||
|
||||
if (jprof == NULL) {
|
||||
if (settings->verbose) {
|
||||
printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", outputProfile.c_str());
|
||||
printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", params.icm.output.c_str());
|
||||
}
|
||||
} else {
|
||||
if (settings->verbose) {
|
||||
printf("Using \"%s\" output profile\n", outputProfile.c_str());
|
||||
printf("Using \"%s\" output profile\n", params.icm.output.c_str());
|
||||
}
|
||||
|
||||
ProfileContent pc = iccStore->getContent (outputProfile);
|
||||
ProfileContent pc = iccStore->getContent (params.icm.output);
|
||||
readyImg->setOutputProfile (pc.data, pc.length);
|
||||
}
|
||||
} else {
|
||||
|
@ -35,11 +35,13 @@
|
||||
|
||||
using namespace rtengine::procparams;
|
||||
|
||||
class EditorPanel::MonitorProfileSelector
|
||||
class EditorPanel::ColorManagementToolbar
|
||||
{
|
||||
private:
|
||||
MyComboBoxText profileBox;
|
||||
PopUpButton intentBox;
|
||||
Gtk::ToggleButton softProof;
|
||||
Gtk::ToggleButton spGamutCheck;
|
||||
sigc::connection profileConn, intentConn;
|
||||
|
||||
rtengine::StagedImageProcessor* const& processor;
|
||||
@ -61,6 +63,7 @@ private:
|
||||
for (std::vector<Glib::ustring>::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) {
|
||||
profileBox.append_text (*iterator);
|
||||
}
|
||||
profileBox.set_tooltip_text (profileBox.get_active_text ());
|
||||
}
|
||||
|
||||
void prepareIntentBox ()
|
||||
@ -73,11 +76,31 @@ private:
|
||||
intentBox.show ();
|
||||
}
|
||||
|
||||
void prepareSoftProofingBox ()
|
||||
{
|
||||
Gtk::Image *softProofImage = Gtk::manage (new RTImage ("softProof.png"));
|
||||
softProofImage->set_padding(0, 0);
|
||||
softProof.add(*softProofImage);
|
||||
softProof.set_relief(Gtk::RELIEF_NONE);
|
||||
softProof.set_tooltip_markup(M("SOFTPROOF_TOOLTIP"));
|
||||
|
||||
softProof.set_active(false);
|
||||
softProof.show ();
|
||||
|
||||
Gtk::Image *spGamutCheckImage = Gtk::manage (new RTImage ("spGamutCheck.png"));
|
||||
spGamutCheckImage->set_padding(0, 0);
|
||||
spGamutCheck.add(*spGamutCheckImage);
|
||||
spGamutCheck.set_relief(Gtk::RELIEF_NONE);
|
||||
spGamutCheck.set_tooltip_markup(M("SOFTPROOF_GAMUTCHECK_TOOLTIP"));
|
||||
|
||||
spGamutCheck.set_active(false);
|
||||
spGamutCheck.set_sensitive(false);
|
||||
spGamutCheck.show ();
|
||||
}
|
||||
|
||||
void profileBoxChanged ()
|
||||
{
|
||||
updateParameters ();
|
||||
|
||||
profileBox.set_tooltip_text (profileBox.get_active_text ());
|
||||
}
|
||||
|
||||
void intentBoxChanged (int)
|
||||
@ -85,6 +108,16 @@ private:
|
||||
updateParameters ();
|
||||
}
|
||||
|
||||
void softProofToggled ()
|
||||
{
|
||||
updateSoftProofParameters ();
|
||||
}
|
||||
|
||||
void spGamutCheckToggled ()
|
||||
{
|
||||
updateSoftProofParameters ();
|
||||
}
|
||||
|
||||
void updateParameters ()
|
||||
{
|
||||
ConnectionBlocker profileBlocker (profileConn);
|
||||
@ -115,8 +148,10 @@ private:
|
||||
intentBox.set_sensitive (false);
|
||||
intentBox.setSelected (0);
|
||||
|
||||
profileBox.set_tooltip_text ("");
|
||||
|
||||
} else {
|
||||
const std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile);
|
||||
const 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;
|
||||
@ -130,6 +165,8 @@ private:
|
||||
intentBox.set_sensitive (false);
|
||||
intentBox.setSelected (0);
|
||||
}
|
||||
|
||||
profileBox.set_tooltip_text (profileBox.get_active_text ());
|
||||
}
|
||||
|
||||
rtengine::RenderingIntent intent;
|
||||
@ -155,22 +192,38 @@ private:
|
||||
processor->endUpdateParams (rtengine::EvMonitorTransform);
|
||||
}
|
||||
|
||||
void updateSoftProofParameters ()
|
||||
{
|
||||
spGamutCheck.set_sensitive(softProof.get_active());
|
||||
|
||||
if (profileBox.get_active_row_number () > 0) {
|
||||
processor->beginUpdateParams ();
|
||||
processor->setSoftProofing (softProof.get_active(), spGamutCheck.get_active());
|
||||
processor->endUpdateParams (rtengine::EvMonitorTransform);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) :
|
||||
ColorManagementToolbar (rtengine::StagedImageProcessor* const& ipc) :
|
||||
intentBox (Glib::ustring (), true),
|
||||
processor (ipc)
|
||||
{
|
||||
prepareProfileBox ();
|
||||
prepareIntentBox ();
|
||||
prepareSoftProofingBox ();
|
||||
|
||||
reset ();
|
||||
|
||||
profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::profileBoxChanged));
|
||||
intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::intentBoxChanged));
|
||||
softProof.signal_toggled().connect(sigc::mem_fun (this, &ColorManagementToolbar::softProofToggled));
|
||||
spGamutCheck.signal_toggled().connect(sigc::mem_fun (this, &ColorManagementToolbar::spGamutCheckToggled));;
|
||||
profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &ColorManagementToolbar::profileBoxChanged));
|
||||
intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &ColorManagementToolbar::intentBoxChanged));
|
||||
}
|
||||
|
||||
void pack_end_in (Gtk::Box* box)
|
||||
{
|
||||
box->pack_end (spGamutCheck, Gtk::PACK_SHRINK, 0);
|
||||
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);
|
||||
}
|
||||
@ -443,9 +496,9 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
|
||||
|
||||
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);
|
||||
// Color management toolbar
|
||||
colorMgmtToolBar.reset (new ColorManagementToolbar (ipc));
|
||||
colorMgmtToolBar->pack_end_in (iops);
|
||||
|
||||
editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0);
|
||||
editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0);
|
||||
@ -754,7 +807,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
|
||||
|
||||
history->resetSnapShotNumber();
|
||||
|
||||
monitorProfile->reset ();
|
||||
colorMgmtToolBar->reset ();
|
||||
}
|
||||
|
||||
void EditorPanel::close ()
|
||||
|
@ -84,8 +84,8 @@ protected:
|
||||
Gtk::Button* navNext;
|
||||
Gtk::Button* navPrev;
|
||||
|
||||
class MonitorProfileSelector;
|
||||
std::unique_ptr<MonitorProfileSelector> monitorProfile;
|
||||
class ColorManagementToolbar;
|
||||
std::unique_ptr<ColorManagementToolbar> colorMgmtToolBar;
|
||||
|
||||
ImageAreaPanel* iareapanel;
|
||||
PreviewHandler* previewHandler;
|
||||
|
@ -1179,6 +1179,7 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
|
||||
params.icm.working = options.fastexport_icm_working ;
|
||||
params.icm.output = options.fastexport_icm_output ;
|
||||
params.icm.outputIntent = options.fastexport_icm_outputIntent ;
|
||||
params.icm.outputBPC = options.fastexport_icm_outputBPC ;
|
||||
params.icm.gamma = options.fastexport_icm_gamma ;
|
||||
params.resize.enabled = options.fastexport_resize_enabled ;
|
||||
params.resize.scale = options.fastexport_resize_scale ;
|
||||
|
@ -202,6 +202,11 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
|
||||
ointent->set_active (1);
|
||||
oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK);
|
||||
|
||||
// Black Point Compensation
|
||||
obpc = Gtk::manage(new Gtk::CheckButton((M("TP_ICM_BPC"))));
|
||||
obpc->set_active (true);
|
||||
oVBox->pack_start(*obpc, Gtk::PACK_SHRINK);
|
||||
|
||||
// Output gamma
|
||||
|
||||
Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ());
|
||||
@ -295,6 +300,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
|
||||
wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) );
|
||||
dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) );
|
||||
|
||||
obpcconn = obpc->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::oBPCChanged) );
|
||||
gamcsconn = freegamma->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::GamChanged));
|
||||
tcurveconn = ckbToneCurve->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::toneCurveChanged));
|
||||
ltableconn = ckbApplyLookTable->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::applyLookTableChanged));
|
||||
@ -455,6 +461,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
|
||||
disableListener ();
|
||||
|
||||
obpcconn.block (true);
|
||||
ipc.block (true);
|
||||
gamcsconn.block (true);
|
||||
tcurveconn.block(true);
|
||||
@ -469,36 +476,50 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
|
||||
if (pp->icm.input == "(none)") {
|
||||
inone->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
if (!batchMode) {
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
}
|
||||
updateDCP(pp->icm.dcpIlluminant, "");
|
||||
} else if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() == Gtk::STATE_INSENSITIVE)) {
|
||||
iembedded->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
if (!batchMode) {
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
}
|
||||
updateDCP(pp->icm.dcpIlluminant, "");
|
||||
} else if ((pp->icm.input == "(cameraICC)") && icameraICC->get_state() != Gtk::STATE_INSENSITIVE) {
|
||||
icameraICC->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (true);
|
||||
if (!batchMode) {
|
||||
ckbBlendCMSMatrix->set_sensitive (true);
|
||||
}
|
||||
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
||||
} else if ((pp->icm.input == "(cameraICC)") && icamera->get_state() != Gtk::STATE_INSENSITIVE && icameraICC->get_state() == Gtk::STATE_INSENSITIVE) {
|
||||
// this is the case when (cameraICC) is instructed by packaged profiles, but ICC file is not found
|
||||
// therefore falling back UI to explicitly reflect the (camera) option
|
||||
icamera->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
if (!batchMode) {
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
}
|
||||
updateDCP(pp->icm.dcpIlluminant, "");
|
||||
} else if ((pp->icm.input == "(cameraICC)") && icamera->get_state() == Gtk::STATE_INSENSITIVE && icameraICC->get_state() == Gtk::STATE_INSENSITIVE) {
|
||||
// If neither (camera) nor (cameraICC) are available, as is the case when loading a non-raw, activate (embedded).
|
||||
iembedded->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
if (!batchMode) {
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
}
|
||||
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
||||
} else if ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() != Gtk::STATE_INSENSITIVE) {
|
||||
icamera->set_active (true);
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
if (!batchMode) {
|
||||
ckbBlendCMSMatrix->set_sensitive (false);
|
||||
}
|
||||
updateDCP(pp->icm.dcpIlluminant, "");
|
||||
} else {
|
||||
ifromfile->set_active (true);
|
||||
oldip = pp->icm.input.substr(5); // cut of "file:"
|
||||
ipDialog->set_filename (pp->icm.input.substr(5));
|
||||
ckbBlendCMSMatrix->set_sensitive (true);
|
||||
if (!batchMode) {
|
||||
ckbBlendCMSMatrix->set_sensitive (true);
|
||||
}
|
||||
updateDCP(pp->icm.dcpIlluminant, pp->icm.input.substr(5));
|
||||
}
|
||||
|
||||
@ -516,6 +537,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
}
|
||||
ointent->set_active(pp->icm.outputIntent);
|
||||
|
||||
obpc->set_active (pp->icm.outputBPC);
|
||||
ckbToneCurve->set_active (pp->icm.toneCurve);
|
||||
lastToneCurve = pp->icm.toneCurve;
|
||||
ckbApplyLookTable->set_active (pp->icm.applyLookTable);
|
||||
@ -528,22 +550,28 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
ckbBlendCMSMatrix->set_active (pp->icm.blendCMSMatrix);
|
||||
lastBlendCMSMatrix = pp->icm.blendCMSMatrix;
|
||||
|
||||
onames->set_sensitive(wgamma->get_active_row_number() == 0 || freegamma->get_active()); //"default"
|
||||
wgamma->set_sensitive(!freegamma->get_active());
|
||||
|
||||
freegamma->set_active (pp->icm.freegamma);
|
||||
lastgamfree = pp->icm.freegamma;
|
||||
|
||||
if (!batchMode) {
|
||||
onames->set_sensitive(wgamma->get_active_row_number() == 0 && !pp->icm.freegamma); //"default"
|
||||
wgamma->set_sensitive(!pp->icm.freegamma);
|
||||
gampos->set_sensitive(pp->icm.freegamma);
|
||||
slpos->set_sensitive(pp->icm.freegamma);
|
||||
}
|
||||
|
||||
gampos->setValue (pp->icm.gampos);
|
||||
slpos->setValue (pp->icm.slpos);
|
||||
|
||||
if (pedited) {
|
||||
iunchanged->set_active (!pedited->icm.input);
|
||||
obpc->set_inconsistent(!pedited->icm.outputBPC);
|
||||
ckbToneCurve->set_inconsistent(!pedited->icm.toneCurve);
|
||||
ckbApplyLookTable->set_inconsistent(!pedited->icm.applyLookTable);
|
||||
ckbApplyBaselineExposureOffset->set_inconsistent(!pedited->icm.applyBaselineExposureOffset);
|
||||
ckbApplyHueSatMap->set_inconsistent(!pedited->icm.applyHueSatMap);
|
||||
ckbBlendCMSMatrix->set_inconsistent(!pedited->icm.blendCMSMatrix);
|
||||
freegamma->set_inconsistent (!pedited->icm.freegamma);
|
||||
|
||||
if (!pedited->icm.working) {
|
||||
wnames->set_active_text(M("GENERAL_UNCHANGED"));
|
||||
@ -578,6 +606,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
hsmconn.block(false);
|
||||
gamcsconn.block (false);
|
||||
ipc.block (false);
|
||||
obpcconn.block (false);
|
||||
|
||||
enableListener ();
|
||||
}
|
||||
@ -655,12 +684,14 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
|
||||
pp->icm.blendCMSMatrix = ckbBlendCMSMatrix->get_active ();
|
||||
pp->icm.gampos = (double) gampos->getValue();
|
||||
pp->icm.slpos = (double) slpos->getValue();
|
||||
pp->icm.outputBPC = obpc->get_active ();
|
||||
|
||||
if (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.outputBPC = !obpc->get_inconsistent ();
|
||||
pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED");
|
||||
pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent ();
|
||||
pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent ();
|
||||
@ -697,7 +728,7 @@ void ICMPanel::setAdjusterBehavior (bool gammaadd, bool slopeadd)
|
||||
void ICMPanel::adjusterChanged (Adjuster* a, double newval)
|
||||
{
|
||||
|
||||
if (listener && freegamma->get_active()) {
|
||||
if (listener && (freegamma->get_active() || batchMode)) {
|
||||
|
||||
Glib::ustring costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), newval);
|
||||
|
||||
@ -735,7 +766,7 @@ void ICMPanel::dcpIlluminantChanged()
|
||||
|
||||
void ICMPanel::toneCurveChanged()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (multiImage) {
|
||||
if (ckbToneCurve->get_inconsistent()) {
|
||||
ckbToneCurve->set_inconsistent (false);
|
||||
tcurveconn.block (true);
|
||||
@ -749,13 +780,19 @@ void ICMPanel::toneCurveChanged()
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
listener->panelChanged (EvDCPToneCurve, ckbToneCurve->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
|
||||
if (ckbToneCurve->get_inconsistent()) {
|
||||
listener->panelChanged (EvDCPToneCurve, M("GENERAL_UNCHANGED"));
|
||||
} else if (ckbToneCurve->get_active()) {
|
||||
listener->panelChanged (EvDCPToneCurve, M("GENERAL_ENABLED"));
|
||||
} else {
|
||||
listener->panelChanged (EvDCPToneCurve, M("GENERAL_DISABLED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICMPanel::applyLookTableChanged()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (multiImage) {
|
||||
if (ckbApplyLookTable->get_inconsistent()) {
|
||||
ckbApplyLookTable->set_inconsistent (false);
|
||||
ltableconn.block (true);
|
||||
@ -769,13 +806,19 @@ void ICMPanel::applyLookTableChanged()
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
listener->panelChanged (EvDCPApplyLookTable, ckbApplyLookTable->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
|
||||
if (ckbApplyLookTable->get_inconsistent()) {
|
||||
listener->panelChanged (EvDCPApplyLookTable, M("GENERAL_UNCHANGED"));
|
||||
} else if (ckbApplyLookTable->get_active()) {
|
||||
listener->panelChanged (EvDCPApplyLookTable, M("GENERAL_ENABLED"));
|
||||
} else {
|
||||
listener->panelChanged (EvDCPApplyLookTable, M("GENERAL_DISABLED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICMPanel::applyBaselineExposureOffsetChanged()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (multiImage) {
|
||||
if (ckbApplyBaselineExposureOffset->get_inconsistent()) {
|
||||
ckbApplyBaselineExposureOffset->set_inconsistent (false);
|
||||
beoconn.block (true);
|
||||
@ -789,13 +832,19 @@ void ICMPanel::applyBaselineExposureOffsetChanged()
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
listener->panelChanged (EvDCPApplyBaselineExposureOffset, ckbApplyBaselineExposureOffset->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
|
||||
if (ckbApplyBaselineExposureOffset->get_inconsistent()) {
|
||||
listener->panelChanged (EvDCPApplyBaselineExposureOffset, M("GENERAL_UNCHANGED"));
|
||||
} else if (ckbApplyBaselineExposureOffset->get_active()) {
|
||||
listener->panelChanged (EvDCPApplyBaselineExposureOffset, M("GENERAL_ENABLED"));
|
||||
} else {
|
||||
listener->panelChanged (EvDCPApplyBaselineExposureOffset, M("GENERAL_DISABLED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICMPanel::applyHueSatMapChanged()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (multiImage) {
|
||||
if (ckbApplyHueSatMap->get_inconsistent()) {
|
||||
ckbApplyHueSatMap->set_inconsistent (false);
|
||||
hsmconn.block (true);
|
||||
@ -809,7 +858,13 @@ void ICMPanel::applyHueSatMapChanged()
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
listener->panelChanged (EvDCPApplyHueSatMap, ckbApplyHueSatMap->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
|
||||
if (ckbApplyHueSatMap->get_inconsistent()) {
|
||||
listener->panelChanged (EvDCPApplyHueSatMap, M("GENERAL_UNCHANGED"));
|
||||
} else if (ckbApplyHueSatMap->get_active()) {
|
||||
listener->panelChanged (EvDCPApplyHueSatMap, M("GENERAL_ENABLED"));
|
||||
} else {
|
||||
listener->panelChanged (EvDCPApplyHueSatMap, M("GENERAL_DISABLED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,7 +901,7 @@ void ICMPanel::ipChanged ()
|
||||
|
||||
void ICMPanel::blendCMSMatrixChanged()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (multiImage) {
|
||||
if (ckbBlendCMSMatrix->get_inconsistent()) {
|
||||
ckbBlendCMSMatrix->set_inconsistent (false);
|
||||
blendcmsconn.block (true);
|
||||
@ -860,13 +915,19 @@ void ICMPanel::blendCMSMatrixChanged()
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
listener->panelChanged (EvBlendCMSMatrix, ckbBlendCMSMatrix->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
|
||||
if (ckbBlendCMSMatrix->get_inconsistent()) {
|
||||
listener->panelChanged (EvBlendCMSMatrix, M("GENERAL_UNCHANGED"));
|
||||
} else if (ckbBlendCMSMatrix->get_active()) {
|
||||
listener->panelChanged (EvBlendCMSMatrix, M("GENERAL_ENABLED"));
|
||||
} else {
|
||||
listener->panelChanged (EvBlendCMSMatrix, M("GENERAL_DISABLED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICMPanel::GamChanged()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (multiImage) {
|
||||
if (freegamma->get_inconsistent()) {
|
||||
freegamma->set_inconsistent (false);
|
||||
gamcsconn.block (true);
|
||||
@ -880,14 +941,25 @@ void ICMPanel::GamChanged()
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
if (freegamma->get_active()) {
|
||||
if (freegamma->get_inconsistent()) {
|
||||
listener->panelChanged (EvGAMFREE, M("GENERAL_UNCHANGED"));
|
||||
}
|
||||
else if (freegamma->get_active()) {
|
||||
listener->panelChanged (EvGAMFREE, M("GENERAL_ENABLED"));
|
||||
onames->set_sensitive(!freegamma->get_active());//disabled choice
|
||||
wgamma->set_sensitive(!freegamma->get_active());
|
||||
if (!batchMode) {
|
||||
onames->set_sensitive(false);//disabled choice
|
||||
wgamma->set_sensitive(false);
|
||||
gampos->set_sensitive(true);
|
||||
slpos->set_sensitive(true);
|
||||
}
|
||||
} else {
|
||||
listener->panelChanged (EvGAMFREE, M("GENERAL_DISABLED"));
|
||||
onames->set_sensitive(!freegamma->get_active() && wgamma->get_active_row_number() == 0);
|
||||
wgamma->set_sensitive(!freegamma->get_active());
|
||||
if (!batchMode) {
|
||||
onames->set_sensitive(wgamma->get_active_row_number() == 0);
|
||||
wgamma->set_sensitive(true);
|
||||
gampos->set_sensitive(false);
|
||||
slpos->set_sensitive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -908,6 +980,32 @@ void ICMPanel::oiChanged ()
|
||||
}
|
||||
}
|
||||
|
||||
void ICMPanel::oBPCChanged ()
|
||||
{
|
||||
if (multiImage) {
|
||||
if (obpc->get_inconsistent()) {
|
||||
obpc->set_inconsistent (false);
|
||||
obpcconn.block (true);
|
||||
obpc->set_active (false);
|
||||
obpcconn.block (false);
|
||||
} else if (lastobpc) {
|
||||
obpc->set_inconsistent (true);
|
||||
}
|
||||
|
||||
lastobpc = obpc->get_active ();
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
if (obpc->get_inconsistent()) {
|
||||
listener->panelChanged (EvOBPCompens, M("GENERAL_UNCHANGED"));
|
||||
} else if (obpc->get_active()) {
|
||||
listener->panelChanged (EvOBPCompens, M("GENERAL_ENABLED"));
|
||||
} else {
|
||||
listener->panelChanged (EvOBPCompens, M("GENERAL_DISABLED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICMPanel::setRawMeta (bool raw, const rtengine::ImageData* pMeta)
|
||||
{
|
||||
|
||||
|
@ -53,6 +53,8 @@ protected:
|
||||
sigc::connection beoconn;
|
||||
bool lastApplyHueSatMap;
|
||||
sigc::connection hsmconn;
|
||||
bool lastobpc;
|
||||
sigc::connection obpcconn;
|
||||
bool lastBlendCMSMatrix;
|
||||
bool isBatchMode;
|
||||
sigc::connection blendcmsconn;
|
||||
@ -60,6 +62,7 @@ protected:
|
||||
private:
|
||||
Gtk::VBox * iVBox;
|
||||
|
||||
Gtk::CheckButton* obpc;
|
||||
Gtk::CheckButton* freegamma;
|
||||
Gtk::RadioButton* inone;
|
||||
|
||||
@ -108,6 +111,7 @@ public:
|
||||
void wpChanged ();
|
||||
void opChanged ();
|
||||
void oiChanged ();
|
||||
void oBPCChanged ();
|
||||
void ipChanged ();
|
||||
void gpChanged ();
|
||||
void GamChanged ();
|
||||
|
@ -469,6 +469,7 @@ void Options::setDefaults ()
|
||||
fastexport_icm_working = "ProPhoto";
|
||||
fastexport_icm_output = "RT_sRGB";
|
||||
fastexport_icm_outputIntent = rtengine::RI_RELATIVE;
|
||||
fastexport_icm_outputBPC = true;
|
||||
fastexport_icm_gamma = "default";
|
||||
fastexport_resize_enabled = true;
|
||||
fastexport_resize_scale = 1;
|
||||
@ -634,6 +635,8 @@ 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"
|
||||
@ -1463,6 +1466,10 @@ int Options::readFromFile (Glib::ustring fname)
|
||||
rtSettings.monitorIntent = static_cast<rtengine::RenderingIntent>(keyFile.get_integer("Color Management", "Intent"));
|
||||
}
|
||||
|
||||
if (keyFile.has_key ("Color Management", "Intent")) {
|
||||
rtSettings.monitorBPC = keyFile.get_boolean("Color Management", "MonitorBPC");
|
||||
}
|
||||
|
||||
if (keyFile.has_key ("Color Management", "CRI")) {
|
||||
rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI");
|
||||
}
|
||||
@ -1719,6 +1726,10 @@ int Options::readFromFile (Glib::ustring fname)
|
||||
fastexport_icm_outputIntent = static_cast<rtengine::RenderingIntent>(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" ));
|
||||
}
|
||||
|
||||
if (keyFile.has_key ("Fast Export", "fastexport_icm_output_bpc" )) {
|
||||
fastexport_icm_outputBPC = keyFile.get_boolean ("Fast Export", "fastexport_icm_output_bpc" );
|
||||
}
|
||||
|
||||
if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) {
|
||||
fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" );
|
||||
}
|
||||
@ -2028,6 +2039,7 @@ int Options::saveToFile (Glib::ustring fname)
|
||||
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.monitorIntent);
|
||||
keyFile.set_boolean ("Color Management", "MonitorBPC", rtSettings.monitorBPC);
|
||||
keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice);
|
||||
keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey);
|
||||
keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc);
|
||||
@ -2096,6 +2108,7 @@ int Options::saveToFile (Glib::ustring fname)
|
||||
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_integer ("Fast Export", "fastexport_icm_output_bpc" , fastexport_icm_outputBPC );
|
||||
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 );
|
||||
|
@ -260,6 +260,7 @@ public:
|
||||
Glib::ustring fastexport_icm_working;
|
||||
Glib::ustring fastexport_icm_output;
|
||||
rtengine::RenderingIntent fastexport_icm_outputIntent;
|
||||
bool fastexport_icm_outputBPC;
|
||||
Glib::ustring fastexport_icm_gamma;
|
||||
bool fastexport_resize_enabled;
|
||||
double fastexport_resize_scale;
|
||||
|
@ -353,8 +353,9 @@ void ParamsEdited::set (bool v)
|
||||
icm.working = v;
|
||||
icm.output = v;
|
||||
icm.outputIntent = v;
|
||||
icm.outputBPC = v;
|
||||
icm.gamma = v;
|
||||
icm.freegamma = v;
|
||||
icm.freegamma = v;
|
||||
icm.gampos = v;
|
||||
icm.slpos = v;
|
||||
raw.bayersensor.method = v;
|
||||
@ -847,6 +848,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
|
||||
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.outputBPC = icm.outputBPC && p.icm.outputBPC == other.icm.outputBPC ;
|
||||
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;
|
||||
@ -2210,6 +2212,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
|
||||
toEdit.icm.outputIntent = mods.icm.outputIntent;
|
||||
}
|
||||
|
||||
if (icm.outputBPC) {
|
||||
toEdit.icm.outputBPC = mods.icm.outputBPC;
|
||||
}
|
||||
|
||||
//if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos;
|
||||
//if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos;
|
||||
if (icm.gampos) {
|
||||
|
@ -544,6 +544,7 @@ public:
|
||||
bool working;
|
||||
bool output;
|
||||
bool outputIntent;
|
||||
bool outputBPC;
|
||||
bool gamma;
|
||||
bool gampos;
|
||||
bool slpos;
|
||||
|
@ -707,6 +707,9 @@ Gtk::Widget* Preferences::getColorManagementPanel ()
|
||||
monIntent->append_text (M("PREFERENCES_INTENT_ABSOLUTE"));
|
||||
monIntent->set_active (1);
|
||||
|
||||
monBPC = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_MONBPC")));
|
||||
monBPC->set_active (true);
|
||||
|
||||
iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged));
|
||||
|
||||
#if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851
|
||||
@ -716,22 +719,24 @@ Gtk::Widget* Preferences::getColorManagementPanel ()
|
||||
|
||||
Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 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);
|
||||
colt->attach (*pdlabel, 0, 1, row, row + 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
|
||||
colt->attach (*iccDir, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
|
||||
#if !defined(__APPLE__) // monitor profile not supported on apple
|
||||
++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);
|
||||
colt->attach (*mplabel, 0, 1, row, row + 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
|
||||
colt->attach (*monProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
|
||||
#if defined(WIN32)
|
||||
++row;
|
||||
colt->attach (*cbAutoMonProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
|
||||
colt->attach (*cbAutoMonProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
|
||||
#endif
|
||||
#endif
|
||||
++row;
|
||||
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);
|
||||
colt->attach (*milabel, 0, 1, row, row + 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
|
||||
colt->attach (*monIntent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
|
||||
mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
mvbcm->pack_start (*monBPC, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
#if defined(WIN32)
|
||||
autoMonProfileToggled();
|
||||
#endif
|
||||
@ -1458,6 +1463,7 @@ void Preferences::storePreferences ()
|
||||
moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE;
|
||||
break;
|
||||
}
|
||||
moptions.rtSettings.monitorBPC = monBPC->get_active ();
|
||||
#if defined(WIN32)
|
||||
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
|
||||
#endif
|
||||
@ -1588,6 +1594,7 @@ void Preferences::fillPreferences ()
|
||||
monIntent->set_active (2);
|
||||
break;
|
||||
}
|
||||
monBPC->set_active (moptions.rtSettings.monitorBPC);
|
||||
#if defined(WIN32)
|
||||
cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile);
|
||||
#endif
|
||||
|
@ -97,6 +97,7 @@ protected:
|
||||
Gtk::FileChooserButton* iccDir;
|
||||
Gtk::ComboBoxText* monProfile;
|
||||
Gtk::ComboBoxText* monIntent;
|
||||
Gtk::CheckButton* monBPC;
|
||||
Gtk::CheckButton* cbAutoMonProfile;
|
||||
//Gtk::CheckButton* cbAutocielab;
|
||||
Gtk::CheckButton* cbciecamfloat;
|
||||
|
430
tools/color_management.svg
Normal file
430
tools/color_management.svg
Normal file
@ -0,0 +1,430 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="297mm"
|
||||
height="210mm"
|
||||
viewBox="0 0 1052.3622 744.09448"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="color_management.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker5710"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5712"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#dd8a7e;stroke-width:1pt;stroke-opacity:1;fill:#dd8a7e;fill-opacity:1"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4281"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#dd8a7e;stroke-width:1pt;stroke-opacity:1;fill:#dd8a7e;fill-opacity:1"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker5062"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5064"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker4998"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5000"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4287"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#add352;stroke-width:1pt;stroke-opacity:1;fill:#add352;fill-opacity:1"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker4756"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4758"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#439872;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4272"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
transform="scale(0.8) translate(12.5,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4293"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#439872;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker4574"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4576"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4290"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#439872;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) translate(1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4275"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="493.25484"
|
||||
inkscape:cy="287.08088"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1018"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-308.26772)">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4218"
|
||||
d="m 414.03112,637.20982 c 34.16308,0 69.92396,17.17259 125.16361,17.17259"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#add352;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send)" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#439872;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:28,7;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker4998)"
|
||||
d="m 372.32787,680.64952 c 16.21054,39.59059 30.90653,57.74251 30.90653,98.45433"
|
||||
id="path4200"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
y="790.53473"
|
||||
x="538.40112"
|
||||
height="80"
|
||||
width="200"
|
||||
id="rect4210"
|
||||
style="opacity:1;fill:#dcb7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#dd8a7e;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5710)"
|
||||
d="m 274.53933,674.19203 c -31.92389,48.56808 -43.48293,40.68411 -98.97824,105.07044"
|
||||
id="path4202"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<g
|
||||
id="g4246"
|
||||
transform="translate(202.03051,369.71583)">
|
||||
<rect
|
||||
style="opacity:1;fill:#e1f5f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4188"
|
||||
width="210"
|
||||
height="80"
|
||||
x="-133.34013"
|
||||
y="420.81891" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4136"
|
||||
y="453.82062"
|
||||
x="-119.87822"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="453.82062"
|
||||
x="-119.87822"
|
||||
id="tspan4138"
|
||||
sodipodi:role="line">Espace couleur</tspan><tspan
|
||||
id="tspan4140"
|
||||
y="481.94562"
|
||||
x="-119.87822"
|
||||
sodipodi:role="line">de travail (WCS)</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4240"
|
||||
transform="translate(202.03051,368.70567)">
|
||||
<rect
|
||||
y="421.82907"
|
||||
x="136.37061"
|
||||
height="80"
|
||||
width="200"
|
||||
id="rect4190"
|
||||
style="opacity:1;fill:#e1f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4146"
|
||||
y="456.15463"
|
||||
x="154.52246"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4150"
|
||||
y="456.15463"
|
||||
x="154.52246"
|
||||
sodipodi:role="line">Profile ICC/ICM</tspan><tspan
|
||||
id="tspan4180"
|
||||
y="484.27963"
|
||||
x="154.52246"
|
||||
sodipodi:role="line">de sortie</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4234"
|
||||
transform="translate(202.03051,365.59396)">
|
||||
<rect
|
||||
y="235.96106"
|
||||
x="349.51279"
|
||||
height="80"
|
||||
width="200"
|
||||
id="rect4194"
|
||||
style="opacity:1;fill:#e1f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4152"
|
||||
y="270.28662"
|
||||
x="367.66464"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4156"
|
||||
y="270.28662"
|
||||
x="367.66464"
|
||||
sodipodi:role="line">Profile ICC/ICM</tspan><tspan
|
||||
id="tspan4178"
|
||||
y="298.41162"
|
||||
x="367.66464"
|
||||
sodipodi:role="line">du moniteur</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4257"
|
||||
transform="translate(202.03051,369.71583)">
|
||||
<rect
|
||||
y="231.83919"
|
||||
x="549.51282"
|
||||
height="80"
|
||||
width="150"
|
||||
id="rect4196"
|
||||
style="opacity:1;fill:#dcb7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4158"
|
||||
y="280.22723"
|
||||
x="573.45386"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="280.22723"
|
||||
x="573.45386"
|
||||
id="tspan4160"
|
||||
sodipodi:role="line">Moniteur</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g7175">
|
||||
<rect
|
||||
y="790.53473"
|
||||
x="813.17279"
|
||||
height="80"
|
||||
width="170"
|
||||
id="rect4198"
|
||||
style="opacity:1;fill:#dcb7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4162"
|
||||
y="836.742"
|
||||
x="832.14496"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="836.742"
|
||||
x="832.14496"
|
||||
id="tspan4164"
|
||||
sodipodi:role="line">Imprimante</tspan></text>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="548.02759"
|
||||
y="838.92279"
|
||||
id="text4170"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4172"
|
||||
x="548.02759"
|
||||
y="838.92279">Fichier de sortie</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="68.690376"
|
||||
y="990.74292"
|
||||
id="text4182"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4184"
|
||||
x="68.690376"
|
||||
y="990.74292">Epreuvage écran</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4204"
|
||||
y="557.82416"
|
||||
x="169.88316"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="557.82416"
|
||||
x="169.88316"
|
||||
id="tspan4206"
|
||||
sodipodi:role="line">options.rtSettings.HistogramWorking</tspan></text>
|
||||
<rect
|
||||
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4186"
|
||||
width="180"
|
||||
height="80"
|
||||
x="239.46707"
|
||||
y="601.55499" />
|
||||
<g
|
||||
id="g4220"
|
||||
transform="translate(202.46703,367.10444)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4142"
|
||||
y="271.17874"
|
||||
x="56.132729"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="271.17874"
|
||||
x="56.132729"
|
||||
id="tspan4144"
|
||||
sodipodi:role="line">Image L*a*b</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4214"
|
||||
y="291.69702"
|
||||
x="56.868813"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="291.69702"
|
||||
x="56.868813"
|
||||
id="tspan4216"
|
||||
sodipodi:role="line">Fin du pipeline</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4996"
|
||||
d="m 470.38637,792.93755 c -0.75841,-36.39289 70.13855,-39.54432 124.58385,-100.76784"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#439872;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:28,7;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker5062)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 17 KiB |
Loading…
x
Reference in New Issue
Block a user