Merge branch 'master' into gtk3
BIN
rtdata/images/Dark/actions/spGamutCheck.png
Normal file
After Width: | Height: | Size: 707 B |
BIN
rtdata/images/Dark/actions/unchanged-18.png
Normal file
After Width: | Height: | Size: 149 B |
BIN
rtdata/images/Dark/actions/unchanged-22.png
Normal file
After Width: | Height: | Size: 153 B |
BIN
rtdata/images/Light/actions/spGamutCheck.png
Normal file
After Width: | Height: | Size: 701 B |
BIN
rtdata/images/Light/actions/unchanged-18.png
Normal file
After Width: | Height: | Size: 149 B |
BIN
rtdata/images/Light/actions/unchanged-22.png
Normal file
After Width: | Height: | Size: 153 B |
@ -632,6 +632,7 @@ HISTORY_MSG_403;O - NB - Sensibilité des bords
|
|||||||
HISTORY_MSG_404;O - NB - Base amplification
|
HISTORY_MSG_404;O - NB - Base amplification
|
||||||
HISTORY_MSG_405;O - Débruitage - Niveau 4
|
HISTORY_MSG_405;O - Débruitage - Niveau 4
|
||||||
HISTORY_MSG_406;O - NB - Pixels voisins
|
HISTORY_MSG_406;O - NB - Pixels voisins
|
||||||
|
HISTORY_MSG_443;Compensation du Point Noir de Sortie
|
||||||
HISTORY_NEWSNAPSHOT;Ajouter
|
HISTORY_NEWSNAPSHOT;Ajouter
|
||||||
HISTORY_NEWSNAPSHOT_TOOLTIP;Raccourci: <b>Alt-s</b>
|
HISTORY_NEWSNAPSHOT_TOOLTIP;Raccourci: <b>Alt-s</b>
|
||||||
HISTORY_SNAPSHOT;Capture
|
HISTORY_SNAPSHOT;Capture
|
||||||
@ -953,6 +954,7 @@ PREFERENCES_MENUGROUPPROFILEOPERATIONS;Opérations sur les profils
|
|||||||
PREFERENCES_MENUGROUPRANK;Classement
|
PREFERENCES_MENUGROUPRANK;Classement
|
||||||
PREFERENCES_MENUOPTIONS;Options du menu
|
PREFERENCES_MENUOPTIONS;Options du menu
|
||||||
PREFERENCES_METADATA;Metadonnées
|
PREFERENCES_METADATA;Metadonnées
|
||||||
|
PREFERENCES_MONBPC;Compensation du Point Noir pour la transformation L*a*b*->Moniteur
|
||||||
PREFERENCES_MIN;Mini (100x115)
|
PREFERENCES_MIN;Mini (100x115)
|
||||||
PREFERENCES_MULTITAB;Éditeurs multiple
|
PREFERENCES_MULTITAB;Éditeurs multiple
|
||||||
PREFERENCES_MULTITABDUALMON;Éditeurs multiple, si possible sur un second moniteur
|
PREFERENCES_MULTITABDUALMON;Éditeurs multiple, si possible sur un second moniteur
|
||||||
@ -1083,6 +1085,8 @@ SAVEDLG_SUBSAMP_3;Meilleure qualité
|
|||||||
SAVEDLG_TIFFUNCOMPRESSED;TIFF non compressé
|
SAVEDLG_TIFFUNCOMPRESSED;TIFF non compressé
|
||||||
SAVEDLG_WARNFILENAME;Le fichier sera nommé
|
SAVEDLG_WARNFILENAME;Le fichier sera nommé
|
||||||
SHCSELECTOR_TOOLTIP;Cliquez le bouton droit de la souris\npour réinitialiser la position de ces 3 curseurs
|
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_B;Bas
|
||||||
THRESHOLDSELECTOR_BL;Bas-gauche
|
THRESHOLDSELECTOR_BL;Bas-gauche
|
||||||
THRESHOLDSELECTOR_BR;Bas-droite
|
THRESHOLDSELECTOR_BR;Bas-droite
|
||||||
@ -1456,6 +1460,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_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;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_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;Illuminant
|
||||||
TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolé
|
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.
|
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.
|
||||||
|
@ -674,6 +674,7 @@ HISTORY_MSG_439;Retinex - Process
|
|||||||
HISTORY_MSG_440;CbDL - Method
|
HISTORY_MSG_440;CbDL - Method
|
||||||
HISTORY_MSG_441;Retinex - Gain transmission
|
HISTORY_MSG_441;Retinex - Gain transmission
|
||||||
HISTORY_MSG_442;Retinex - Scale
|
HISTORY_MSG_442;Retinex - Scale
|
||||||
|
HISTORY_MSG_443;Output Black Point Compensation
|
||||||
HISTORY_NEWSNAPSHOT;Add
|
HISTORY_NEWSNAPSHOT;Add
|
||||||
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
|
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
|
||||||
HISTORY_SNAPSHOT;Snapshot
|
HISTORY_SNAPSHOT;Snapshot
|
||||||
@ -1000,6 +1001,7 @@ PREFERENCES_MENUGROUPRANK;Group "Rank"
|
|||||||
PREFERENCES_MENUOPTIONS;Context Menu Options
|
PREFERENCES_MENUOPTIONS;Context Menu Options
|
||||||
PREFERENCES_METADATA;Metadata
|
PREFERENCES_METADATA;Metadata
|
||||||
PREFERENCES_MIN;Mini (100x115)
|
PREFERENCES_MIN;Mini (100x115)
|
||||||
|
PREFERENCES_MONBPC;Black Point Compensation for the L*a*b*->Monitor transform
|
||||||
PREFERENCES_MONINTENT;Default monitor intent
|
PREFERENCES_MONINTENT;Default monitor intent
|
||||||
PREFERENCES_MONPROFILE;Default monitor profile
|
PREFERENCES_MONPROFILE;Default monitor profile
|
||||||
PREFERENCES_MULTITAB;Multiple Editor Tabs Mode
|
PREFERENCES_MULTITAB;Multiple Editor Tabs Mode
|
||||||
@ -1136,6 +1138,8 @@ SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved h
|
|||||||
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
|
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
|
||||||
SAVEDLG_WARNFILENAME;File will be named
|
SAVEDLG_WARNFILENAME;File will be named
|
||||||
SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders.
|
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_B;Bottom
|
||||||
THRESHOLDSELECTOR_BL;Bottom-left
|
THRESHOLDSELECTOR_BL;Bottom-left
|
||||||
THRESHOLDSELECTOR_BR;Bottom-right
|
THRESHOLDSELECTOR_BR;Bottom-right
|
||||||
@ -1523,6 +1527,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_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;Blend ICC highlights with matrix
|
||||||
TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles.
|
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;Illuminant
|
||||||
TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated
|
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.
|
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.
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
#include "cplx_wavelet_dec.h"
|
#include "cplx_wavelet_dec.h"
|
||||||
#include "median.h"
|
#include "median.h"
|
||||||
|
#include "iccstore.h"
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "mytime.h"
|
#include "mytime.h"
|
||||||
#include "sleef.c"
|
#include "sleef.c"
|
||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
|
#include "iccstore.h"
|
||||||
|
|
||||||
#define pow_F(a,b) (xexpf(b*xlogf(a)))
|
#define pow_F(a,b) (xexpf(b*xlogf(a)))
|
||||||
|
|
||||||
@ -1647,7 +1648,7 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg
|
|||||||
Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut
|
Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut
|
||||||
}
|
}
|
||||||
|
|
||||||
void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5)
|
void Color::calcGamma (double pwr, double ts, int mode, int imax, GammaValues &gamma)
|
||||||
{
|
{
|
||||||
//from Dcraw (D.Coffin)
|
//from Dcraw (D.Coffin)
|
||||||
int i;
|
int i;
|
||||||
@ -1683,12 +1684,13 @@ void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mode--) {
|
if (!mode--) {
|
||||||
gamma0 = g[0];
|
gamma[0] = g[0];
|
||||||
gamma1 = g[1];
|
gamma[1] = g[1];
|
||||||
gamma2 = g[2];
|
gamma[2] = g[2];
|
||||||
gamma3 = g[3];
|
gamma[3] = g[3];
|
||||||
gamma4 = g[4];
|
gamma[4] = g[4];
|
||||||
gamma5 = g[5];
|
gamma[5] = g[5];
|
||||||
|
gamma[6] = 0.;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
#include "LUT.h"
|
#include "LUT.h"
|
||||||
#include "labimage.h"
|
#include "labimage.h"
|
||||||
#include "iccstore.h"
|
|
||||||
#include "iccmatrices.h"
|
#include "iccmatrices.h"
|
||||||
#include "sleef.c"
|
#include "sleef.c"
|
||||||
#define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c)
|
#define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c)
|
||||||
@ -31,6 +30,8 @@
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
typedef std::array<double, 7> GammaValues;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
||||||
class MunsellDebugInfo
|
class MunsellDebugInfo
|
||||||
@ -47,6 +48,7 @@ public:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class Color
|
class Color
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -880,21 +882,21 @@ public:
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the gamma curves' parameters used by LCMS2
|
* @brief Get the gamma curves' parameters used by LCMS2
|
||||||
* @param pwr gamma value [>1]
|
* @param pwr gamma value [>1]
|
||||||
* @param ts slope [0 ; 20]
|
* @param ts slope [0 ; 20]
|
||||||
* @param mode [always 0]
|
* @param mode [always 0]
|
||||||
* @imax imax [always 0]
|
* @imax imax [always 0]
|
||||||
* @param gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
|
* @param gamma a pointer to an array of 6 double gamma values:
|
||||||
* @param gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value)
|
* gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
|
||||||
* @param gamma2 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
|
* gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value)
|
||||||
* @param gamma3 used in ip2Lab2rgb [0 ; 1], usually near 0.003(return value)
|
* gamma2 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
|
||||||
* @param gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
|
* gamma3 used in ip2Lab2rgb [0 ; 1], usually near 0.003(return value)
|
||||||
* @param gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
|
* gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
|
||||||
|
* gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
|
||||||
*/
|
*/
|
||||||
static void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5);
|
static void calcGamma (double pwr, double ts, int mode, int imax, GammaValues &gamma);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
#include "ciecam02.h"
|
#include "ciecam02.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
#include "iccstore.h"
|
||||||
#undef CLIPD
|
#undef CLIPD
|
||||||
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
|
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
|
||||||
|
|
||||||
|
@ -962,24 +962,14 @@ void Crop::update (int todo)
|
|||||||
// all pipette buffer processing should be finished now
|
// all pipette buffer processing should be finished now
|
||||||
PipetteBuffer::setReady();
|
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);
|
parent->ipf.lab2monitorRgb (labnCrop, cropImg);
|
||||||
|
|
||||||
if (cropImageListener) {
|
if (cropImageListener) {
|
||||||
// this in output space held in parallel to allow analysis like shadow/highlight
|
// Computing the internal image for analysis, i.e. conversion from lab->Output profile (rtSettings.HistogramWorking disabled) or lab->WCS (rtSettings.HistogramWorking enabled)
|
||||||
Glib::ustring outProfile = params.icm.output;
|
|
||||||
Glib::ustring workProfile = params.icm.working;
|
|
||||||
Image8 *cropImgtrue;
|
|
||||||
|
|
||||||
if(settings->HistogramWorking) {
|
// internal image in output color space for analysis
|
||||||
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 ?
|
Image8 *cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, params.icm);
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
int finalW = rqcropw;
|
int finalW = rqcropw;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ protected:
|
|||||||
Imagefloat* origCrop; // "one chunk" allocation
|
Imagefloat* origCrop; // "one chunk" allocation
|
||||||
LabImage* laboCrop; // "one chunk" allocation
|
LabImage* laboCrop; // "one chunk" allocation
|
||||||
LabImage* labnCrop; // "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
|
float * cbuf_real; // "one chunk" allocation
|
||||||
SHMap* cshmap; // per line allocation
|
SHMap* cshmap; // per line allocation
|
||||||
|
|
||||||
|
@ -32,14 +32,15 @@
|
|||||||
|
|
||||||
#include "../rtgui/options.h"
|
#include "../rtgui/options.h"
|
||||||
|
|
||||||
namespace
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
extern const Settings* settings;
|
||||||
|
|
||||||
void loadProfiles (const Glib::ustring& dirName,
|
void loadProfiles (const Glib::ustring& dirName,
|
||||||
std::map<Glib::ustring, cmsHPROFILE>* profiles,
|
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,
|
std::map<Glib::ustring, Glib::ustring>* profileNames,
|
||||||
bool nameUpper, bool onlyRgb)
|
bool nameUpper)
|
||||||
{
|
{
|
||||||
if (dirName.empty ()) {
|
if (dirName.empty ()) {
|
||||||
return;
|
return;
|
||||||
@ -76,10 +77,10 @@ void loadProfiles (const Glib::ustring& dirName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (profiles) {
|
if (profiles) {
|
||||||
const rtengine::ProfileContent content (filePath);
|
const ProfileContent content (filePath);
|
||||||
const cmsHPROFILE profile = content.toProfile ();
|
const cmsHPROFILE profile = content.toProfile ();
|
||||||
|
|
||||||
if (profile && (!onlyRgb || cmsGetColorSpace (profile) == cmsSigRgbData)) {
|
if (profile) {
|
||||||
profiles->insert (std::make_pair (name, profile));
|
profiles->insert (std::make_pair (name, profile));
|
||||||
|
|
||||||
if (profileContents) {
|
if (profileContents) {
|
||||||
@ -95,20 +96,20 @@ void loadProfiles (const Glib::ustring& dirName,
|
|||||||
} catch (Glib::Exception&) {}
|
} catch (Glib::Exception&) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, std::uint8_t& result)
|
inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, uint8_t& result)
|
||||||
{
|
{
|
||||||
if (cmsIsIntentSupported (profile, intent, direction)) {
|
if (cmsIsIntentSupported (profile, intent, direction)) {
|
||||||
result |= 1 << intent;
|
result |= 1 << intent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction)
|
inline uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction)
|
||||||
{
|
{
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t result = 0;
|
uint8_t result = 0;
|
||||||
|
|
||||||
getSupportedIntent (profile, INTENT_PERCEPTUAL, direction, result);
|
getSupportedIntent (profile, INTENT_PERCEPTUAL, direction, result);
|
||||||
getSupportedIntent (profile, INTENT_RELATIVE_COLORIMETRIC, direction, result);
|
getSupportedIntent (profile, INTENT_RELATIVE_COLORIMETRIC, direction, result);
|
||||||
@ -121,7 +122,7 @@ inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number di
|
|||||||
inline cmsHPROFILE createXYZProfile ()
|
inline cmsHPROFILE createXYZProfile ()
|
||||||
{
|
{
|
||||||
double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0} };
|
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};
|
const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best, xyz_rec2020};
|
||||||
@ -164,7 +165,7 @@ std::vector<Glib::ustring> getWorkingProfiles ()
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Glib::ustring> ICCStore::getProfiles () const
|
std::vector<Glib::ustring> ICCStore::getProfiles (const bool onlyRgb) const
|
||||||
{
|
{
|
||||||
|
|
||||||
MyMutex::MyLock lock (mutex_);
|
MyMutex::MyLock lock (mutex_);
|
||||||
@ -172,6 +173,7 @@ std::vector<Glib::ustring> ICCStore::getProfiles () const
|
|||||||
std::vector<Glib::ustring> res;
|
std::vector<Glib::ustring> res;
|
||||||
|
|
||||||
for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) {
|
for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) {
|
||||||
|
if (!onlyRgb || (onlyRgb && cmsGetColorSpace (profile->second) == cmsSigRgbData))
|
||||||
res.push_back (profile->first);
|
res.push_back (profile->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +189,8 @@ std::vector<Glib::ustring> ICCStore::getProfilesFromDir (const Glib::ustring& di
|
|||||||
|
|
||||||
ProfileMap profiles;
|
ProfileMap profiles;
|
||||||
|
|
||||||
loadProfiles (profilesDir, &profiles, NULL, NULL, false, true);
|
loadProfiles (profilesDir, &profiles, nullptr, nullptr, false);
|
||||||
loadProfiles (dirName, &profiles, NULL, NULL, false, true);
|
loadProfiles (dirName, &profiles, nullptr, nullptr, false);
|
||||||
|
|
||||||
for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) {
|
for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) {
|
||||||
res.push_back (profile->first);
|
res.push_back (profile->first);
|
||||||
@ -201,14 +203,14 @@ cmsHPROFILE ICCStore::makeStdGammaProfile (cmsHPROFILE iprof)
|
|||||||
{
|
{
|
||||||
// forgive me for the messy code, quick hack to change gamma of an ICC profile to the RT standard gamma
|
// forgive me for the messy code, quick hack to change gamma of an ICC profile to the RT standard gamma
|
||||||
if (!iprof) {
|
if (!iprof) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsUInt32Number bytesNeeded = 0;
|
cmsUInt32Number bytesNeeded = 0;
|
||||||
cmsSaveProfileToMem (iprof, 0, &bytesNeeded);
|
cmsSaveProfileToMem (iprof, 0, &bytesNeeded);
|
||||||
|
|
||||||
if (bytesNeeded == 0) {
|
if (bytesNeeded == 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *data = new uint8_t[bytesNeeded + 1];
|
uint8_t *data = new uint8_t[bytesNeeded + 1];
|
||||||
@ -362,6 +364,312 @@ cmsHPROFILE ICCStore::workingSpaceGamma (const Glib::ustring& name) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ICCStore::getGammaArray(const procparams::ColorManagementParams &icm, GammaValues &ga)
|
||||||
|
{
|
||||||
|
const double eps = 0.000000001; // not divide by zero
|
||||||
|
if (!icm.freegamma) {//if Free gamma not selected
|
||||||
|
// gamma : ga[0],ga[1],ga[2],ga[3],ga[4],ga[5] by calcul
|
||||||
|
if(icm.gamma == "BT709_g2.2_s4.5") {
|
||||||
|
ga[0] = 2.22; //BT709 2.2 4.5 - my preferred as D.Coffin
|
||||||
|
ga[1] = 0.909995;
|
||||||
|
ga[2] = 0.090005;
|
||||||
|
ga[3] = 0.222222;
|
||||||
|
ga[4] = 0.081071;
|
||||||
|
} 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;
|
||||||
|
} 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;
|
||||||
|
} 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;
|
||||||
|
} 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.;
|
||||||
|
} 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.;
|
||||||
|
} else /* if (icm.gamma == "linear_g1.0") */ {
|
||||||
|
ga[0] = 1.0; //gamma=1 linear : for high dynamic images (cf : D.Coffin...)
|
||||||
|
ga[1] = 1.;
|
||||||
|
ga[2] = 0.;
|
||||||
|
ga[3] = 1. / eps;
|
||||||
|
ga[4] = 0.;
|
||||||
|
}
|
||||||
|
ga[5] = 0.0;
|
||||||
|
ga[6] = 0.0;
|
||||||
|
} else { //free gamma selected
|
||||||
|
GammaValues g_a; //gamma parameters
|
||||||
|
double pwr = 1.0 / icm.gampos;
|
||||||
|
double ts = icm.slpos;
|
||||||
|
double slope = icm.slpos == 0 ? eps : icm.slpos;
|
||||||
|
|
||||||
|
int mode = 0, imax = 0;
|
||||||
|
Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
|
||||||
|
ga[4] = g_a[3] * ts;
|
||||||
|
//printf("g_a.gamma0=%f g_a.gamma1=%f g_a.gamma2=%f g_a.gamma3=%f g_a.gamma4=%f\n", g_a.gamma0,g_a.gamma1,g_a.gamma2,g_a.gamma3,g_a.gamma4);
|
||||||
|
ga[0] = icm.gampos;
|
||||||
|
ga[1] = 1. / (1.0 + g_a[4]);
|
||||||
|
ga[2] = g_a[4] / (1.0 + g_a[4]);
|
||||||
|
ga[3] = 1. / slope;
|
||||||
|
ga[5] = 0.0;
|
||||||
|
ga[6] = 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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: the caller must lock lcmsMutex
|
||||||
|
cmsHPROFILE ICCStore::createGammaProfile (const procparams::ColorManagementParams &icm, GammaValues &ga) {
|
||||||
|
float p[6]; //primaries
|
||||||
|
ga[6] = 0.0;
|
||||||
|
|
||||||
|
enum class ColorTemp {
|
||||||
|
D50 = 5003, // for Widegamut, Prophoto Best, Beta -> D50
|
||||||
|
D65 = 6504 // for sRGB, AdobeRGB, Bruce Rec2020 -> D65
|
||||||
|
};
|
||||||
|
ColorTemp temp = ColorTemp::D50;
|
||||||
|
|
||||||
|
//primaries for 7 working profiles ==> output profiles
|
||||||
|
// eventually to adapt primaries if RT used special profiles !
|
||||||
|
if (icm.output == "WideGamut") {
|
||||||
|
p[0] = 0.7350; //Widegamut primaries
|
||||||
|
p[1] = 0.2650;
|
||||||
|
p[2] = 0.1150;
|
||||||
|
p[3] = 0.8260;
|
||||||
|
p[4] = 0.1570;
|
||||||
|
p[5] = 0.0180;
|
||||||
|
} else if (icm.output == "Adobe RGB") {
|
||||||
|
p[0] = 0.6400; //Adobe primaries
|
||||||
|
p[1] = 0.3300;
|
||||||
|
p[2] = 0.2100;
|
||||||
|
p[3] = 0.7100;
|
||||||
|
p[4] = 0.1500;
|
||||||
|
p[5] = 0.0600;
|
||||||
|
temp = ColorTemp::D65;
|
||||||
|
} else if (icm.output == "sRGB") {
|
||||||
|
p[0] = 0.6400; // sRGB primaries
|
||||||
|
p[1] = 0.3300;
|
||||||
|
p[2] = 0.3000;
|
||||||
|
p[3] = 0.6000;
|
||||||
|
p[4] = 0.1500;
|
||||||
|
p[5] = 0.0600;
|
||||||
|
temp = ColorTemp::D65;
|
||||||
|
} else if (icm.output == "BruceRGB") {
|
||||||
|
p[0] = 0.6400; // Bruce primaries
|
||||||
|
p[1] = 0.3300;
|
||||||
|
p[2] = 0.2800;
|
||||||
|
p[3] = 0.6500;
|
||||||
|
p[4] = 0.1500;
|
||||||
|
p[5] = 0.0600;
|
||||||
|
temp = ColorTemp::D65;
|
||||||
|
} else if (icm.output == "Beta RGB") {
|
||||||
|
p[0] = 0.6888; // Beta primaries
|
||||||
|
p[1] = 0.3112;
|
||||||
|
p[2] = 0.1986;
|
||||||
|
p[3] = 0.7551;
|
||||||
|
p[4] = 0.1265;
|
||||||
|
p[5] = 0.0352;
|
||||||
|
} else if (icm.output == "BestRGB") {
|
||||||
|
p[0] = 0.7347; // Best primaries
|
||||||
|
p[1] = 0.2653;
|
||||||
|
p[2] = 0.2150;
|
||||||
|
p[3] = 0.7750;
|
||||||
|
p[4] = 0.1300;
|
||||||
|
p[5] = 0.0350;
|
||||||
|
} else if (icm.output == "Rec2020") {
|
||||||
|
p[0] = 0.7080; // Rec2020 primaries
|
||||||
|
p[1] = 0.2920;
|
||||||
|
p[2] = 0.1700;
|
||||||
|
p[3] = 0.7970;
|
||||||
|
p[4] = 0.1310;
|
||||||
|
p[5] = 0.0460;
|
||||||
|
temp = ColorTemp::D65;
|
||||||
|
} else {
|
||||||
|
p[0] = 0.7347; //ProPhoto and default primaries
|
||||||
|
p[1] = 0.2653;
|
||||||
|
p[2] = 0.1596;
|
||||||
|
p[3] = 0.8404;
|
||||||
|
p[4] = 0.0366;
|
||||||
|
p[5] = 0.0001;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmsCIExyY xyD;
|
||||||
|
cmsCIExyYTRIPLE Primaries = {
|
||||||
|
{p[0], p[1], 1.0}, // red
|
||||||
|
{p[2], p[3], 1.0}, // green
|
||||||
|
{p[4], p[5], 1.0} // blue
|
||||||
|
};
|
||||||
|
cmsToneCurve* GammaTRC[3];
|
||||||
|
|
||||||
|
// 7 parameters for smoother curves
|
||||||
|
cmsFloat64Number Parameters[7] = { ga[0], ga[1], ga[2], ga[3], ga[4], ga[5], ga[6] } ;
|
||||||
|
|
||||||
|
//lcmsMutex->lock (); Mutex acquired by the caller
|
||||||
|
cmsWhitePointFromTemp(&xyD, (double)temp);
|
||||||
|
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters); //5 = smoother than 4
|
||||||
|
cmsHPROFILE oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC); //oprofdef become Outputprofile
|
||||||
|
cmsFreeToneCurve(GammaTRC[0]);
|
||||||
|
//lcmsMutex->unlock ();
|
||||||
|
|
||||||
|
return oprofdef;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: the caller must lock lcmsMutex
|
||||||
|
cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, GammaValues &ga) {
|
||||||
|
bool pro = false;
|
||||||
|
Glib::ustring outProfile;
|
||||||
|
cmsHPROFILE outputProfile = nullptr;
|
||||||
|
|
||||||
|
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 nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//begin adaptation rTRC gTRC bTRC
|
||||||
|
//"outputProfile" profile has the same characteristics than RGB values, but TRC are adapted... for applying profile
|
||||||
|
if (settings->verbose) {
|
||||||
|
printf("Output Gamma - profile: \"%s\"\n", outProfile.c_str() ); //c_str()
|
||||||
|
}
|
||||||
|
|
||||||
|
outputProfile = iccStore->getProfile(outProfile); //get output profile
|
||||||
|
|
||||||
|
if (outputProfile == nullptr) {
|
||||||
|
|
||||||
|
if (settings->verbose) {
|
||||||
|
printf("\"%s\" ICC output profile not found!\n", outProfile.c_str());
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 == nullptr) {
|
||||||
|
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 = nullptr;
|
||||||
|
GammaTRC = cmsBuildParametricToneCurve(nullptr, 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_);
|
||||||
|
return fileProfiles.find(name) != fileProfiles.end();
|
||||||
|
}
|
||||||
|
|
||||||
cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const
|
cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -407,7 +715,7 @@ cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const
|
|||||||
|
|
||||||
// profile does not exist
|
// profile does not exist
|
||||||
if (f == fileStdProfilesFileNames.end ()) {
|
if (f == fileStdProfilesFileNames.end ()) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// but there exists one => load it
|
// but there exists one => load it
|
||||||
@ -433,21 +741,21 @@ ProfileContent ICCStore::getContent (const Glib::ustring& name) const
|
|||||||
return r != fileProfileContents.end () ? r->second : ProfileContent();
|
return r != fileProfileContents.end () ? r->second : ProfileContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const
|
uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const
|
||||||
{
|
{
|
||||||
MyMutex::MyLock lock (mutex_);
|
MyMutex::MyLock lock (mutex_);
|
||||||
|
|
||||||
return getSupportedIntents (profile, LCMS_USED_AS_INPUT);
|
return getSupportedIntents (profile, LCMS_USED_AS_INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const
|
uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const
|
||||||
{
|
{
|
||||||
MyMutex::MyLock lock (mutex_);
|
MyMutex::MyLock lock (mutex_);
|
||||||
|
|
||||||
return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT);
|
return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const
|
uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const
|
||||||
{
|
{
|
||||||
MyMutex::MyLock lock (mutex_);
|
MyMutex::MyLock lock (mutex_);
|
||||||
|
|
||||||
@ -464,15 +772,15 @@ void ICCStore::init (const Glib::ustring& usrICCDir, const Glib::ustring& rtICCD
|
|||||||
profilesDir = Glib::build_filename (rtICCDir, "output");
|
profilesDir = Glib::build_filename (rtICCDir, "output");
|
||||||
fileProfiles.clear();
|
fileProfiles.clear();
|
||||||
fileProfileContents.clear();
|
fileProfileContents.clear();
|
||||||
loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, NULL, false, true);
|
loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, nullptr, false);
|
||||||
loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, NULL, false, true);
|
loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, nullptr, false);
|
||||||
|
|
||||||
// Input profiles
|
// Input profiles
|
||||||
// Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir)
|
// Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir)
|
||||||
stdProfilesDir = Glib::build_filename (rtICCDir, "input");
|
stdProfilesDir = Glib::build_filename (rtICCDir, "input");
|
||||||
fileStdProfiles.clear();
|
fileStdProfiles.clear();
|
||||||
fileStdProfilesFileNames.clear();
|
fileStdProfilesFileNames.clear();
|
||||||
loadProfiles (stdProfilesDir, NULL, NULL, &fileStdProfilesFileNames, true, false);
|
loadProfiles (stdProfilesDir, nullptr, nullptr, &fileStdProfilesFileNames, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the first monitor default profile of operating system, if selected
|
// Determine the first monitor default profile of operating system, if selected
|
||||||
@ -515,7 +823,7 @@ void ICCStore::findDefaultMonitorProfile ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileContent::ProfileContent (const Glib::ustring& fileName) : data (NULL), length (0)
|
ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(nullptr), length(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
FILE* f = g_fopen (fileName.c_str (), "rb");
|
FILE* f = g_fopen (fileName.c_str (), "rb");
|
||||||
@ -542,14 +850,14 @@ ProfileContent::ProfileContent (const ProfileContent& other)
|
|||||||
data = new char[length + 1];
|
data = new char[length + 1];
|
||||||
memcpy (data, other.data, length + 1);
|
memcpy (data, other.data, length + 1);
|
||||||
} else {
|
} else {
|
||||||
data = NULL;
|
data = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileContent::ProfileContent (cmsHPROFILE hProfile) : data (NULL), length (0)
|
ProfileContent::ProfileContent (cmsHPROFILE hProfile) : data(nullptr), length(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (hProfile != NULL) {
|
if (hProfile != nullptr) {
|
||||||
cmsUInt32Number bytesNeeded = 0;
|
cmsUInt32Number bytesNeeded = 0;
|
||||||
cmsSaveProfileToMem (hProfile, 0, &bytesNeeded);
|
cmsSaveProfileToMem (hProfile, 0, &bytesNeeded);
|
||||||
|
|
||||||
@ -573,7 +881,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other)
|
|||||||
data = new char[length + 1];
|
data = new char[length + 1];
|
||||||
memcpy (data, other.data, length + 1);
|
memcpy (data, other.data, length + 1);
|
||||||
} else {
|
} else {
|
||||||
data = NULL;
|
data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -585,7 +893,7 @@ cmsHPROFILE ProfileContent::toProfile () const
|
|||||||
if (data) {
|
if (data) {
|
||||||
return cmsOpenProfileFromMem (data, length);
|
return cmsOpenProfileFromMem (data, length);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
#include "procparams.h"
|
||||||
|
#include "color.h"
|
||||||
#include "../rtgui/threadutils.h"
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
@ -85,8 +88,11 @@ public:
|
|||||||
|
|
||||||
void init (const Glib::ustring& usrICCDir, const Glib::ustring& stdICCDir);
|
void init (const Glib::ustring& usrICCDir, const Glib::ustring& stdICCDir);
|
||||||
|
|
||||||
|
static void getGammaArray(const procparams::ColorManagementParams &icm, GammaValues &ga);
|
||||||
static cmsHPROFILE makeStdGammaProfile (cmsHPROFILE iprof);
|
static cmsHPROFILE makeStdGammaProfile (cmsHPROFILE iprof);
|
||||||
static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring());
|
static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring());
|
||||||
|
static cmsHPROFILE createGammaProfile (const procparams::ColorManagementParams &icm, GammaValues &ga);
|
||||||
|
static cmsHPROFILE createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, GammaValues &ga);
|
||||||
|
|
||||||
// Main monitors standard profile name, from OS
|
// Main monitors standard profile name, from OS
|
||||||
void findDefaultMonitorProfile ();
|
void findDefaultMonitorProfile ();
|
||||||
@ -98,29 +104,30 @@ public:
|
|||||||
TMatrix workingSpaceMatrix (const Glib::ustring& name) const;
|
TMatrix workingSpaceMatrix (const Glib::ustring& name) const;
|
||||||
TMatrix workingSpaceInverseMatrix (const Glib::ustring& name) const;
|
TMatrix workingSpaceInverseMatrix (const Glib::ustring& name) const;
|
||||||
|
|
||||||
cmsHPROFILE getProfile (const Glib::ustring& name) const;
|
bool outputProfileExist (const Glib::ustring& name) const;
|
||||||
cmsHPROFILE getStdProfile (const Glib::ustring& name) const;
|
cmsHPROFILE getProfile (const Glib::ustring& name) const;
|
||||||
ProfileContent getContent (const Glib::ustring& name) const;
|
cmsHPROFILE getStdProfile (const Glib::ustring& name) const;
|
||||||
|
ProfileContent getContent (const Glib::ustring& name) const;
|
||||||
|
|
||||||
cmsHPROFILE getXYZProfile () const;
|
cmsHPROFILE getXYZProfile () const;
|
||||||
cmsHPROFILE getsRGBProfile () const;
|
cmsHPROFILE getsRGBProfile () const;
|
||||||
|
|
||||||
std::vector<Glib::ustring> getProfiles () const;
|
std::vector<Glib::ustring> getProfiles (const bool onlyRgb = false) const;
|
||||||
std::vector<Glib::ustring> getProfilesFromDir (const Glib::ustring& dirName) const;
|
std::vector<Glib::ustring> getProfilesFromDir (const Glib::ustring& dirName) const;
|
||||||
|
|
||||||
std::uint8_t getInputIntents (cmsHPROFILE profile) const;
|
uint8_t getInputIntents (cmsHPROFILE profile) const;
|
||||||
std::uint8_t getOutputIntents (cmsHPROFILE profile) const;
|
uint8_t getOutputIntents (cmsHPROFILE profile) const;
|
||||||
std::uint8_t getProofIntents (cmsHPROFILE profile) const;
|
uint8_t getProofIntents (cmsHPROFILE profile) const;
|
||||||
|
|
||||||
std::uint8_t getInputIntents (const Glib::ustring& name) const;
|
uint8_t getInputIntents (const Glib::ustring& name) const;
|
||||||
std::uint8_t getOutputIntents (const Glib::ustring& name) const;
|
uint8_t getOutputIntents (const Glib::ustring& name) const;
|
||||||
std::uint8_t getProofIntents (const Glib::ustring& name) const;
|
uint8_t getProofIntents (const Glib::ustring& name) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define iccStore ICCStore::getInstance()
|
#define iccStore ICCStore::getInstance()
|
||||||
|
|
||||||
inline ProfileContent::ProfileContent () :
|
inline ProfileContent::ProfileContent () :
|
||||||
data(NULL),
|
data(nullptr),
|
||||||
length(0)
|
length(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -140,17 +147,17 @@ inline Glib::ustring ICCStore::getDefaultMonitorProfileName () const
|
|||||||
return defaultMonitorProfile;
|
return defaultMonitorProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const
|
inline uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const
|
||||||
{
|
{
|
||||||
return getInputIntents (getProfile (name));
|
return getInputIntents (getProfile (name));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const
|
inline uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const
|
||||||
{
|
{
|
||||||
return getOutputIntents (getProfile (name));
|
return getOutputIntents (getProfile (name));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const
|
inline uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const
|
||||||
{
|
{
|
||||||
return getProofIntents (getProfile (name));
|
return getProofIntents (getProfile (name));
|
||||||
}
|
}
|
||||||
|
@ -326,43 +326,48 @@ Image16::tofloat()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parallized transformation; create transform with cmsFLAGS_NOCACHE!
|
// Parallized transformation; create transform with cmsFLAGS_NOCACHE!
|
||||||
void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform)
|
void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage, int cx, int cy)
|
||||||
{
|
{
|
||||||
//cmsDoTransform(hTransform, data, data, planestride);
|
// LittleCMS cannot parallelize planar Lab float images
|
||||||
|
|
||||||
// LittleCMS cannot parallelize planar setups -- Hombre: LCMS2.4 can! But it we use this new feature, memory allocation have to be modified too
|
|
||||||
// so build temporary buffers to allow multi processor execution
|
// so build temporary buffers to allow multi processor execution
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
AlignedBuffer<unsigned short> buffer(width * 3);
|
AlignedBuffer<float> bufferLab(width * 3);
|
||||||
|
AlignedBuffer<unsigned short> bufferRGB(width * 3);
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp for schedule(static)
|
#pragma omp for schedule(static)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = cy; y < cy + 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] + cx;
|
||||||
|
pa = labImage.a[y] + cx;
|
||||||
|
pb = labImage.b[y] + cx;
|
||||||
|
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
*(p++) = *(pR++);
|
*(pLab++) = *(pL++) / 327.68f;
|
||||||
*(p++) = *(pG++);
|
*(pLab++) = *(pa++) / 327.68f;
|
||||||
*(p++) = *(pB++);
|
*(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);
|
pR = r(y - cy);
|
||||||
pG = g(y);
|
pG = g(y - cy);
|
||||||
pB = b(y);
|
pB = b(y - cy);
|
||||||
|
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
*(pR++) = *(p++);
|
*(pR++) = *(pRGB++);
|
||||||
*(pG++) = *(p++);
|
*(pG++) = *(pRGB++);
|
||||||
*(pB++) = *(p++);
|
*(pB++) = *(pRGB++);
|
||||||
}
|
}
|
||||||
} // End of parallelization
|
} // End of parallelization
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecCMSTransform(cmsHTRANSFORM hTransform);
|
void ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage, int cx, int cy);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -771,39 +771,39 @@ int ImageIO::loadTIFF (Glib::ustring fname)
|
|||||||
* We could use the min/max values set in TIFFTAG_SMINSAMPLEVALUE and
|
* We could use the min/max values set in TIFFTAG_SMINSAMPLEVALUE and
|
||||||
* TIFFTAG_SMAXSAMPLEVALUE, but for now, we normalize the image to the
|
* TIFFTAG_SMAXSAMPLEVALUE, but for now, we normalize the image to the
|
||||||
* effective minimum and maximum values
|
* effective minimum and maximum values
|
||||||
*
|
*/
|
||||||
printf("Informations de \"%s\":\n", fname.c_str());
|
if (options.rtSettings.verbose) {
|
||||||
uint16 tiffDefaultScale, tiffBaselineExposure, tiffLinearResponseLimit;
|
printf("Informations of \"%s\":\n", fname.c_str());
|
||||||
if (TIFFGetField(in, TIFFTAG_DEFAULTSCALE, &tiffDefaultScale)) {
|
uint16 tiffDefaultScale, tiffBaselineExposure, tiffLinearResponseLimit;
|
||||||
printf(" DefaultScale: %d\n", tiffDefaultScale);
|
if (TIFFGetField(in, TIFFTAG_DEFAULTSCALE, &tiffDefaultScale)) {
|
||||||
}
|
printf(" DefaultScale: %d\n", tiffDefaultScale);
|
||||||
else
|
}
|
||||||
printf(" No DefaultScale value!\n");
|
else
|
||||||
if (TIFFGetField(in, TIFFTAG_BASELINEEXPOSURE, &tiffBaselineExposure)) {
|
printf(" No DefaultScale value!\n");
|
||||||
printf(" BaselineExposure: %d\n", tiffBaselineExposure);
|
if (TIFFGetField(in, TIFFTAG_BASELINEEXPOSURE, &tiffBaselineExposure)) {
|
||||||
}
|
printf(" BaselineExposure: %d\n", tiffBaselineExposure);
|
||||||
else
|
}
|
||||||
printf(" No BaselineExposure value!\n");
|
else
|
||||||
if (TIFFGetField(in, TIFFTAG_LINEARRESPONSELIMIT, &tiffLinearResponseLimit)) {
|
printf(" No BaselineExposure value!\n");
|
||||||
printf(" LinearResponseLimit: %d\n", tiffLinearResponseLimit);
|
if (TIFFGetField(in, TIFFTAG_LINEARRESPONSELIMIT, &tiffLinearResponseLimit)) {
|
||||||
}
|
printf(" LinearResponseLimit: %d\n", tiffLinearResponseLimit);
|
||||||
else
|
}
|
||||||
printf(" No LinearResponseLimit value!\n");
|
else
|
||||||
|
printf(" No LinearResponseLimit value!\n");
|
||||||
|
|
||||||
uint16 tiffMinValue, tiffMaxValue;
|
uint16 tiffMinValue, tiffMaxValue;
|
||||||
if (TIFFGetField(in, TIFFTAG_SMINSAMPLEVALUE, &tiffMinValue)) {
|
if (TIFFGetField(in, TIFFTAG_SMINSAMPLEVALUE, &tiffMinValue)) {
|
||||||
printf(" MinValue: %d\n", tiffMinValue);
|
printf(" MinValue: %d\n", tiffMinValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf(" No minimum value!\n");
|
||||||
|
if (TIFFGetField(in, TIFFTAG_SMAXSAMPLEVALUE, &tiffMaxValue)) {
|
||||||
|
printf(" MaxValue: %d\n\n", tiffMaxValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf(" No maximum value!\n\n");
|
||||||
|
printf(" Those values are not taken into account, the image data are normalized to a [0;1] range\n\n");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
printf(" No minimum value!\n");
|
|
||||||
if (TIFFGetField(in, TIFFTAG_SMAXSAMPLEVALUE, &tiffMaxValue)) {
|
|
||||||
printf(" MaxValue: %d\n\n", tiffMaxValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf(" No maximum value!\n\n");
|
|
||||||
printf("\n");
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
char* profdata;
|
char* profdata;
|
||||||
deleteLoadedProfileData();
|
deleteLoadedProfileData();
|
||||||
@ -811,30 +811,8 @@ int ImageIO::loadTIFF (Glib::ustring fname)
|
|||||||
|
|
||||||
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &loadedProfileLength, &profdata)) {
|
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &loadedProfileLength, &profdata)) {
|
||||||
embProfile = cmsOpenProfileFromMem (profdata, loadedProfileLength);
|
embProfile = cmsOpenProfileFromMem (profdata, loadedProfileLength);
|
||||||
|
loadedProfileData = new char [loadedProfileLength];
|
||||||
// For 32 bits floating point images, gamma is forced to linear in embedded ICC profiles
|
memcpy (loadedProfileData, profdata, loadedProfileLength);
|
||||||
if ( sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT) ) {
|
|
||||||
// Modifying the gammaTRG tags
|
|
||||||
cmsWriteTag(embProfile, cmsSigGreenTRCTag, (void*)Color::linearGammaTRC );
|
|
||||||
cmsWriteTag(embProfile, cmsSigRedTRCTag, (void*)Color::linearGammaTRC );
|
|
||||||
cmsWriteTag(embProfile, cmsSigBlueTRCTag, (void*)Color::linearGammaTRC );
|
|
||||||
|
|
||||||
// Saving the profile in the memory
|
|
||||||
cmsUInt32Number bytesNeeded = 0;
|
|
||||||
cmsSaveProfileToMem(embProfile, 0, &bytesNeeded);
|
|
||||||
|
|
||||||
if (bytesNeeded > 0) {
|
|
||||||
loadedProfileData = new char[bytesNeeded + 1];
|
|
||||||
cmsSaveProfileToMem(embProfile, loadedProfileData, &bytesNeeded);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadedProfileLength = (int)bytesNeeded;
|
|
||||||
} else {
|
|
||||||
// Saving the profile in the memory as is
|
|
||||||
loadedProfileData = new char [loadedProfileLength];
|
|
||||||
memcpy (loadedProfileData, profdata, loadedProfileLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
embProfile = NULL;
|
embProfile = NULL;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "../rtgui/ppversion.h"
|
#include "../rtgui/ppversion.h"
|
||||||
#include "colortemp.h"
|
#include "colortemp.h"
|
||||||
#include "improcfun.h"
|
#include "improcfun.h"
|
||||||
|
#include "iccstore.h"
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#endif
|
#endif
|
||||||
@ -33,9 +34,9 @@ extern const Settings* settings;
|
|||||||
|
|
||||||
ImProcCoordinator::ImProcCoordinator ()
|
ImProcCoordinator::ImProcCoordinator ()
|
||||||
: orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL),
|
: 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),
|
ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_RELATIVE),
|
||||||
highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false),
|
softProof(false), gamutCheck(false), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false),
|
||||||
bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(NAN),
|
allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(NAN),
|
||||||
|
|
||||||
hltonecurve(65536),
|
hltonecurve(65536),
|
||||||
shtonecurve(65536),
|
shtonecurve(65536),
|
||||||
@ -87,7 +88,7 @@ ImProcCoordinator::ImProcCoordinator ()
|
|||||||
fullw(1), fullh(1),
|
fullw(1), fullh(1),
|
||||||
pW(-1), pH(-1),
|
pW(-1), pH(-1),
|
||||||
plistener(NULL), imageListener(NULL), aeListener(NULL), acListener(NULL), abwListener(NULL), actListener(NULL), adnListener(NULL), awavListener(NULL), dehaListener(NULL), hListener(NULL),
|
plistener(NULL), imageListener(NULL), aeListener(NULL), acListener(NULL), abwListener(NULL), actListener(NULL), adnListener(NULL), awavListener(NULL), dehaListener(NULL), hListener(NULL),
|
||||||
resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false), wavcontlutili(false),
|
resultValid(false), lastOutputProfile("BADFOOD"), lastOutputIntent(RI__COUNT), lastOutputBPC(false), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false), wavcontlutili(false),
|
||||||
butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), conversionBuffer(1, 1)
|
butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), conversionBuffer(1, 1)
|
||||||
|
|
||||||
{}
|
{}
|
||||||
@ -778,8 +779,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the monitor color transform if necessary
|
// Update the monitor color transform if necessary
|
||||||
if (todo & M_MONITOR) {
|
if ((todo & M_MONITOR) || (lastOutputProfile!=params.icm.output) || lastOutputIntent!=params.icm.outputIntent || lastOutputBPC!=params.icm.outputBPC) {
|
||||||
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent);
|
lastOutputProfile = params.icm.output;
|
||||||
|
lastOutputIntent = params.icm.outputIntent;
|
||||||
|
lastOutputBPC = params.icm.outputBPC;
|
||||||
|
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProof, gamutCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process crop, if needed
|
// process crop, if needed
|
||||||
@ -794,20 +798,12 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
|
|||||||
MyMutex::MyLock prevImgLock(previmg->getMutex());
|
MyMutex::MyLock prevImgLock(previmg->getMutex());
|
||||||
|
|
||||||
try {
|
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);
|
ipf.lab2monitorRgb (nprevl, previmg);
|
||||||
|
|
||||||
|
// Computing the internal image for analysis, i.e. conversion from WCS->Output profile
|
||||||
delete workimg;
|
delete workimg;
|
||||||
Glib::ustring outProfile = params.icm.output;
|
workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, params.icm);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
} catch(char * str) {
|
} catch(char * str) {
|
||||||
progress ("Error converting file...", 0);
|
progress ("Error converting file...", 0);
|
||||||
return;
|
return;
|
||||||
@ -1134,6 +1130,18 @@ void ImProcCoordinator::getMonitorProfile (Glib::ustring& profile, RenderingInte
|
|||||||
intent = monitorIntent;
|
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)
|
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ protected:
|
|||||||
Imagefloat *oprevi;
|
Imagefloat *oprevi;
|
||||||
LabImage *oprevl;
|
LabImage *oprevl;
|
||||||
LabImage *nprevl;
|
LabImage *nprevl;
|
||||||
Image8 *previmg;
|
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;
|
Image8 *workimg; // internal image in output color space for analysis
|
||||||
CieImage *ncie;
|
CieImage *ncie;
|
||||||
|
|
||||||
ImageSource* imgsrc;
|
ImageSource* imgsrc;
|
||||||
@ -73,8 +73,9 @@ protected:
|
|||||||
ImProcFunctions ipf;
|
ImProcFunctions ipf;
|
||||||
|
|
||||||
Glib::ustring monitorProfile;
|
Glib::ustring monitorProfile;
|
||||||
|
|
||||||
RenderingIntent monitorIntent;
|
RenderingIntent monitorIntent;
|
||||||
|
bool softProof;
|
||||||
|
bool gamutCheck;
|
||||||
|
|
||||||
int scale;
|
int scale;
|
||||||
bool highDetailPreprocessComputed;
|
bool highDetailPreprocessComputed;
|
||||||
@ -179,6 +180,13 @@ protected:
|
|||||||
MyMutex mProcessing;
|
MyMutex mProcessing;
|
||||||
ProcParams params;
|
ProcParams params;
|
||||||
|
|
||||||
|
// for optimization purpose, the output profile, output rendering intent and
|
||||||
|
// output BPC will trigger a regeneration of the profile on parameter change only
|
||||||
|
// and automatically
|
||||||
|
Glib::ustring lastOutputProfile;
|
||||||
|
RenderingIntent lastOutputIntent;
|
||||||
|
bool lastOutputBPC;
|
||||||
|
|
||||||
// members of the updater:
|
// members of the updater:
|
||||||
Glib::Thread* thread;
|
Glib::Thread* thread;
|
||||||
MyMutex updaterThreadStart;
|
MyMutex updaterThreadStart;
|
||||||
@ -256,6 +264,8 @@ public:
|
|||||||
|
|
||||||
void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent);
|
void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent);
|
||||||
void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const;
|
void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const;
|
||||||
|
void setSoftProofing (bool softProof, bool gamutCheck);
|
||||||
|
void getSoftProofing (bool &softProof, bool &gamutCheck);
|
||||||
|
|
||||||
bool updateTryLock ()
|
bool updateTryLock ()
|
||||||
{
|
{
|
||||||
|
@ -61,14 +61,6 @@ ImProcFunctions::~ImProcFunctions ()
|
|||||||
if (monitorTransform) {
|
if (monitorTransform) {
|
||||||
cmsDeleteTransform (monitorTransform);
|
cmsDeleteTransform (monitorTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output2monitorTransform) {
|
|
||||||
cmsDeleteTransform (output2monitorTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lab2outputTransform) {
|
|
||||||
cmsDeleteTransform (lab2outputTransform);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImProcFunctions::setScale (double iscale)
|
void ImProcFunctions::setScale (double iscale)
|
||||||
@ -76,24 +68,14 @@ void ImProcFunctions::setScale (double iscale)
|
|||||||
scale = 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
|
// set up monitor transform
|
||||||
if (monitorTransform) {
|
if (monitorTransform) {
|
||||||
cmsDeleteTransform (monitorTransform);
|
cmsDeleteTransform (monitorTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output2monitorTransform) {
|
|
||||||
cmsDeleteTransform (output2monitorTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lab2outputTransform) {
|
|
||||||
cmsDeleteTransform (lab2outputTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
monitorTransform = nullptr;
|
monitorTransform = nullptr;
|
||||||
output2monitorTransform = nullptr;
|
|
||||||
lab2outputTransform = nullptr;
|
|
||||||
|
|
||||||
#if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB
|
#if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB
|
||||||
|
|
||||||
@ -101,20 +83,57 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con
|
|||||||
|
|
||||||
if (monitor) {
|
if (monitor) {
|
||||||
MyMutex::MyLock lcmsLock (*lcmsMutex);
|
MyMutex::MyLock lcmsLock (*lcmsMutex);
|
||||||
|
|
||||||
|
cmsUInt32Number flags;
|
||||||
cmsHPROFILE iprof = cmsCreateLab4Profile(nullptr);
|
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) {
|
if (softProof) {
|
||||||
outputProfile = icm.output;
|
cmsHPROFILE oprof = nullptr;
|
||||||
cmsHPROFILE jprof = iccStore->getProfile(outputProfile);
|
if(icm.gamma != "default" || icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8
|
||||||
|
GammaValues ga;
|
||||||
if (jprof) {
|
iccStore->getGammaArray(icm, ga);
|
||||||
lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
|
oprof = iccStore->createGammaProfile (icm, ga);
|
||||||
output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
|
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
GammaValues ga;
|
||||||
|
iccStore->getGammaArray(icm, ga);
|
||||||
|
oprof = iccStore->createCustomGammaOutputProfile (icm, ga);
|
||||||
|
} else {
|
||||||
|
oprof = iccStore->getProfile(icm.output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
cmsCloseProfile(iprof);
|
||||||
|
@ -223,7 +223,7 @@ public:
|
|||||||
bool needsPCVignetting ();
|
bool needsPCVignetting ();
|
||||||
|
|
||||||
void firstAnalysis (const Imagefloat* const working, const ProcParams ¶ms, LUTu & vhist16);
|
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,
|
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,
|
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 );
|
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 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);
|
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);
|
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm);
|
||||||
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, const procparams::ColorManagementParams &icm, bool bw, GammaValues *ga=NULL);
|
||||||
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw);//without gamma ==>default
|
|
||||||
// CieImage *ciec;
|
// 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);
|
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;
|
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)
|
void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
|
||||||
{
|
{
|
||||||
if (monitorTransform) {
|
if (monitorTransform) {
|
||||||
@ -61,21 +67,13 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
|
|||||||
float* ra = lab->a[i];
|
float* ra = lab->a[i];
|
||||||
float* rb = lab->b[i];
|
float* rb = lab->b[i];
|
||||||
|
|
||||||
float fy, fx, fz, x_, y_, z_, LL;
|
|
||||||
|
|
||||||
for (int j = 0; j < W; j++) {
|
for (int j = 0; j < W; j++) {
|
||||||
buffer[iy++] = rL[j] / 327.68f;
|
buffer[iy++] = rL[j] / 327.68f;
|
||||||
buffer[iy++] = ra[j] / 327.68f;
|
buffer[iy++] = ra[j] / 327.68f;
|
||||||
buffer[iy++] = rb[j] / 327.68f;
|
buffer[iy++] = rb[j] / 327.68f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) {
|
cmsDoTransform (monitorTransform, buffer, data + ix, W);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // End of parallelization
|
} // End of parallelization
|
||||||
} else {
|
} else {
|
||||||
@ -115,8 +113,18 @@ 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);
|
||||||
|
|
||||||
if (cx < 0) {
|
if (cx < 0) {
|
||||||
cx = 0;
|
cx = 0;
|
||||||
@ -135,9 +143,22 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Image8* image = new Image8 (cw, ch);
|
Image8* image = new Image8 (cw, ch);
|
||||||
|
Glib::ustring profile;
|
||||||
cmsHPROFILE oprof = iccStore->getProfile (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) {
|
if (oprof) {
|
||||||
cmsHPROFILE oprofG = oprof;
|
cmsHPROFILE oprofG = oprof;
|
||||||
|
|
||||||
@ -145,11 +166,16 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
|||||||
oprofG = ICCStore::makeStdGammaProfile(oprof);
|
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 ();
|
lcmsMutex->lock ();
|
||||||
cmsHPROFILE hLab = cmsCreateLab4Profile(NULL);
|
cmsHPROFILE LabIProf = cmsCreateLab4Profile(NULL);
|
||||||
cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent,
|
cmsHTRANSFORM hTransform = cmsCreateTransform (LabIProf, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, icm.outputIntent, flags); // NOCACHE is important for thread safety
|
||||||
cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety
|
cmsCloseProfile(LabIProf);
|
||||||
cmsCloseProfile(hLab);
|
|
||||||
lcmsMutex->unlock ();
|
lcmsMutex->unlock ();
|
||||||
|
|
||||||
unsigned char *data = image->data;
|
unsigned char *data = image->data;
|
||||||
@ -220,8 +246,24 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
|||||||
|
|
||||||
return image;
|
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, GammaValues *ga)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (cx < 0) {
|
if (cx < 0) {
|
||||||
@ -241,49 +283,37 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
Image16* image = new Image16 (cw, ch);
|
Image16* image = new Image16 (cw, ch);
|
||||||
cmsHPROFILE oprof = iccStore->getProfile (profile);
|
|
||||||
|
cmsHPROFILE oprof = NULL;
|
||||||
|
if (ga) {
|
||||||
|
lcmsMutex->lock ();
|
||||||
|
iccStore->getGammaArray(icm, *ga);
|
||||||
|
oprof = iccStore->createGammaProfile(icm, *ga);
|
||||||
|
lcmsMutex->unlock ();
|
||||||
|
printf("iccStore->createGammaProfile(icm, *ga);\n");
|
||||||
|
} else {
|
||||||
|
oprof = iccStore->getProfile (icm.output);
|
||||||
|
printf("iccStore->getProfile (%s);\n", icm.output.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (oprof) {
|
if (oprof) {
|
||||||
#ifdef _OPENMP
|
cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||||
#pragma omp parallel for if (multiThread)
|
if (icm.outputBPC) {
|
||||||
#endif
|
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
|
||||||
|
printf("lab2rgb16 / icm.outputBPC=true / outputIntent=%d\n", icm.outputIntent);
|
||||||
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 x_, y_, z_;
|
|
||||||
Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_);
|
|
||||||
|
|
||||||
xa[j - cx] = float2uint16range(x_);
|
|
||||||
ya[j - cx] = float2uint16range(y_);
|
|
||||||
za[j - cx] = float2uint16range(z_);
|
|
||||||
|
|
||||||
if(bw && y_ < 65535.f ) { //force Bw value and take highlight into account
|
|
||||||
xa[j - cx] = float2uint16range(y_ * Color::D50x);
|
|
||||||
za[j - cx] = float2uint16range(y_ * Color::D50z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else printf("lab2rgb16 / icm.outputBPC=false / outputIntent=%d\n", icm.outputIntent);
|
||||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
|
||||||
lcmsMutex->lock ();
|
lcmsMutex->lock ();
|
||||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
|
cmsHPROFILE iprof = cmsCreateLab4Profile(nullptr);
|
||||||
|
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, oprof, TYPE_RGB_16, icm.outputIntent, flags);
|
||||||
lcmsMutex->unlock ();
|
lcmsMutex->unlock ();
|
||||||
|
|
||||||
image->ExecCMSTransform(hTransform);
|
image->ExecCMSTransform(hTransform, *lab, cx, cy);
|
||||||
|
|
||||||
cmsDeleteTransform(hTransform);
|
cmsDeleteTransform(hTransform);
|
||||||
} else {
|
} else {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for if (multiThread)
|
#pragma omp parallel for schedule(dynamic,16) if (multiThread)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = cy; i < cy + ch; i++) {
|
for (int i = cy; i < cy + ch; i++) {
|
||||||
float R, G, B;
|
float R, G, B;
|
||||||
float* rL = lab->L[i];
|
float* rL = lab->L[i];
|
||||||
@ -297,279 +327,10 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
|
|||||||
float fz = fy - (0.005f * rb[j]) / 327.68f;
|
float fz = fy - (0.005f * rb[j]) / 327.68f;
|
||||||
float LL = rL[j] / 327.68f;
|
float LL = rL[j] / 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 y_ = 65535.0 * Color::f2xyz(fy);
|
||||||
float z_ = 65535.0f * (float) Color::f2xyz(fz) * Color::D50z;
|
float z_ = 65535.0f * Color::f2xyz(fz) * Color::D50z;
|
||||||
float y_ = (LL > Color::epskap) ? (float) 65535.0f * fy * fy * fy : 65535.0f * LL / Color::kappa;
|
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)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
|
|
||||||
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 pwr;
|
|
||||||
double ts;
|
|
||||||
ga6 = 0.0;
|
|
||||||
pwr = 1.0 / gampos;
|
|
||||||
ts = slpos;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; //gamma parameters
|
|
||||||
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
|
|
||||||
ga4 = g_a3 * ts;
|
|
||||||
ga0 = gampos;
|
|
||||||
ga1 = 1. / (1.0 + g_a4);
|
|
||||||
ga2 = g_a4 / (1.0 + g_a4);
|
|
||||||
ga3 = 1. / slpos;
|
|
||||||
ga5 = 0.0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 becomes Outputprofile
|
|
||||||
|
|
||||||
cmsFreeToneCurve(GammaTRC[0]);
|
|
||||||
|
|
||||||
if (oprofdef) {
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel for 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);
|
|
||||||
|
|
||||||
for (int j = cx; j < cx + cw; j++) {
|
|
||||||
float x_, y_, z_;
|
|
||||||
Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_);
|
|
||||||
|
|
||||||
xa[j - cx] = float2uint16range(x_);
|
|
||||||
ya[j - cx] = float2uint16range(y_);
|
|
||||||
za[j - cx] = float2uint16range(z_);
|
|
||||||
|
|
||||||
if(bw && y_ < 65535.f) { //force Bw value and take highlight into account
|
|
||||||
xa[j - cx] = float2uint16range(y_ * Color::D50x);
|
|
||||||
za[j - cx] = float2uint16range(y_ * Color::D50z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
|
||||||
lcmsMutex->lock ();
|
|
||||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
|
|
||||||
lcmsMutex->unlock ();
|
|
||||||
|
|
||||||
image->ExecCMSTransform(hTransform);
|
|
||||||
cmsDeleteTransform(hTransform);
|
|
||||||
} else {
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel for 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];
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
Color::xyz2srgb(x_, y_, z_, R, G, B);
|
Color::xyz2srgb(x_, y_, z_, R, G, B);
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
#include "median.h"
|
#include "median.h"
|
||||||
#include "EdgePreservingDecomposition.h"
|
#include "EdgePreservingDecomposition.h"
|
||||||
|
#include "iccstore.h"
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
|
@ -469,6 +469,7 @@ enum ProcEvent {
|
|||||||
EvcbdlMethod = 439,
|
EvcbdlMethod = 439,
|
||||||
EvRetinexgaintransmission = 440,
|
EvRetinexgaintransmission = 440,
|
||||||
EvLskal = 441,
|
EvLskal = 441,
|
||||||
|
EvOBPCompens = 442,
|
||||||
NUMOFEVENTS
|
NUMOFEVENTS
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -927,6 +927,7 @@ void ColorManagementParams::setDefaults()
|
|||||||
working = "ProPhoto";
|
working = "ProPhoto";
|
||||||
output = "RT_sRGB";
|
output = "RT_sRGB";
|
||||||
outputIntent = RI_RELATIVE;
|
outputIntent = RI_RELATIVE;
|
||||||
|
outputBPC = true;
|
||||||
gamma = "default";
|
gamma = "default";
|
||||||
gampos = 2.22;
|
gampos = 2.22;
|
||||||
slpos = 4.5;
|
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);
|
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) {
|
if (!pedited || pedited->icm.gamma) {
|
||||||
keyFile.set_string ("Color Management", "Gammafree", 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.outputBPC = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (keyFile.has_key ("Color Management", "Gammafree")) {
|
if (keyFile.has_key ("Color Management", "Gammafree")) {
|
||||||
icm.gamma = keyFile.get_string ("Color Management", "Gammafree");
|
icm.gamma = keyFile.get_string ("Color Management", "Gammafree");
|
||||||
|
|
||||||
|
@ -969,6 +969,7 @@ public:
|
|||||||
Glib::ustring working;
|
Glib::ustring working;
|
||||||
Glib::ustring output;
|
Glib::ustring output;
|
||||||
RenderingIntent outputIntent;
|
RenderingIntent outputIntent;
|
||||||
|
bool outputBPC;
|
||||||
static const Glib::ustring NoICMString;
|
static const Glib::ustring NoICMString;
|
||||||
|
|
||||||
Glib::ustring gamma;
|
Glib::ustring gamma;
|
||||||
|
@ -1973,7 +1973,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
|
|||||||
} else if(retinexParams.gammaretinex == "hig") {
|
} else if(retinexParams.gammaretinex == "hig") {
|
||||||
retinexgamtab = &(Color::gammatab_145_3);
|
retinexgamtab = &(Color::gammatab_145_3);
|
||||||
} else if(retinexParams.gammaretinex == "fre") {
|
} else if(retinexParams.gammaretinex == "fre") {
|
||||||
double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5;
|
GammaValues g_a;
|
||||||
double pwr = 1.0 / retinexParams.gam;
|
double pwr = 1.0 / retinexParams.gam;
|
||||||
double gamm = retinexParams.gam;
|
double gamm = retinexParams.gam;
|
||||||
double ts = retinexParams.slope;
|
double ts = retinexParams.slope;
|
||||||
@ -1984,21 +1984,21 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mode = 0, imax = 0;
|
int mode = 0, imax = 0;
|
||||||
Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope
|
Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope
|
||||||
|
|
||||||
// printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4);
|
// printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4);
|
||||||
double start;
|
double start;
|
||||||
double add;
|
double add;
|
||||||
|
|
||||||
if(gamm2 < 1.) {
|
if(gamm2 < 1.) {
|
||||||
start = g_a2;
|
start = g_a[2];
|
||||||
add = g_a4;
|
add = g_a[4];
|
||||||
} else {
|
} else {
|
||||||
start = g_a3;
|
start = g_a[3];
|
||||||
add = g_a4;
|
add = g_a[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
double mul = 1. + g_a4;
|
double mul = 1. + g_a[4];
|
||||||
|
|
||||||
lutTonereti(65536);
|
lutTonereti(65536);
|
||||||
|
|
||||||
@ -2245,7 +2245,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
|
|||||||
} else if(deh.gammaretinex == "hig") {
|
} else if(deh.gammaretinex == "hig") {
|
||||||
retinexigamtab = &(Color::igammatab_145_3);
|
retinexigamtab = &(Color::igammatab_145_3);
|
||||||
} else if(deh.gammaretinex == "fre") {
|
} else if(deh.gammaretinex == "fre") {
|
||||||
double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5;
|
GammaValues g_a;
|
||||||
double pwr = 1.0 / deh.gam;
|
double pwr = 1.0 / deh.gam;
|
||||||
double gamm = deh.gam;
|
double gamm = deh.gam;
|
||||||
double gamm2 = gamm;
|
double gamm2 = gamm;
|
||||||
@ -2256,18 +2256,18 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
|
|||||||
std::swap(pwr, gamm);
|
std::swap(pwr, gamm);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope
|
Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope
|
||||||
|
|
||||||
double mul = 1. + g_a4;
|
double mul = 1. + g_a[4];
|
||||||
double add;
|
double add;
|
||||||
double start;
|
double start;
|
||||||
|
|
||||||
if(gamm2 < 1.) {
|
if(gamm2 < 1.) {
|
||||||
start = g_a3;
|
start = g_a[3];
|
||||||
add = g_a3;
|
add = g_a[3];
|
||||||
} else {
|
} else {
|
||||||
add = g_a4;
|
add = g_a[4];
|
||||||
start = g_a2;
|
start = g_a[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
// 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);
|
||||||
|
@ -119,8 +119,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
|||||||
ALLNORAW, // EvDPDNLuma,
|
ALLNORAW, // EvDPDNLuma,
|
||||||
ALLNORAW, // EvDPDNChroma,
|
ALLNORAW, // EvDPDNChroma,
|
||||||
ALLNORAW, // EvDPDNGamma,
|
ALLNORAW, // EvDPDNGamma,
|
||||||
ALLNORAW, // EvDirPyrEqualizer,
|
ALLNORAW, // EvDirPyrEqualizer,
|
||||||
ALLNORAW, // EvDirPyrEqlEnabled,
|
ALLNORAW, // EvDirPyrEqlEnabled,
|
||||||
LUMINANCECURVE, // EvLSaturation,
|
LUMINANCECURVE, // EvLSaturation,
|
||||||
LUMINANCECURVE, // EvLaCurve,
|
LUMINANCECURVE, // EvLaCurve,
|
||||||
LUMINANCECURVE, // EvLbCurve,
|
LUMINANCECURVE, // EvLbCurve,
|
||||||
@ -275,12 +275,12 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
|||||||
LUMINANCECURVE, // EvLCLCurve
|
LUMINANCECURVE, // EvLCLCurve
|
||||||
LUMINANCECURVE, // EvLLHCurve
|
LUMINANCECURVE, // EvLLHCurve
|
||||||
LUMINANCECURVE, // EvLHHCurve
|
LUMINANCECURVE, // EvLHHCurve
|
||||||
ALLNORAW, // EvDirPyrEqualizerThreshold
|
ALLNORAW, // EvDirPyrEqualizerThreshold
|
||||||
ALLNORAW, // EvDPDNenhance
|
ALLNORAW, // EvDPDNenhance
|
||||||
RGBCURVE, // EvBWMethodalg
|
RGBCURVE, // EvBWMethodalg
|
||||||
ALLNORAW, // EvDirPyrEqualizerSkin
|
ALLNORAW, // EvDirPyrEqualizerSkin
|
||||||
ALLNORAW, // EvDirPyrEqlgamutlab
|
ALLNORAW, // EvDirPyrEqlgamutlab
|
||||||
ALLNORAW, // EvDirPyrEqualizerHueskin
|
ALLNORAW, // EvDirPyrEqualizerHueskin
|
||||||
ALLNORAW, // EvDPDNmedian
|
ALLNORAW, // EvDPDNmedian
|
||||||
ALLNORAW, // EvDPDNmedmet
|
ALLNORAW, // EvDPDNmedmet
|
||||||
RGBCURVE, // EvColorToningEnabled
|
RGBCURVE, // EvColorToningEnabled
|
||||||
@ -453,7 +453,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
|||||||
RETINEX, // EvLhighl
|
RETINEX, // EvLhighl
|
||||||
DEMOSAIC, // EvLbaselog
|
DEMOSAIC, // EvLbaselog
|
||||||
DEMOSAIC, // EvRetinexlhcurve
|
DEMOSAIC, // EvRetinexlhcurve
|
||||||
ALLNORAW, // EvOIntent
|
OUTPUTPROFILE, // EvOIntent
|
||||||
MONITORTRANSFORM, // EvMonitorTransform: no history message
|
MONITORTRANSFORM, // EvMonitorTransform: no history message
|
||||||
RETINEX, // EvLiter
|
RETINEX, // EvLiter
|
||||||
RETINEX, // EvLgrad
|
RETINEX, // EvLgrad
|
||||||
@ -465,10 +465,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
|||||||
RETINEX, // EvLradius
|
RETINEX, // EvLradius
|
||||||
RETINEX, // EvmapMethod
|
RETINEX, // EvmapMethod
|
||||||
DEMOSAIC, // EvRetinexmapcurve
|
DEMOSAIC, // EvRetinexmapcurve
|
||||||
DEMOSAIC, // EvviewMethod
|
DEMOSAIC, // EvviewMethod
|
||||||
ALLNORAW, // EvcbdlMethod
|
ALLNORAW, // EvcbdlMethod
|
||||||
RETINEX, // EvRetinexgaintransmission
|
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
|
// Bitfield of functions to do to the preview image when an event occurs
|
||||||
// Use those or create new ones for your new events
|
// 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 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 DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
|
||||||
#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
|
#define 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 DEFRINGE (M_LUMINANCE|M_COLOR)
|
||||||
#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR)
|
#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR)
|
||||||
#define DIRPYREQUALIZER (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 CROP M_CROP
|
||||||
#define RESIZE M_VOID
|
#define RESIZE M_VOID
|
||||||
#define EXIF M_VOID
|
#define EXIF M_VOID
|
||||||
@ -69,7 +69,7 @@
|
|||||||
#define MINUPDATE M_MINUPDATE
|
#define MINUPDATE M_MINUPDATE
|
||||||
#define RETINEX (M_RETINEX|ALLNORAW)
|
#define RETINEX (M_RETINEX|ALLNORAW)
|
||||||
#define MONITORTRANSFORM M_MONITOR
|
#define MONITORTRANSFORM M_MONITOR
|
||||||
#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM)
|
#define OUTPUTPROFILE M_MONITOR
|
||||||
|
|
||||||
extern int refreshmap[];
|
extern int refreshmap[];
|
||||||
#endif
|
#endif
|
||||||
|
@ -418,6 +418,8 @@ public:
|
|||||||
|
|
||||||
virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0;
|
virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0;
|
||||||
virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0;
|
virtual 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 () {}
|
virtual ~StagedImageProcessor () {}
|
||||||
|
|
||||||
|
@ -908,7 +908,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
|||||||
|
|
||||||
ImProcFunctions ipf (¶ms, false);
|
ImProcFunctions ipf (¶ms, false);
|
||||||
ipf.setScale (sqrt(double(fw * fw + fh * fh)) / sqrt(double(thumbImg->width * thumbImg->width + thumbImg->height * thumbImg->height))*scale);
|
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);
|
LUTu hist16 (65536);
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
|
|
||||||
Glib::ustring monitorProfile; ///< ICC profile name used for the monitor
|
Glib::ustring monitorProfile; ///< ICC profile name used for the monitor
|
||||||
RenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile
|
RenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile
|
||||||
|
bool monitorBPC; ///< Black Point Compensation for the Labimage->Monitor transform (directly, i.e. not soft-proofing and no WCS in between)
|
||||||
bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile
|
bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile
|
||||||
bool autocielab;
|
bool autocielab;
|
||||||
bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode
|
bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode
|
||||||
|
@ -1151,213 +1151,27 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
|||||||
cmsHPROFILE jprof = NULL;
|
cmsHPROFILE jprof = NULL;
|
||||||
bool customGamma = false;
|
bool customGamma = false;
|
||||||
bool useLCMS = 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
|
if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8
|
||||||
|
|
||||||
double ga0, ga1, ga2, ga3, ga4, ga5, ga6;
|
GammaValues ga;
|
||||||
// if(params.blackwhite.enabled) params.toneCurve.hrenabled=false;
|
// 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;
|
customGamma = true;
|
||||||
|
|
||||||
//or selected Free gamma
|
//or selected Free gamma
|
||||||
useLCMS = false;
|
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;
|
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 {
|
|
||||||
cmsToneCurve* GammaTRC[3] = { NULL, NULL, NULL };
|
|
||||||
|
|
||||||
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
|
|
||||||
//change desc Tag , to "free gamma", or "BT709", etc.
|
|
||||||
cmsMLU *DescriptionMLU, *CopyrightMLU, *DmndMLU, *DmddMLU;// for modification TAG
|
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
// if Default gamma mode: we use the profile selected in the "Output profile" combobox;
|
// 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
|
// 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);
|
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly);
|
||||||
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);
|
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf("Output profile_: \"%s\"\n", params.icm.output.c_str());
|
printf("Output profile_: \"%s\"\n", params.icm.output.c_str());
|
||||||
@ -1369,17 +1183,15 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!autili && !butili ) {
|
if(bwonly) { //force BW r=g=b
|
||||||
if(params.blackwhite.enabled && !params.colorToning.enabled ) {//force BW r=g=b
|
if (settings->verbose) {
|
||||||
if (settings->verbose) {
|
printf("Force BW\n");
|
||||||
printf("Force BW\n");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (int ccw = 0; ccw < cw; ccw++) {
|
for (int ccw = 0; ccw < cw; ccw++) {
|
||||||
for (int cch = 0; cch < ch; cch++) {
|
for (int cch = 0; cch < ch; cch++) {
|
||||||
readyImg->r(cch, ccw) = readyImg->g(cch, ccw);
|
readyImg->r(cch, ccw) = readyImg->g(cch, ccw);
|
||||||
readyImg->b(cch, ccw) = readyImg->g(cch, ccw);
|
readyImg->b(cch, ccw) = readyImg->g(cch, ccw);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1405,37 +1217,28 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
|||||||
// Setting the output curve to readyImg
|
// Setting the output curve to readyImg
|
||||||
if (customGamma) {
|
if (customGamma) {
|
||||||
if (!useLCMS) {
|
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);
|
ProfileContent pc(jprof);
|
||||||
readyImg->setOutputProfile (pc.data, pc.length);
|
readyImg->setOutputProfile (pc.data, pc.length);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b
|
// use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma
|
||||||
Glib::ustring outputProfile;
|
|
||||||
|
|
||||||
if (params.icm.output != "" && params.icm.output != ColorManagementParams::NoICMString) {
|
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
|
// 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 (jprof == NULL) {
|
||||||
if (settings->verbose) {
|
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 {
|
} else {
|
||||||
if (settings->verbose) {
|
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);
|
readyImg->setOutputProfile (pc.data, pc.length);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -354,7 +354,7 @@ void CurveEditorGroup::setTooltip( Glib::ustring ttip)
|
|||||||
void CurveEditorGroup::setBatchMode (bool batchMode)
|
void CurveEditorGroup::setBatchMode (bool batchMode)
|
||||||
{
|
{
|
||||||
for (std::vector<CurveEditor*>::iterator i = curveEditors.begin(); i != curveEditors.end(); ++i) {
|
for (std::vector<CurveEditor*>::iterator i = curveEditors.begin(); i != curveEditors.end(); ++i) {
|
||||||
(*i)->curveType->addEntry("curveType-unchanged.png", M("GENERAL_UNCHANGED"));
|
(*i)->curveType->addEntry("unchanged-18.png", M("GENERAL_UNCHANGED"));
|
||||||
(*i)->curveType->show();
|
(*i)->curveType->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,11 +35,13 @@
|
|||||||
|
|
||||||
using namespace rtengine::procparams;
|
using namespace rtengine::procparams;
|
||||||
|
|
||||||
class EditorPanel::MonitorProfileSelector
|
class EditorPanel::ColorManagementToolbar
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
MyComboBoxText profileBox;
|
MyComboBoxText profileBox;
|
||||||
PopUpButton intentBox;
|
PopUpButton intentBox;
|
||||||
|
Gtk::ToggleButton softProof;
|
||||||
|
Gtk::ToggleButton spGamutCheck;
|
||||||
sigc::connection profileConn, intentConn;
|
sigc::connection profileConn, intentConn;
|
||||||
|
|
||||||
rtengine::StagedImageProcessor* const& processor;
|
rtengine::StagedImageProcessor* const& processor;
|
||||||
@ -61,29 +63,51 @@ private:
|
|||||||
profileBox.set_active (0);
|
profileBox.set_active (0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const std::vector<Glib::ustring> profiles = rtengine::iccStore->getProfiles ();
|
const std::vector<Glib::ustring> profiles = rtengine::iccStore->getProfiles (true);
|
||||||
|
|
||||||
for (std::vector<Glib::ustring>::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) {
|
for (std::vector<Glib::ustring>::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) {
|
||||||
profileBox.append (*iterator);
|
profileBox.append (*iterator);
|
||||||
}
|
}
|
||||||
|
profileBox.set_tooltip_text (profileBox.get_active_text ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareIntentBox ()
|
void prepareIntentBox ()
|
||||||
{
|
{
|
||||||
intentBox.addEntry ("intent-relative.png", M ("PREFERENCES_INTENT_RELATIVE"));
|
// same order as the enum
|
||||||
intentBox.addEntry ("intent-perceptual.png", M ("PREFERENCES_INTENT_PERCEPTUAL"));
|
intentBox.addEntry ("intent-perceptual.png", M ("PREFERENCES_INTENT_PERCEPTUAL"));
|
||||||
|
intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE"));
|
||||||
intentBox.addEntry ("intent-absolute.png", M ("PREFERENCES_INTENT_ABSOLUTE"));
|
intentBox.addEntry ("intent-absolute.png", M ("PREFERENCES_INTENT_ABSOLUTE"));
|
||||||
setExpandAlignProperties (intentBox.buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties (intentBox.buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||||
|
|
||||||
intentBox.setSelected (0);
|
intentBox.setSelected(1);
|
||||||
intentBox.show ();
|
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 ()
|
void profileBoxChanged ()
|
||||||
{
|
{
|
||||||
updateParameters ();
|
updateParameters ();
|
||||||
|
|
||||||
profileBox.set_tooltip_text (profileBox.get_active_text ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void intentBoxChanged (int)
|
void intentBoxChanged (int)
|
||||||
@ -91,7 +115,17 @@ private:
|
|||||||
updateParameters ();
|
updateParameters ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateParameters ()
|
void softProofToggled ()
|
||||||
|
{
|
||||||
|
updateSoftProofParameters ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void spGamutCheckToggled ()
|
||||||
|
{
|
||||||
|
updateSoftProofParameters ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateParameters (bool noEvent = false)
|
||||||
{
|
{
|
||||||
ConnectionBlocker profileBlocker (profileConn);
|
ConnectionBlocker profileBlocker (profileConn);
|
||||||
ConnectionBlocker intentBlocker (intentConn);
|
ConnectionBlocker intentBlocker (intentConn);
|
||||||
@ -123,23 +157,36 @@ private:
|
|||||||
profile.clear ();
|
profile.clear ();
|
||||||
|
|
||||||
intentBox.set_sensitive (false);
|
intentBox.set_sensitive (false);
|
||||||
intentBox.setSelected (0);
|
intentBox.setSelected (1);
|
||||||
|
softProof.set_sensitive(false);
|
||||||
|
spGamutCheck.set_sensitive(false);
|
||||||
|
|
||||||
|
profileBox.set_tooltip_text ("");
|
||||||
|
|
||||||
} else {
|
} 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 supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC;
|
||||||
const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL;
|
const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL;
|
||||||
const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC;
|
const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC;
|
||||||
|
|
||||||
if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) {
|
if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) {
|
||||||
intentBox.set_sensitive (true);
|
intentBox.set_sensitive (true);
|
||||||
intentBox.setItemSensitivity (0, supportsRelativeColorimetric);
|
intentBox.setItemSensitivity(0, supportsPerceptual);
|
||||||
intentBox.setItemSensitivity (1, supportsPerceptual);
|
intentBox.setItemSensitivity(1, supportsRelativeColorimetric);
|
||||||
intentBox.setItemSensitivity (2, supportsAbsoluteColorimetric);
|
intentBox.setItemSensitivity(2, supportsAbsoluteColorimetric);
|
||||||
|
softProof.set_sensitive(true);
|
||||||
|
spGamutCheck.set_sensitive(true);
|
||||||
} else {
|
} else {
|
||||||
|
intentBox.setItemSensitivity(0, true);
|
||||||
|
intentBox.setItemSensitivity(1, true);
|
||||||
|
intentBox.setItemSensitivity(2, true);
|
||||||
intentBox.set_sensitive (false);
|
intentBox.set_sensitive (false);
|
||||||
intentBox.setSelected (0);
|
intentBox.setSelected (1);
|
||||||
|
softProof.set_sensitive(false);
|
||||||
|
spGamutCheck.set_sensitive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profileBox.set_tooltip_text (profileBox.get_active_text ());
|
||||||
}
|
}
|
||||||
|
|
||||||
rtengine::RenderingIntent intent;
|
rtengine::RenderingIntent intent;
|
||||||
@ -147,11 +194,11 @@ private:
|
|||||||
switch (intentBox.getSelected ()) {
|
switch (intentBox.getSelected ()) {
|
||||||
default:
|
default:
|
||||||
case 0:
|
case 0:
|
||||||
intent = rtengine::RI_RELATIVE;
|
intent = rtengine::RI_PERCEPTUAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
intent = rtengine::RI_PERCEPTUAL;
|
intent = rtengine::RI_RELATIVE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -163,29 +210,61 @@ private:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
processor->beginUpdateParams ();
|
if (!noEvent) {
|
||||||
|
processor->beginUpdateParams ();
|
||||||
|
}
|
||||||
processor->setMonitorProfile (profile, intent);
|
processor->setMonitorProfile (profile, intent);
|
||||||
processor->endUpdateParams (rtengine::EvMonitorTransform);
|
processor->setSoftProofing (softProof.get_sensitive() && softProof.get_active(), spGamutCheck.get_sensitive() && spGamutCheck.get_active());
|
||||||
|
if (!noEvent) {
|
||||||
|
processor->endUpdateParams (rtengine::EvMonitorTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSoftProofParameters (bool noEvent = false)
|
||||||
|
{
|
||||||
|
spGamutCheck.set_sensitive(softProof.get_active());
|
||||||
|
|
||||||
|
if (profileBox.get_active_row_number () > 0) {
|
||||||
|
if (!noEvent) {
|
||||||
|
processor->beginUpdateParams ();
|
||||||
|
}
|
||||||
|
processor->setSoftProofing (softProof.get_sensitive() && softProof.get_active(), spGamutCheck.get_sensitive() && spGamutCheck.get_active());
|
||||||
|
if (!noEvent) {
|
||||||
|
processor->endUpdateParams (rtengine::EvMonitorTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) :
|
explicit ColorManagementToolbar (rtengine::StagedImageProcessor* const& ipc) :
|
||||||
intentBox (Glib::ustring (), true),
|
intentBox (Glib::ustring (), true),
|
||||||
processor (ipc)
|
processor (ipc)
|
||||||
{
|
{
|
||||||
prepareProfileBox ();
|
prepareProfileBox ();
|
||||||
prepareIntentBox ();
|
prepareIntentBox ();
|
||||||
|
prepareSoftProofingBox ();
|
||||||
|
|
||||||
reset ();
|
reset ();
|
||||||
|
|
||||||
profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::profileBoxChanged));
|
softProof.signal_toggled().connect(sigc::mem_fun (this, &ColorManagementToolbar::softProofToggled));
|
||||||
intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::intentBoxChanged));
|
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_right_in (Gtk::Grid* grid)
|
void pack_right_in (Gtk::Grid* grid)
|
||||||
{
|
{
|
||||||
grid->attach_next_to (profileBox, Gtk::POS_RIGHT, 1, 1);
|
grid->attach_next_to (profileBox, Gtk::POS_RIGHT, 1, 1);
|
||||||
grid->attach_next_to (*intentBox.buttonGroup, Gtk::POS_RIGHT, 1, 1);
|
grid->attach_next_to (*intentBox.buttonGroup, Gtk::POS_RIGHT, 1, 1);
|
||||||
|
grid->attach_next_to (softProof, Gtk::POS_RIGHT, 1, 1);
|
||||||
|
grid->attach_next_to (spGamutCheck, Gtk::POS_RIGHT, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateProcessor()
|
||||||
|
{
|
||||||
|
if (processor) {
|
||||||
|
updateParameters(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset ()
|
void reset ()
|
||||||
@ -207,11 +286,11 @@ public:
|
|||||||
|
|
||||||
switch (options.rtSettings.monitorIntent) {
|
switch (options.rtSettings.monitorIntent) {
|
||||||
default:
|
default:
|
||||||
case rtengine::RI_RELATIVE:
|
case rtengine::RI_PERCEPTUAL:
|
||||||
intentBox.setSelected (0);
|
intentBox.setSelected (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case rtengine::RI_PERCEPTUAL:
|
case rtengine::RI_RELATIVE:
|
||||||
intentBox.setSelected (1);
|
intentBox.setSelected (1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -418,8 +497,6 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
|
|||||||
tbShowHideSidePanels->set_image (*iShowHideSidePanels);
|
tbShowHideSidePanels->set_image (*iShowHideSidePanels);
|
||||||
setExpandAlignProperties (tbShowHideSidePanels, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties (tbShowHideSidePanels, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||||
|
|
||||||
monitorProfile.reset (new MonitorProfileSelector (ipc));
|
|
||||||
|
|
||||||
navPrev = navNext = navSync = NULL;
|
navPrev = navNext = navSync = NULL;
|
||||||
|
|
||||||
if (!simpleEditor && !options.tabbedUI) {
|
if (!simpleEditor && !options.tabbedUI) {
|
||||||
@ -452,6 +529,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
|
|||||||
// ================== PACKING THE BOTTOM WIDGETS =================
|
// ================== PACKING THE BOTTOM WIDGETS =================
|
||||||
|
|
||||||
// Adding widgets from center to the left, on the left side (using Gtk::POS_LEFT)
|
// Adding widgets from center to the left, on the left side (using Gtk::POS_LEFT)
|
||||||
|
iops->attach_next_to (*vsep2, Gtk::POS_LEFT, 1, 1);
|
||||||
iops->attach_next_to (*progressLabel, Gtk::POS_LEFT, 1, 1);
|
iops->attach_next_to (*progressLabel, Gtk::POS_LEFT, 1, 1);
|
||||||
iops->attach_next_to (*vsep1, Gtk::POS_LEFT, 1, 1);
|
iops->attach_next_to (*vsep1, Gtk::POS_LEFT, 1, 1);
|
||||||
iops->attach_next_to (*sendtogimp, Gtk::POS_LEFT, 1, 1);
|
iops->attach_next_to (*sendtogimp, Gtk::POS_LEFT, 1, 1);
|
||||||
@ -462,9 +540,10 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
|
|||||||
|
|
||||||
iops->attach_next_to (*saveimgas, Gtk::POS_LEFT, 1, 1);
|
iops->attach_next_to (*saveimgas, Gtk::POS_LEFT, 1, 1);
|
||||||
|
|
||||||
// Adding widgets from center to the right, on the right side (using Gtk::POS_RIGHT)
|
|
||||||
iops->attach_next_to (*vsep2, Gtk::POS_RIGHT, 1, 1);
|
// Color management toolbar
|
||||||
monitorProfile->pack_right_in (iops);
|
colorMgmtToolBar.reset (new ColorManagementToolbar (ipc));
|
||||||
|
colorMgmtToolBar->pack_right_in (iops);
|
||||||
|
|
||||||
if (!simpleEditor && !options.tabbedUI) {
|
if (!simpleEditor && !options.tabbedUI) {
|
||||||
iops->attach_next_to (*vsep3, Gtk::POS_RIGHT, 1, 1);
|
iops->attach_next_to (*vsep3, Gtk::POS_RIGHT, 1, 1);
|
||||||
@ -736,6 +815,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
|
|||||||
this->isrc = isrc;
|
this->isrc = isrc;
|
||||||
ipc = rtengine::StagedImageProcessor::create (isrc);
|
ipc = rtengine::StagedImageProcessor::create (isrc);
|
||||||
ipc->setProgressListener (this);
|
ipc->setProgressListener (this);
|
||||||
|
colorMgmtToolBar->updateProcessor();
|
||||||
ipc->setPreviewImageListener (previewHandler);
|
ipc->setPreviewImageListener (previewHandler);
|
||||||
ipc->setPreviewScale (10); // Important
|
ipc->setPreviewScale (10); // Important
|
||||||
tpc->initImage (ipc, tmb->getType() == FT_Raw);
|
tpc->initImage (ipc, tmb->getType() == FT_Raw);
|
||||||
@ -784,8 +864,6 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
history->resetSnapShotNumber();
|
history->resetSnapShotNumber();
|
||||||
|
|
||||||
monitorProfile->reset ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPanel::close ()
|
void EditorPanel::close ()
|
||||||
|
@ -85,8 +85,8 @@ protected:
|
|||||||
Gtk::Button* navNext;
|
Gtk::Button* navNext;
|
||||||
Gtk::Button* navPrev;
|
Gtk::Button* navPrev;
|
||||||
|
|
||||||
class MonitorProfileSelector;
|
class ColorManagementToolbar;
|
||||||
std::unique_ptr<MonitorProfileSelector> monitorProfile;
|
std::unique_ptr<ColorManagementToolbar> colorMgmtToolBar;
|
||||||
|
|
||||||
ImageAreaPanel* iareapanel;
|
ImageAreaPanel* iareapanel;
|
||||||
PreviewHandler* previewHandler;
|
PreviewHandler* previewHandler;
|
||||||
|
@ -1185,6 +1185,7 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
|
|||||||
params.icm.working = options.fastexport_icm_working ;
|
params.icm.working = options.fastexport_icm_working ;
|
||||||
params.icm.output = options.fastexport_icm_output ;
|
params.icm.output = options.fastexport_icm_output ;
|
||||||
params.icm.outputIntent = options.fastexport_icm_outputIntent ;
|
params.icm.outputIntent = options.fastexport_icm_outputIntent ;
|
||||||
|
params.icm.outputBPC = options.fastexport_icm_outputBPC ;
|
||||||
params.icm.gamma = options.fastexport_icm_gamma ;
|
params.icm.gamma = options.fastexport_icm_gamma ;
|
||||||
params.resize.enabled = options.fastexport_resize_enabled ;
|
params.resize.enabled = options.fastexport_resize_enabled ;
|
||||||
params.resize.scale = options.fastexport_resize_scale ;
|
params.resize.scale = options.fastexport_resize_scale ;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "../rtengine/improccoordinator.h"
|
#include "../rtengine/improccoordinator.h"
|
||||||
#include "../rtengine/color.h"
|
#include "../rtengine/color.h"
|
||||||
#include "../rtengine/opthelper.h"
|
#include "../rtengine/opthelper.h"
|
||||||
|
#include "../rtengine/iccstore.h"
|
||||||
using namespace rtengine;
|
using namespace rtengine;
|
||||||
|
|
||||||
extern Options options;
|
extern Options options;
|
||||||
|
@ -205,15 +205,21 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
|
|||||||
Gtk::HBox *riHBox = Gtk::manage ( new Gtk::HBox());
|
Gtk::HBox *riHBox = Gtk::manage ( new Gtk::HBox());
|
||||||
Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_PROFILEINTENT")+":"));
|
Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_PROFILEINTENT")+":"));
|
||||||
riHBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK);
|
riHBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK);
|
||||||
ointent = Gtk::manage (new MyComboBoxText ());
|
ointent = Gtk::manage (new PopUpButton ());
|
||||||
riHBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET);
|
ointent->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL"));
|
||||||
ointent->append (M("PREFERENCES_INTENT_PERCEPTUAL"));
|
ointent->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE"));
|
||||||
ointent->append (M("PREFERENCES_INTENT_RELATIVE"));
|
ointent->addEntry("intent-saturation.png", M("PREFERENCES_INTENT_SATURATION"));
|
||||||
ointent->append (M("PREFERENCES_INTENT_SATURATION"));
|
ointent->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE"));
|
||||||
ointent->append (M("PREFERENCES_INTENT_ABSOLUTE"));
|
ointent->setSelected (1);
|
||||||
ointent->set_active (1);
|
ointent->show();
|
||||||
|
riHBox->pack_start (*ointent->buttonGroup, Gtk::PACK_EXPAND_PADDING);
|
||||||
oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK);
|
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
|
// Output gamma
|
||||||
|
|
||||||
Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ());
|
Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ());
|
||||||
@ -306,6 +312,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
|
|||||||
wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) );
|
wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) );
|
||||||
dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) );
|
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));
|
gamcsconn = freegamma->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::GamChanged));
|
||||||
tcurveconn = ckbToneCurve->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::toneCurveChanged));
|
tcurveconn = ckbToneCurve->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::toneCurveChanged));
|
||||||
ltableconn = ckbApplyLookTable->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::applyLookTableChanged));
|
ltableconn = ckbApplyLookTable->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::applyLookTableChanged));
|
||||||
@ -324,6 +331,31 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
|
|||||||
show_all ();
|
show_all ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ICMPanel::updateRenderingIntent (const Glib::ustring &profile) {
|
||||||
|
const uint8_t supportedIntents = rtengine::iccStore->getOutputIntents (profile);
|
||||||
|
const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL;
|
||||||
|
const bool supportsRelative = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC;
|
||||||
|
const bool supportsSaturation = supportedIntents & 1 << INTENT_SATURATION;
|
||||||
|
const bool supportsAbsolute = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC;
|
||||||
|
|
||||||
|
//printf("Intents: %d / Perceptual: %d Relative: %d Saturation: %d Absolute: %d\n", supportedIntents, supportsPerceptual, supportsRelative, supportsSaturation, supportsAbsolute);
|
||||||
|
|
||||||
|
if (!profile.empty() && (supportsPerceptual || supportsRelative || supportsSaturation || supportsAbsolute)) {
|
||||||
|
ointent->set_sensitive (true);
|
||||||
|
ointent->setItemSensitivity(0, supportsPerceptual);
|
||||||
|
ointent->setItemSensitivity(1, supportsRelative);
|
||||||
|
ointent->setItemSensitivity(2, supportsSaturation);
|
||||||
|
ointent->setItemSensitivity(3, supportsAbsolute);
|
||||||
|
} else {
|
||||||
|
ointent->setItemSensitivity(0, true);
|
||||||
|
ointent->setItemSensitivity(1, true);
|
||||||
|
ointent->setItemSensitivity(2, true);
|
||||||
|
ointent->setItemSensitivity(3, true);
|
||||||
|
ointent->set_sensitive (false);
|
||||||
|
ointent->setSelected (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name)
|
void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -466,6 +498,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
|
|
||||||
disableListener ();
|
disableListener ();
|
||||||
|
|
||||||
|
obpcconn.block (true);
|
||||||
ipc.block (true);
|
ipc.block (true);
|
||||||
gamcsconn.block (true);
|
gamcsconn.block (true);
|
||||||
tcurveconn.block(true);
|
tcurveconn.block(true);
|
||||||
@ -480,36 +513,50 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
|
|
||||||
if (pp->icm.input == "(none)") {
|
if (pp->icm.input == "(none)") {
|
||||||
inone->set_active (true);
|
inone->set_active (true);
|
||||||
ckbBlendCMSMatrix->set_sensitive (false);
|
if (!batchMode) {
|
||||||
|
ckbBlendCMSMatrix->set_sensitive (false);
|
||||||
|
}
|
||||||
updateDCP(pp->icm.dcpIlluminant, "");
|
updateDCP(pp->icm.dcpIlluminant, "");
|
||||||
} else if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() == Gtk::STATE_INSENSITIVE)) {
|
} else if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() == Gtk::STATE_INSENSITIVE)) {
|
||||||
iembedded->set_active (true);
|
iembedded->set_active (true);
|
||||||
ckbBlendCMSMatrix->set_sensitive (false);
|
if (!batchMode) {
|
||||||
|
ckbBlendCMSMatrix->set_sensitive (false);
|
||||||
|
}
|
||||||
updateDCP(pp->icm.dcpIlluminant, "");
|
updateDCP(pp->icm.dcpIlluminant, "");
|
||||||
} else if ((pp->icm.input == "(cameraICC)") && icameraICC->get_state() != Gtk::STATE_INSENSITIVE) {
|
} else if ((pp->icm.input == "(cameraICC)") && icameraICC->get_state() != Gtk::STATE_INSENSITIVE) {
|
||||||
icameraICC->set_active (true);
|
icameraICC->set_active (true);
|
||||||
ckbBlendCMSMatrix->set_sensitive (true);
|
if (!batchMode) {
|
||||||
|
ckbBlendCMSMatrix->set_sensitive (true);
|
||||||
|
}
|
||||||
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
||||||
} else if ((pp->icm.input == "(cameraICC)") && icamera->get_state() != Gtk::STATE_INSENSITIVE && icameraICC->get_state() == Gtk::STATE_INSENSITIVE) {
|
} 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
|
// 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
|
// therefore falling back UI to explicitly reflect the (camera) option
|
||||||
icamera->set_active (true);
|
icamera->set_active (true);
|
||||||
ckbBlendCMSMatrix->set_sensitive (false);
|
if (!batchMode) {
|
||||||
|
ckbBlendCMSMatrix->set_sensitive (false);
|
||||||
|
}
|
||||||
updateDCP(pp->icm.dcpIlluminant, "");
|
updateDCP(pp->icm.dcpIlluminant, "");
|
||||||
} else if ((pp->icm.input == "(cameraICC)") && icamera->get_state() == Gtk::STATE_INSENSITIVE && icameraICC->get_state() == Gtk::STATE_INSENSITIVE) {
|
} 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).
|
// If neither (camera) nor (cameraICC) are available, as is the case when loading a non-raw, activate (embedded).
|
||||||
iembedded->set_active (true);
|
iembedded->set_active (true);
|
||||||
ckbBlendCMSMatrix->set_sensitive (false);
|
if (!batchMode) {
|
||||||
|
ckbBlendCMSMatrix->set_sensitive (false);
|
||||||
|
}
|
||||||
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
|
||||||
} else if ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() != Gtk::STATE_INSENSITIVE) {
|
} else if ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() != Gtk::STATE_INSENSITIVE) {
|
||||||
icamera->set_active (true);
|
icamera->set_active (true);
|
||||||
ckbBlendCMSMatrix->set_sensitive (false);
|
if (!batchMode) {
|
||||||
|
ckbBlendCMSMatrix->set_sensitive (false);
|
||||||
|
}
|
||||||
updateDCP(pp->icm.dcpIlluminant, "");
|
updateDCP(pp->icm.dcpIlluminant, "");
|
||||||
} else {
|
} else {
|
||||||
ifromfile->set_active (true);
|
ifromfile->set_active (true);
|
||||||
oldip = pp->icm.input.substr(5); // cut of "file:"
|
oldip = pp->icm.input.substr(5); // cut of "file:"
|
||||||
ipDialog->set_filename (pp->icm.input.substr(5));
|
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));
|
updateDCP(pp->icm.dcpIlluminant, pp->icm.input.substr(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,8 +572,9 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
if (onames->get_active_row_number() == -1) {
|
if (onames->get_active_row_number() == -1) {
|
||||||
onames->set_active_text (M("TP_ICM_NOICM"));
|
onames->set_active_text (M("TP_ICM_NOICM"));
|
||||||
}
|
}
|
||||||
ointent->set_active(pp->icm.outputIntent);
|
ointent->setSelected (pp->icm.outputIntent);
|
||||||
|
|
||||||
|
obpc->set_active (pp->icm.outputBPC);
|
||||||
ckbToneCurve->set_active (pp->icm.toneCurve);
|
ckbToneCurve->set_active (pp->icm.toneCurve);
|
||||||
lastToneCurve = pp->icm.toneCurve;
|
lastToneCurve = pp->icm.toneCurve;
|
||||||
ckbApplyLookTable->set_active (pp->icm.applyLookTable);
|
ckbApplyLookTable->set_active (pp->icm.applyLookTable);
|
||||||
@ -539,22 +587,29 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
ckbBlendCMSMatrix->set_active (pp->icm.blendCMSMatrix);
|
ckbBlendCMSMatrix->set_active (pp->icm.blendCMSMatrix);
|
||||||
lastBlendCMSMatrix = 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);
|
freegamma->set_active (pp->icm.freegamma);
|
||||||
lastgamfree = 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);
|
||||||
|
updateRenderingIntent(pp->icm.output);
|
||||||
|
}
|
||||||
|
|
||||||
gampos->setValue (pp->icm.gampos);
|
gampos->setValue (pp->icm.gampos);
|
||||||
slpos->setValue (pp->icm.slpos);
|
slpos->setValue (pp->icm.slpos);
|
||||||
|
|
||||||
if (pedited) {
|
if (pedited) {
|
||||||
iunchanged->set_active (!pedited->icm.input);
|
iunchanged->set_active (!pedited->icm.input);
|
||||||
|
obpc->set_inconsistent(!pedited->icm.outputBPC);
|
||||||
ckbToneCurve->set_inconsistent(!pedited->icm.toneCurve);
|
ckbToneCurve->set_inconsistent(!pedited->icm.toneCurve);
|
||||||
ckbApplyLookTable->set_inconsistent(!pedited->icm.applyLookTable);
|
ckbApplyLookTable->set_inconsistent(!pedited->icm.applyLookTable);
|
||||||
ckbApplyBaselineExposureOffset->set_inconsistent(!pedited->icm.applyBaselineExposureOffset);
|
ckbApplyBaselineExposureOffset->set_inconsistent(!pedited->icm.applyBaselineExposureOffset);
|
||||||
ckbApplyHueSatMap->set_inconsistent(!pedited->icm.applyHueSatMap);
|
ckbApplyHueSatMap->set_inconsistent(!pedited->icm.applyHueSatMap);
|
||||||
ckbBlendCMSMatrix->set_inconsistent(!pedited->icm.blendCMSMatrix);
|
ckbBlendCMSMatrix->set_inconsistent(!pedited->icm.blendCMSMatrix);
|
||||||
|
freegamma->set_inconsistent (!pedited->icm.freegamma);
|
||||||
|
|
||||||
if (!pedited->icm.working) {
|
if (!pedited->icm.working) {
|
||||||
wnames->set_active_text(M("GENERAL_UNCHANGED"));
|
wnames->set_active_text(M("GENERAL_UNCHANGED"));
|
||||||
@ -565,7 +620,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pedited->icm.outputIntent) {
|
if (!pedited->icm.outputIntent) {
|
||||||
ointent->set_active_text(M("GENERAL_UNCHANGED"));
|
ointent->setSelected (4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pedited->icm.dcpIlluminant) {
|
if (!pedited->icm.dcpIlluminant) {
|
||||||
@ -589,6 +644,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
hsmconn.block(false);
|
hsmconn.block(false);
|
||||||
gamcsconn.block (false);
|
gamcsconn.block (false);
|
||||||
ipc.block (false);
|
ipc.block (false);
|
||||||
|
obpcconn.block (false);
|
||||||
|
|
||||||
enableListener ();
|
enableListener ();
|
||||||
}
|
}
|
||||||
@ -628,7 +684,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
|
|||||||
pp->icm.output = onames->get_active_text();
|
pp->icm.output = onames->get_active_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ointentVal = ointent->get_active_row_number();
|
int ointentVal = ointent->getSelected ();
|
||||||
if (ointentVal >= 0 && ointentVal < RI__COUNT) {
|
if (ointentVal >= 0 && ointentVal < RI__COUNT) {
|
||||||
pp->icm.outputIntent = static_cast<RenderingIntent>(ointentVal);
|
pp->icm.outputIntent = static_cast<RenderingIntent>(ointentVal);
|
||||||
} else {
|
} else {
|
||||||
@ -666,12 +722,14 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
|
|||||||
pp->icm.blendCMSMatrix = ckbBlendCMSMatrix->get_active ();
|
pp->icm.blendCMSMatrix = ckbBlendCMSMatrix->get_active ();
|
||||||
pp->icm.gampos = (double) gampos->getValue();
|
pp->icm.gampos = (double) gampos->getValue();
|
||||||
pp->icm.slpos = (double) slpos->getValue();
|
pp->icm.slpos = (double) slpos->getValue();
|
||||||
|
pp->icm.outputBPC = obpc->get_active ();
|
||||||
|
|
||||||
if (pedited) {
|
if (pedited) {
|
||||||
pedited->icm.input = !iunchanged->get_active ();
|
pedited->icm.input = !iunchanged->get_active ();
|
||||||
pedited->icm.working = wnames->get_active_text() != M("GENERAL_UNCHANGED");
|
pedited->icm.working = wnames->get_active_text() != M("GENERAL_UNCHANGED");
|
||||||
pedited->icm.output = onames->get_active_text() != M("GENERAL_UNCHANGED");
|
pedited->icm.output = onames->get_active_text() != M("GENERAL_UNCHANGED");
|
||||||
pedited->icm.outputIntent = ointent->get_active_text() != M("GENERAL_UNCHANGED");
|
pedited->icm.outputIntent = ointent->getSelected () < 4;
|
||||||
|
pedited->icm.outputBPC = !obpc->get_inconsistent ();
|
||||||
pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED");
|
pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED");
|
||||||
pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent ();
|
pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent ();
|
||||||
pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent ();
|
pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent ();
|
||||||
@ -708,7 +766,7 @@ void ICMPanel::setAdjusterBehavior (bool gammaadd, bool slopeadd)
|
|||||||
void ICMPanel::adjusterChanged (Adjuster* a, double newval)
|
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);
|
Glib::ustring costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), newval);
|
||||||
|
|
||||||
@ -746,7 +804,7 @@ void ICMPanel::dcpIlluminantChanged()
|
|||||||
|
|
||||||
void ICMPanel::toneCurveChanged()
|
void ICMPanel::toneCurveChanged()
|
||||||
{
|
{
|
||||||
if (batchMode) {
|
if (multiImage) {
|
||||||
if (ckbToneCurve->get_inconsistent()) {
|
if (ckbToneCurve->get_inconsistent()) {
|
||||||
ckbToneCurve->set_inconsistent (false);
|
ckbToneCurve->set_inconsistent (false);
|
||||||
tcurveconn.block (true);
|
tcurveconn.block (true);
|
||||||
@ -760,13 +818,19 @@ void ICMPanel::toneCurveChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
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()
|
void ICMPanel::applyLookTableChanged()
|
||||||
{
|
{
|
||||||
if (batchMode) {
|
if (multiImage) {
|
||||||
if (ckbApplyLookTable->get_inconsistent()) {
|
if (ckbApplyLookTable->get_inconsistent()) {
|
||||||
ckbApplyLookTable->set_inconsistent (false);
|
ckbApplyLookTable->set_inconsistent (false);
|
||||||
ltableconn.block (true);
|
ltableconn.block (true);
|
||||||
@ -780,13 +844,19 @@ void ICMPanel::applyLookTableChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
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()
|
void ICMPanel::applyBaselineExposureOffsetChanged()
|
||||||
{
|
{
|
||||||
if (batchMode) {
|
if (multiImage) {
|
||||||
if (ckbApplyBaselineExposureOffset->get_inconsistent()) {
|
if (ckbApplyBaselineExposureOffset->get_inconsistent()) {
|
||||||
ckbApplyBaselineExposureOffset->set_inconsistent (false);
|
ckbApplyBaselineExposureOffset->set_inconsistent (false);
|
||||||
beoconn.block (true);
|
beoconn.block (true);
|
||||||
@ -800,13 +870,19 @@ void ICMPanel::applyBaselineExposureOffsetChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
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()
|
void ICMPanel::applyHueSatMapChanged()
|
||||||
{
|
{
|
||||||
if (batchMode) {
|
if (multiImage) {
|
||||||
if (ckbApplyHueSatMap->get_inconsistent()) {
|
if (ckbApplyHueSatMap->get_inconsistent()) {
|
||||||
ckbApplyHueSatMap->set_inconsistent (false);
|
ckbApplyHueSatMap->set_inconsistent (false);
|
||||||
hsmconn.block (true);
|
hsmconn.block (true);
|
||||||
@ -820,7 +896,13 @@ void ICMPanel::applyHueSatMapChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,7 +939,7 @@ void ICMPanel::ipChanged ()
|
|||||||
|
|
||||||
void ICMPanel::blendCMSMatrixChanged()
|
void ICMPanel::blendCMSMatrixChanged()
|
||||||
{
|
{
|
||||||
if (batchMode) {
|
if (multiImage) {
|
||||||
if (ckbBlendCMSMatrix->get_inconsistent()) {
|
if (ckbBlendCMSMatrix->get_inconsistent()) {
|
||||||
ckbBlendCMSMatrix->set_inconsistent (false);
|
ckbBlendCMSMatrix->set_inconsistent (false);
|
||||||
blendcmsconn.block (true);
|
blendcmsconn.block (true);
|
||||||
@ -871,13 +953,19 @@ void ICMPanel::blendCMSMatrixChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
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()
|
void ICMPanel::GamChanged()
|
||||||
{
|
{
|
||||||
if (batchMode) {
|
if (multiImage) {
|
||||||
if (freegamma->get_inconsistent()) {
|
if (freegamma->get_inconsistent()) {
|
||||||
freegamma->set_inconsistent (false);
|
freegamma->set_inconsistent (false);
|
||||||
gamcsconn.block (true);
|
gamcsconn.block (true);
|
||||||
@ -891,31 +979,90 @@ void ICMPanel::GamChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
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"));
|
listener->panelChanged (EvGAMFREE, M("GENERAL_ENABLED"));
|
||||||
onames->set_sensitive(!freegamma->get_active());//disabled choice
|
if (!batchMode) {
|
||||||
wgamma->set_sensitive(!freegamma->get_active());
|
onames->set_sensitive(false);//disabled choice
|
||||||
|
wgamma->set_sensitive(false);
|
||||||
|
gampos->set_sensitive(true);
|
||||||
|
slpos->set_sensitive(true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
listener->panelChanged (EvGAMFREE, M("GENERAL_DISABLED"));
|
listener->panelChanged (EvGAMFREE, M("GENERAL_DISABLED"));
|
||||||
onames->set_sensitive(!freegamma->get_active() && wgamma->get_active_row_number() == 0);
|
if (!batchMode) {
|
||||||
wgamma->set_sensitive(!freegamma->get_active());
|
onames->set_sensitive(wgamma->get_active_row_number() == 0);
|
||||||
|
wgamma->set_sensitive(true);
|
||||||
|
gampos->set_sensitive(false);
|
||||||
|
slpos->set_sensitive(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMPanel::opChanged ()
|
void ICMPanel::opChanged ()
|
||||||
{
|
{
|
||||||
|
if (!batchMode) {
|
||||||
|
updateRenderingIntent(onames->get_active_text());
|
||||||
|
}
|
||||||
|
|
||||||
if (listener) {
|
if (listener) {
|
||||||
listener->panelChanged (EvOProfile, onames->get_active_text());
|
listener->panelChanged (EvOProfile, onames->get_active_text());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMPanel::oiChanged ()
|
void ICMPanel::oiChanged (int n)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (listener) {
|
if (listener) {
|
||||||
listener->panelChanged (EvOIntent, ointent->get_active_text());
|
Glib::ustring str;
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
str = M("PREFERENCES_INTENT_PERCEPTUAL");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
str = M("PREFERENCES_INTENT_RELATIVE");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
str = M("PREFERENCES_INTENT_SATURATION");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
str = M("PREFERENCES_INTENT_ABSOLUTE");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
|
str = M("GENERAL_UNCHANGED");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
listener->panelChanged (EvOIntent, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,6 +1164,8 @@ void ICMPanel::setBatchMode (bool batchMode)
|
|||||||
iVBox->reorder_child (*iunchanged, 5);
|
iVBox->reorder_child (*iunchanged, 5);
|
||||||
removeIfThere (this, saveRef);
|
removeIfThere (this, saveRef);
|
||||||
onames->append (M("GENERAL_UNCHANGED"));
|
onames->append (M("GENERAL_UNCHANGED"));
|
||||||
|
ointent->addEntry("unchanged-22.png", M("GENERAL_UNCHANGED"));
|
||||||
|
ointent->show();
|
||||||
wnames->append (M("GENERAL_UNCHANGED"));
|
wnames->append (M("GENERAL_UNCHANGED"));
|
||||||
wgamma->append (M("GENERAL_UNCHANGED"));
|
wgamma->append (M("GENERAL_UNCHANGED"));
|
||||||
dcpIll->append (M("GENERAL_UNCHANGED"));
|
dcpIll->append (M("GENERAL_UNCHANGED"));
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
|
|
||||||
#include "toolpanel.h"
|
#include "toolpanel.h"
|
||||||
|
#include "popupbutton.h"
|
||||||
#include "../rtengine/imagedata.h"
|
#include "../rtengine/imagedata.h"
|
||||||
|
|
||||||
class ICMPanelListener
|
class ICMPanelListener
|
||||||
@ -53,6 +54,8 @@ protected:
|
|||||||
sigc::connection beoconn;
|
sigc::connection beoconn;
|
||||||
bool lastApplyHueSatMap;
|
bool lastApplyHueSatMap;
|
||||||
sigc::connection hsmconn;
|
sigc::connection hsmconn;
|
||||||
|
bool lastobpc;
|
||||||
|
sigc::connection obpcconn;
|
||||||
bool lastBlendCMSMatrix;
|
bool lastBlendCMSMatrix;
|
||||||
bool isBatchMode;
|
bool isBatchMode;
|
||||||
sigc::connection blendcmsconn;
|
sigc::connection blendcmsconn;
|
||||||
@ -60,6 +63,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
Gtk::VBox * iVBox;
|
Gtk::VBox * iVBox;
|
||||||
|
|
||||||
|
Gtk::CheckButton* obpc;
|
||||||
Gtk::CheckButton* freegamma;
|
Gtk::CheckButton* freegamma;
|
||||||
Gtk::RadioButton* inone;
|
Gtk::RadioButton* inone;
|
||||||
|
|
||||||
@ -78,7 +82,7 @@ private:
|
|||||||
MyComboBoxText* wgamma;
|
MyComboBoxText* wgamma;
|
||||||
|
|
||||||
MyComboBoxText* onames;
|
MyComboBoxText* onames;
|
||||||
MyComboBoxText* ointent;
|
PopUpButton* ointent;
|
||||||
Gtk::RadioButton* ofromdir;
|
Gtk::RadioButton* ofromdir;
|
||||||
Gtk::RadioButton* ofromfile;
|
Gtk::RadioButton* ofromfile;
|
||||||
Gtk::RadioButton* iunchanged;
|
Gtk::RadioButton* iunchanged;
|
||||||
@ -95,6 +99,7 @@ private:
|
|||||||
Glib::ustring lastRefFilename;
|
Glib::ustring lastRefFilename;
|
||||||
Glib::ustring camName;
|
Glib::ustring camName;
|
||||||
void updateDCP(int dcpIlluminant, Glib::ustring dcp_name);
|
void updateDCP(int dcpIlluminant, Glib::ustring dcp_name);
|
||||||
|
void updateRenderingIntent (const Glib::ustring &profile);
|
||||||
public:
|
public:
|
||||||
ICMPanel ();
|
ICMPanel ();
|
||||||
|
|
||||||
@ -107,7 +112,8 @@ public:
|
|||||||
|
|
||||||
void wpChanged ();
|
void wpChanged ();
|
||||||
void opChanged ();
|
void opChanged ();
|
||||||
void oiChanged ();
|
void oiChanged (int n);
|
||||||
|
void oBPCChanged ();
|
||||||
void ipChanged ();
|
void ipChanged ();
|
||||||
void gpChanged ();
|
void gpChanged ();
|
||||||
void GamChanged ();
|
void GamChanged ();
|
||||||
|
@ -471,6 +471,7 @@ void Options::setDefaults ()
|
|||||||
fastexport_icm_working = "ProPhoto";
|
fastexport_icm_working = "ProPhoto";
|
||||||
fastexport_icm_output = "RT_sRGB";
|
fastexport_icm_output = "RT_sRGB";
|
||||||
fastexport_icm_outputIntent = rtengine::RI_RELATIVE;
|
fastexport_icm_outputIntent = rtengine::RI_RELATIVE;
|
||||||
|
fastexport_icm_outputBPC = true;
|
||||||
fastexport_icm_gamma = "default";
|
fastexport_icm_gamma = "default";
|
||||||
fastexport_resize_enabled = true;
|
fastexport_resize_enabled = true;
|
||||||
fastexport_resize_scale = 1;
|
fastexport_resize_scale = 1;
|
||||||
@ -636,6 +637,7 @@ void Options::setDefaults ()
|
|||||||
|
|
||||||
rtSettings.monitorProfile = Glib::ustring();
|
rtSettings.monitorProfile = Glib::ustring();
|
||||||
rtSettings.monitorIntent = rtengine::RI_RELATIVE;
|
rtSettings.monitorIntent = rtengine::RI_RELATIVE;
|
||||||
|
rtSettings.monitorBPC = true;
|
||||||
rtSettings.autoMonitorProfile = false;
|
rtSettings.autoMonitorProfile = false;
|
||||||
rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows)
|
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"
|
rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile"
|
||||||
@ -1471,6 +1473,10 @@ int Options::readFromFile (Glib::ustring fname)
|
|||||||
rtSettings.monitorIntent = static_cast<rtengine::RenderingIntent> (keyFile.get_integer ("Color Management", "Intent"));
|
rtSettings.monitorIntent = static_cast<rtengine::RenderingIntent> (keyFile.get_integer ("Color Management", "Intent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyFile.has_key ("Color Management", "MonitorBPC")) {
|
||||||
|
rtSettings.monitorBPC = keyFile.get_boolean("Color Management", "MonitorBPC");
|
||||||
|
}
|
||||||
|
|
||||||
if (keyFile.has_key ("Color Management", "CRI")) {
|
if (keyFile.has_key ("Color Management", "CRI")) {
|
||||||
rtSettings.CRI_color = keyFile.get_integer ("Color Management", "CRI");
|
rtSettings.CRI_color = keyFile.get_integer ("Color Management", "CRI");
|
||||||
}
|
}
|
||||||
@ -1727,6 +1733,10 @@ int Options::readFromFile (Glib::ustring fname)
|
|||||||
fastexport_icm_outputIntent = static_cast<rtengine::RenderingIntent> (keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" ));
|
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" )) {
|
if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) {
|
||||||
fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" );
|
fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" );
|
||||||
}
|
}
|
||||||
@ -1803,7 +1813,7 @@ bool Options::safeDirGet (const Glib::KeyFile& keyFile, const Glib::ustring& sec
|
|||||||
const Glib::ustring& entryName, Glib::ustring& destination)
|
const Glib::ustring& entryName, Glib::ustring& destination)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (keyFile.has_key (section, entryName) && !keyFile.get_string (section, entryName).empty ()) {
|
if (keyFile.has_key (section, entryName) && !keyFile.get_string (section, entryName).empty ()) {
|
||||||
destination = keyFile.get_string (section, entryName);
|
destination = keyFile.get_string (section, entryName);
|
||||||
return true;
|
return true;
|
||||||
@ -2034,6 +2044,7 @@ int Options::saveToFile (Glib::ustring fname)
|
|||||||
keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab);
|
keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab);
|
||||||
keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut);
|
keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut);
|
||||||
keyFile.set_integer ("Color Management", "Intent", rtSettings.monitorIntent);
|
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", "view", rtSettings.viewingdevice);
|
||||||
keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey);
|
keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey);
|
||||||
keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc);
|
keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc);
|
||||||
@ -2102,6 +2113,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_working" , fastexport_icm_working );
|
||||||
keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output );
|
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_intent" , fastexport_icm_outputIntent );
|
||||||
|
keyFile.set_boolean ("Fast Export", "fastexport_icm_output_bpc" , fastexport_icm_outputBPC );
|
||||||
keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma );
|
keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma );
|
||||||
keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled );
|
keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled );
|
||||||
keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale );
|
keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale );
|
||||||
|
@ -269,6 +269,7 @@ public:
|
|||||||
Glib::ustring fastexport_icm_working;
|
Glib::ustring fastexport_icm_working;
|
||||||
Glib::ustring fastexport_icm_output;
|
Glib::ustring fastexport_icm_output;
|
||||||
rtengine::RenderingIntent fastexport_icm_outputIntent;
|
rtengine::RenderingIntent fastexport_icm_outputIntent;
|
||||||
|
bool fastexport_icm_outputBPC;
|
||||||
Glib::ustring fastexport_icm_gamma;
|
Glib::ustring fastexport_icm_gamma;
|
||||||
bool fastexport_resize_enabled;
|
bool fastexport_resize_enabled;
|
||||||
double fastexport_resize_scale;
|
double fastexport_resize_scale;
|
||||||
|
@ -353,8 +353,9 @@ void ParamsEdited::set (bool v)
|
|||||||
icm.working = v;
|
icm.working = v;
|
||||||
icm.output = v;
|
icm.output = v;
|
||||||
icm.outputIntent = v;
|
icm.outputIntent = v;
|
||||||
|
icm.outputBPC = v;
|
||||||
icm.gamma = v;
|
icm.gamma = v;
|
||||||
icm.freegamma = v;
|
icm.freegamma = v;
|
||||||
icm.gampos = v;
|
icm.gampos = v;
|
||||||
icm.slpos = v;
|
icm.slpos = v;
|
||||||
raw.bayersensor.method = 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.working = icm.working && p.icm.working == other.icm.working;
|
||||||
icm.output = icm.output && p.icm.output == other.icm.output;
|
icm.output = icm.output && p.icm.output == other.icm.output;
|
||||||
icm.outputIntent = icm.outputIntent && p.icm.outputIntent == other.icm.outputIntent;
|
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.gamma = icm.gamma && p.icm.gamma == other.icm.gamma;
|
||||||
icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma;
|
icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma;
|
||||||
icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos;
|
icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos;
|
||||||
@ -2210,8 +2212,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
|
|||||||
toEdit.icm.outputIntent = mods.icm.outputIntent;
|
toEdit.icm.outputIntent = mods.icm.outputIntent;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos;
|
if (icm.outputBPC) {
|
||||||
//if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos;
|
toEdit.icm.outputBPC = mods.icm.outputBPC;
|
||||||
|
}
|
||||||
|
|
||||||
if (icm.gampos) {
|
if (icm.gampos) {
|
||||||
toEdit.icm.gampos = dontforceSet && options.baBehav[ADDSET_FREE_OUPUT_GAMMA] ? toEdit.icm.gampos + mods.icm.gampos : mods.icm.gampos;
|
toEdit.icm.gampos = dontforceSet && options.baBehav[ADDSET_FREE_OUPUT_GAMMA] ? toEdit.icm.gampos + mods.icm.gampos : mods.icm.gampos;
|
||||||
}
|
}
|
||||||
|
@ -544,6 +544,7 @@ public:
|
|||||||
bool working;
|
bool working;
|
||||||
bool output;
|
bool output;
|
||||||
bool outputIntent;
|
bool outputIntent;
|
||||||
|
bool outputBPC;
|
||||||
bool gamma;
|
bool gamma;
|
||||||
bool gampos;
|
bool gampos;
|
||||||
bool slpos;
|
bool slpos;
|
||||||
|
@ -680,15 +680,19 @@ Gtk::Widget* Preferences::getColorManagementPanel ()
|
|||||||
monProfile->append (M("PREFERENCES_PROFILE_NONE"));
|
monProfile->append (M("PREFERENCES_PROFILE_NONE"));
|
||||||
monProfile->set_active (0);
|
monProfile->set_active (0);
|
||||||
|
|
||||||
const std::vector<Glib::ustring> profiles = rtengine::ICCStore::getInstance ()->getProfiles ();
|
const std::vector<Glib::ustring> profiles = rtengine::ICCStore::getInstance ()->getProfiles (true);
|
||||||
for (std::vector<Glib::ustring>::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile)
|
for (std::vector<Glib::ustring>::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile)
|
||||||
monProfile->append (*profile);
|
monProfile->append (*profile);
|
||||||
|
|
||||||
monIntent->append (M("PREFERENCES_INTENT_RELATIVE"));
|
// same order as the enum
|
||||||
monIntent->append (M("PREFERENCES_INTENT_PERCEPTUAL"));
|
monIntent->append (M("PREFERENCES_INTENT_PERCEPTUAL"));
|
||||||
|
monIntent->append (M("PREFERENCES_INTENT_RELATIVE"));
|
||||||
monIntent->append (M("PREFERENCES_INTENT_ABSOLUTE"));
|
monIntent->append (M("PREFERENCES_INTENT_ABSOLUTE"));
|
||||||
monIntent->set_active (1);
|
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));
|
iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged));
|
||||||
|
|
||||||
#if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851
|
#if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851
|
||||||
@ -698,22 +702,24 @@ Gtk::Widget* Preferences::getColorManagementPanel ()
|
|||||||
|
|
||||||
Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2));
|
Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2));
|
||||||
int row = 0;
|
int row = 0;
|
||||||
colt->attach (*pdlabel, 0, 1, row, row + 1, Gtk::FILL, 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, 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
|
#if !defined(__APPLE__) // monitor profile not supported on apple
|
||||||
++row;
|
++row;
|
||||||
colt->attach (*mplabel, 0, 1, row, row + 1, Gtk::FILL, 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, Gtk::SHRINK, 2, 2);
|
colt->attach (*monProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
++row;
|
++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
|
||||||
#endif
|
#endif
|
||||||
++row;
|
++row;
|
||||||
colt->attach (*milabel, 0, 1, row, row + 1, Gtk::FILL, 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, 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 (*colt, Gtk::PACK_SHRINK, 4);
|
||||||
|
|
||||||
|
mvbcm->pack_start (*monBPC, Gtk::PACK_SHRINK, 4);
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
autoMonProfileToggled();
|
autoMonProfileToggled();
|
||||||
#endif
|
#endif
|
||||||
@ -1450,15 +1456,16 @@ void Preferences::storePreferences ()
|
|||||||
switch (monIntent->get_active_row_number ()) {
|
switch (monIntent->get_active_row_number ()) {
|
||||||
default:
|
default:
|
||||||
case 0:
|
case 0:
|
||||||
moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE;
|
moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL;
|
moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE;
|
moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
moptions.rtSettings.monitorBPC = monBPC->get_active ();
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
|
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
|
||||||
#endif
|
#endif
|
||||||
@ -1579,16 +1586,17 @@ void Preferences::fillPreferences ()
|
|||||||
setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0);
|
setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0);
|
||||||
switch (moptions.rtSettings.monitorIntent) {
|
switch (moptions.rtSettings.monitorIntent) {
|
||||||
default:
|
default:
|
||||||
case rtengine::RI_RELATIVE:
|
case rtengine::RI_PERCEPTUAL:
|
||||||
monIntent->set_active (0);
|
monIntent->set_active (0);
|
||||||
break;
|
break;
|
||||||
case rtengine::RI_PERCEPTUAL:
|
case rtengine::RI_RELATIVE:
|
||||||
monIntent->set_active (1);
|
monIntent->set_active (1);
|
||||||
break;
|
break;
|
||||||
case rtengine::RI_ABSOLUTE:
|
case rtengine::RI_ABSOLUTE:
|
||||||
monIntent->set_active (2);
|
monIntent->set_active (2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
monBPC->set_active (moptions.rtSettings.monitorBPC);
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile);
|
cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile);
|
||||||
#endif
|
#endif
|
||||||
|
@ -97,6 +97,7 @@ protected:
|
|||||||
Gtk::FileChooserButton* iccDir;
|
Gtk::FileChooserButton* iccDir;
|
||||||
Gtk::ComboBoxText* monProfile;
|
Gtk::ComboBoxText* monProfile;
|
||||||
Gtk::ComboBoxText* monIntent;
|
Gtk::ComboBoxText* monIntent;
|
||||||
|
Gtk::CheckButton* monBPC;
|
||||||
Gtk::CheckButton* cbAutoMonProfile;
|
Gtk::CheckButton* cbAutoMonProfile;
|
||||||
//Gtk::CheckButton* cbAutocielab;
|
//Gtk::CheckButton* cbAutocielab;
|
||||||
Gtk::CheckButton* cbciecamfloat;
|
Gtk::CheckButton* cbciecamfloat;
|
||||||
|
655
tools/color_management.svg
Normal file
@ -0,0 +1,655 @@
|
|||||||
|
<?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="marker10113"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path10115"
|
||||||
|
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:#b049e1;stroke-width:1pt;stroke-opacity:1;fill:#b049e1;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="marker9939"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path9941"
|
||||||
|
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:#b049e1;stroke-width:1pt;stroke-opacity:1;fill:#b049e1;fill-opacity:1"
|
||||||
|
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:isstock="true"
|
||||||
|
style="overflow:visible;"
|
||||||
|
id="marker9189"
|
||||||
|
refX="0.0"
|
||||||
|
refY="0.0"
|
||||||
|
orient="auto"
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<path
|
||||||
|
transform="scale(0.2) rotate(180) translate(6,0)"
|
||||||
|
style="fill-rule:evenodd;stroke:#b049e1;stroke-width:1pt;stroke-opacity:1;fill:#b049e1;fill-opacity:1"
|
||||||
|
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 "
|
||||||
|
id="path9191" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:isstock="true"
|
||||||
|
style="overflow:visible;"
|
||||||
|
id="marker4296"
|
||||||
|
refX="0.0"
|
||||||
|
refY="0.0"
|
||||||
|
orient="auto"
|
||||||
|
inkscape:stockid="Arrow1Send">
|
||||||
|
<path
|
||||||
|
transform="scale(0.2) rotate(180) translate(6,0)"
|
||||||
|
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
|
||||||
|
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 "
|
||||||
|
id="path4298" />
|
||||||
|
</marker>
|
||||||
|
<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"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<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="489.45925"
|
||||||
|
inkscape:cy="597.68828"
|
||||||
|
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 />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Calque 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-308.26772)">
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#b049e1;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker10113)"
|
||||||
|
d="m 871.82971,670.64952 0,50.45433"
|
||||||
|
id="path10111"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path9187"
|
||||||
|
d="m 548.40112,670.64952 0,50.45433"
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#b049e1;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9189)" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="csc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4996"
|
||||||
|
d="m 666.10066,635.08041 c 31.37496,-1.49737 37.63639,-52.56259 42.33564,-92.54896 4.49653,-38.26138 50.69343,-47.46535 84.39106,-0.36174"
|
||||||
|
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)" />
|
||||||
|
<rect
|
||||||
|
y="579.82043"
|
||||||
|
x="423.40112"
|
||||||
|
height="92.857147"
|
||||||
|
width="250"
|
||||||
|
id="rect5442"
|
||||||
|
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||||
|
<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 492.32787,440.64952 c 16.21054,39.59059 30.90653,57.74251 30.90653,98.45433"
|
||||||
|
id="path4200"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4218"
|
||||||
|
d="m 534.03112,397.20982 c 130.59165,0 248.85289,32.24077 287.24555,140.161"
|
||||||
|
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)" />
|
||||||
|
<rect
|
||||||
|
style="opacity:1;fill:#ffffff;fill-opacity:0.71270716;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
id="rect10399"
|
||||||
|
width="169.52106"
|
||||||
|
height="31.025021"
|
||||||
|
x="599.28571"
|
||||||
|
y="405.36221" />
|
||||||
|
<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 394.53933,434.19203 c -31.92389,48.56808 -43.48293,40.68411 -98.97824,105.07044"
|
||||||
|
id="path4202"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<rect
|
||||||
|
style="opacity:1;fill:#ffffff;fill-opacity:0.71270716;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
id="rect7950"
|
||||||
|
width="167.56383"
|
||||||
|
height="42.952511"
|
||||||
|
x="236.2933"
|
||||||
|
y="459.36221" />
|
||||||
|
<rect
|
||||||
|
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"
|
||||||
|
id="rect4190"
|
||||||
|
width="250"
|
||||||
|
height="29.285715"
|
||||||
|
x="423.40112"
|
||||||
|
y="550.53473" />
|
||||||
|
<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="436.6803"
|
||||||
|
y="569.3158"
|
||||||
|
id="text4146"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="436.6803"
|
||||||
|
y="569.3158"
|
||||||
|
id="tspan4180"
|
||||||
|
style="font-size:15px">Output ICC profile & intent</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
id="rect5444"
|
||||||
|
width="250"
|
||||||
|
height="92.857147"
|
||||||
|
x="746.82971"
|
||||||
|
y="579.82043" />
|
||||||
|
<rect
|
||||||
|
y="550.53473"
|
||||||
|
x="746.82971"
|
||||||
|
height="29.285715"
|
||||||
|
width="250"
|
||||||
|
id="rect5408"
|
||||||
|
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
|
||||||
|
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="762.99524"
|
||||||
|
y="569.3158"
|
||||||
|
id="text4152"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
id="tspan4270"
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="762.99524"
|
||||||
|
y="569.3158"
|
||||||
|
style="font-size:15px">Monitor ICC profile & intent</tspan></text>
|
||||||
|
<g
|
||||||
|
id="g9171"
|
||||||
|
transform="translate(65.286377,16)">
|
||||||
|
<rect
|
||||||
|
y="713.55499"
|
||||||
|
x="731.54333"
|
||||||
|
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="761.94305"
|
||||||
|
x="762.66943"
|
||||||
|
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="761.94305"
|
||||||
|
x="762.66943"
|
||||||
|
id="tspan4160"
|
||||||
|
sodipodi:role="line">Monitor</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g9176"
|
||||||
|
transform="translate(68.218231,40)">
|
||||||
|
<rect
|
||||||
|
y="832.55505"
|
||||||
|
x="395.18289"
|
||||||
|
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="880.94312"
|
||||||
|
x="441.62637"
|
||||||
|
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="880.94312"
|
||||||
|
x="441.62637"
|
||||||
|
id="tspan4164"
|
||||||
|
sodipodi:role="line">Printer</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g9166"
|
||||||
|
transform="translate(71.411163,20)">
|
||||||
|
<rect
|
||||||
|
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"
|
||||||
|
id="rect4210"
|
||||||
|
width="200"
|
||||||
|
height="80"
|
||||||
|
x="376.98996"
|
||||||
|
y="711.33673" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4170"
|
||||||
|
y="757.54401"
|
||||||
|
x="417.12546"
|
||||||
|
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="757.54401"
|
||||||
|
x="417.12546"
|
||||||
|
id="tspan4172"
|
||||||
|
sodipodi:role="line">Output file</tspan></text>
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
y="457.36221"
|
||||||
|
x="469.28571"
|
||||||
|
height="31.025021"
|
||||||
|
width="82.14286"
|
||||||
|
id="rect7952"
|
||||||
|
style="opacity:1;fill:#ffffff;fill-opacity:0.71270716;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||||
|
<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="471.19366"
|
||||||
|
y="469.87708"
|
||||||
|
id="text4182"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4184"
|
||||||
|
x="471.19366"
|
||||||
|
y="469.87708"
|
||||||
|
style="font-size:10px">Soft-proofing path</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="471.19366"
|
||||||
|
y="482.37708"
|
||||||
|
style="font-size:10px"
|
||||||
|
id="tspan10377">(Output Black Point Compensation)</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4204"
|
||||||
|
y="471.25275"
|
||||||
|
x="318.36606"
|
||||||
|
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="471.25275"
|
||||||
|
x="318.36606"
|
||||||
|
id="tspan4206"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:10px;text-align:center;text-anchor:middle">Only if</tspan><tspan
|
||||||
|
y="483.75275"
|
||||||
|
x="318.36606"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:10px;text-align:center;text-anchor:middle"
|
||||||
|
id="tspan5382">options.rtSettings.HistogramWorking = 1</tspan><tspan
|
||||||
|
y="496.25275"
|
||||||
|
x="318.36606"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:10px;text-align:center;text-anchor:middle"
|
||||||
|
id="tspan10383">(Output Black Point Compensation)</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="359.46707"
|
||||||
|
y="361.55499" />
|
||||||
|
<g
|
||||||
|
id="g4220"
|
||||||
|
transform="translate(322.64831,127.10442)">
|
||||||
|
<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">L*a*b image</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">End of pipeline</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text5364"
|
||||||
|
y="417.30566"
|
||||||
|
x="599.33655"
|
||||||
|
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="417.30566"
|
||||||
|
x="599.33655"
|
||||||
|
id="tspan5366"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:10px">Normal path</tspan><tspan
|
||||||
|
y="429.80566"
|
||||||
|
x="599.33655"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:10px"
|
||||||
|
id="tspan10375">(Monitor Black Point Compensation)</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
id="rect5378"
|
||||||
|
width="300"
|
||||||
|
height="92.857147"
|
||||||
|
x="89.115433"
|
||||||
|
y="579.82043" />
|
||||||
|
<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="100.83148"
|
||||||
|
y="648.47211"
|
||||||
|
id="text5374"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:10px"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan5376"
|
||||||
|
x="100.83148"
|
||||||
|
y="648.47211">Used fo image analysis <tspan
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold'"
|
||||||
|
id="tspan7948">only</tspan> with</tspan><tspan
|
||||||
|
style="font-size:10px"
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="100.83148"
|
||||||
|
y="660.97211"
|
||||||
|
id="tspan5380">options.rtSettings.HistogramWorking = 1</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text5394"
|
||||||
|
y="648.47211"
|
||||||
|
x="436.97083"
|
||||||
|
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="648.47211"
|
||||||
|
x="436.97083"
|
||||||
|
id="tspan5396"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:10px">Used fo image analysis with</tspan><tspan
|
||||||
|
id="tspan5398"
|
||||||
|
y="660.97211"
|
||||||
|
x="436.97083"
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:10px">options.rtSettings.HistogramWorking = 0</tspan></text>
|
||||||
|
<rect
|
||||||
|
y="550.53473"
|
||||||
|
x="89.115433"
|
||||||
|
height="29.285715"
|
||||||
|
width="300"
|
||||||
|
id="rect5406"
|
||||||
|
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
|
||||||
|
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="100.88519"
|
||||||
|
y="569.3158"
|
||||||
|
id="text4136"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
id="tspan4266"
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="100.88519"
|
||||||
|
y="569.3158"
|
||||||
|
style="font-size:15px">Working space profile (output intent)</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text6976"
|
||||||
|
y="609.3158"
|
||||||
|
x="99.218933"
|
||||||
|
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
|
||||||
|
style="font-size:22.5px"
|
||||||
|
y="609.3158"
|
||||||
|
x="99.218933"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan6980">"Working" image</tspan></text>
|
||||||
|
<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="436.25916"
|
||||||
|
y="609.3158"
|
||||||
|
id="text6982"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
id="tspan6986"
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="436.25916"
|
||||||
|
y="609.3158"
|
||||||
|
style="font-size:22.5px">Output image *</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text7002"
|
||||||
|
y="609.3158"
|
||||||
|
x="762.25916"
|
||||||
|
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
|
||||||
|
style="font-size:22.5px"
|
||||||
|
y="609.3158"
|
||||||
|
x="762.25916"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan7004">Preview image</tspan></text>
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#b049e1;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9939)"
|
||||||
|
d="m 548.40112,810.64952 0,50.45433"
|
||||||
|
id="path9937"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:20px;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="69.700523"
|
||||||
|
y="1008.9257"
|
||||||
|
id="text10389"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan10391"
|
||||||
|
x="69.700523"
|
||||||
|
y="1008.9257"
|
||||||
|
style="font-size:12.5px">* When options.rtSettings.HistogramWorking = 1 and soft-proofing is enabled, the Output image does not really exist,</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="69.700523"
|
||||||
|
y="1024.5508"
|
||||||
|
style="font-size:12.5px"
|
||||||
|
id="tspan10393"> i.e. no memory is allocated, the CMM only makes a double conversion of each pixel of the Lab image</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 28 KiB |
1
tools/source_icons/scalable/spGamutCheck.file
Normal file
@ -0,0 +1 @@
|
|||||||
|
spGamutCheck.png,w22,actions
|
1344
tools/source_icons/scalable/spGamutCheck.svg
Normal file
After Width: | Height: | Size: 45 KiB |
2
tools/source_icons/scalable/unchanged.file
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
unchanged-22.png,w22,actions
|
||||||
|
unchanged-18.png,w18,actions
|
1357
tools/source_icons/scalable/unchanged.svg
Normal file
After Width: | Height: | Size: 45 KiB |