diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png
new file mode 100644
index 000000000..bb7e1a85d
Binary files /dev/null and b/rtdata/images/Dark/actions/intent-absolute.png differ
diff --git a/rtdata/images/Dark/actions/intent-perceptual.png b/rtdata/images/Dark/actions/intent-perceptual.png
new file mode 100644
index 000000000..d41e59458
Binary files /dev/null and b/rtdata/images/Dark/actions/intent-perceptual.png differ
diff --git a/rtdata/images/Dark/actions/intent-relative.png b/rtdata/images/Dark/actions/intent-relative.png
new file mode 100644
index 000000000..c1fb040a9
Binary files /dev/null and b/rtdata/images/Dark/actions/intent-relative.png differ
diff --git a/rtdata/images/Dark/actions/intent-saturation.png b/rtdata/images/Dark/actions/intent-saturation.png
new file mode 100644
index 000000000..cabbb2dad
Binary files /dev/null and b/rtdata/images/Dark/actions/intent-saturation.png differ
diff --git a/rtdata/images/Dark/actions/softProof.png b/rtdata/images/Dark/actions/softProof.png
new file mode 100644
index 000000000..2ff09b7f7
Binary files /dev/null and b/rtdata/images/Dark/actions/softProof.png differ
diff --git a/rtdata/images/Light/actions/intent-absolute.png b/rtdata/images/Light/actions/intent-absolute.png
new file mode 100644
index 000000000..1396e3785
Binary files /dev/null and b/rtdata/images/Light/actions/intent-absolute.png differ
diff --git a/rtdata/images/Light/actions/intent-perceptual.png b/rtdata/images/Light/actions/intent-perceptual.png
new file mode 100644
index 000000000..be281333b
Binary files /dev/null and b/rtdata/images/Light/actions/intent-perceptual.png differ
diff --git a/rtdata/images/Light/actions/intent-relative.png b/rtdata/images/Light/actions/intent-relative.png
new file mode 100644
index 000000000..538b3d900
Binary files /dev/null and b/rtdata/images/Light/actions/intent-relative.png differ
diff --git a/rtdata/images/Light/actions/intent-saturation.png b/rtdata/images/Light/actions/intent-saturation.png
new file mode 100644
index 000000000..d2aac5b7f
Binary files /dev/null and b/rtdata/images/Light/actions/intent-saturation.png differ
diff --git a/rtdata/images/Light/actions/softProof.png b/rtdata/images/Light/actions/softProof.png
new file mode 100644
index 000000000..2c12e216f
Binary files /dev/null and b/rtdata/images/Light/actions/softProof.png differ
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 9c703954a..ad30fbff2 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -773,6 +773,7 @@ MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l
MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l
MAIN_TOOLTIP_THRESHOLD;Threshold
MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b
+MONITOR_PROFILE_SYSTEM;System default
NAVIGATOR_B;B:
NAVIGATOR_G;G:
NAVIGATOR_H;H:
@@ -1512,6 +1513,7 @@ TP_ICM_INPUTPROFILE;Input Profile
TP_ICM_LABEL;Color Management
TP_ICM_NOICM;No ICM: sRGB Output
TP_ICM_OUTPUTPROFILE;Output Profile
+TP_ICM_OUTPUTPROFILEINTENT;Output Rendering Intent
TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling
TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance
TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles.
diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc
index a97ae7f39..cd68aa0a6 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -33,7 +33,7 @@ extern const Settings* settings;
Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow)
: EditBuffer(editDataProvider), origCrop(NULL), laboCrop(NULL), labnCrop(NULL),
cropImg(NULL), cbuf_real(NULL), cshmap(NULL), transCrop(NULL), cieCrop(NULL), cbuffer(NULL),
- updating(false), newUpdatePending(false), skip(10),
+ softProofing(false), updating(false), newUpdatePending(false), skip(10),
cropx(0), cropy(0), cropw(-1), croph(-1),
trafx(0), trafy(0), trafw(-1), trafh(-1),
rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1),
@@ -987,7 +987,7 @@ void Crop::update (int todo)
EditBuffer::setReady();
// switch back to rgb
- parent->ipf.lab2monitorRgb (labnCrop, cropImg);
+ parent->ipf.lab2monitorRgb (labnCrop, cropImg, softProofing);
//parent->ipf.lab2monitorRgb (laboCrop, cropImg);
@@ -1030,13 +1030,13 @@ void Crop::update (int todo)
Image8 *cropImgtrue;
if(settings->HistogramWorking) {
- cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, false);
+ cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, RI_RELATIVE, false); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ?
} else {
if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) {
outProfile = "sRGB";
}
- cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, false);
+ cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, params.icm.outputIntent, false);
}
int finalW = rqcropw;
diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h
index 57f388a51..ea9b1bc00 100644
--- a/rtengine/dcrop.h
+++ b/rtengine/dcrop.h
@@ -54,6 +54,7 @@ protected:
// -----------------------------------------------------------------
float** cbuffer;
+ bool softProofing; /// True if the Crop has to display a soft proof of the output with its profile
bool updating; /// Flag telling if an updater thread is currently processing
bool newUpdatePending; /// Flag telling the updater thread that a new update is pending
int skip;
@@ -103,6 +104,10 @@ public:
/** @brief Asynchronously reprocess the detailed crop */
void fullUpdate (); // called via thread
+ void setSoftProofing(bool doSoftProof) {
+ softProofing = doSoftProof;
+ }
+
void setListener (DetailedCropListener* il);
void destroy ();
int get_skip ()
diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h
index ed9fbb424..6b41987f7 100644
--- a/rtengine/iccstore.h
+++ b/rtengine/iccstore.h
@@ -91,6 +91,7 @@ public:
// Main monitors standard profile name, from OS
void findDefaultMonitorProfile ();
cmsHPROFILE getDefaultMonitorProfile () const;
+ Glib::ustring getDefaultMonitorProfileStr () const;
cmsHPROFILE workingSpace (const Glib::ustring& name) const;
cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const;
@@ -134,6 +135,11 @@ inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const
return getProfile (defaultMonitorProfile);
}
+inline Glib::ustring ICCStore::getDefaultMonitorProfileStr () const
+{
+ return defaultMonitorProfile;
+}
+
inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const
{
return getInputIntents (getProfile (name));
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index 8389ec34e..62de26076 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -31,9 +31,9 @@ extern const Settings* settings;
ImProcCoordinator::ImProcCoordinator ()
: orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL),
- ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10),
- highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false),
- bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.),
+ ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10),
+ highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true),
+ softProofing(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.),
hltonecurve(65536),
shtonecurve(65536),
@@ -781,9 +781,16 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
}
+ // Update the output color transform if necessary
+ if (isColorProfileDirty || (todo & M_MONITOR)) {
+ ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProofing);
+ isColorProfileDirty = false;
+ }
+
// process crop, if needed
for (size_t i = 0; i < crops.size(); i++)
if (crops[i]->hasListener () && cropCall != crops[i] ) {
+ crops[i]->setSoftProofing(softProofing);
crops[i]->update (todo); // may call ourselves
}
@@ -794,23 +801,23 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
progress ("Conversion to RGB...", 100 * readyphase / numofphases);
- if (todo != CROP && todo != MINUPDATE) {
+ if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) {
MyMutex::MyLock prevImgLock(previmg->getMutex());
try {
- ipf.lab2monitorRgb (nprevl, previmg);
+ ipf.lab2monitorRgb (nprevl, previmg, softProofing);
delete workimg;
Glib::ustring outProfile = params.icm.output;
if(settings->HistogramWorking) {
Glib::ustring workProfile = params.icm.working;
- workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, true);
+ 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 == "" || params.icm.output == ColorManagementParams::NoICMString) {
+ if (params.icm.output.empty() || params.icm.output == ColorManagementParams::NoICMString) {
outProfile = "sRGB";
}
- workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, false);
+ workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, params.icm.outputIntent, false);
}
} catch(char * str) {
progress ("Error converting file...", 0);
@@ -1126,6 +1133,28 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &
y = (fullh - h) / 2;
}
+void ImProcCoordinator::setSoftProofing (bool softProof)
+{
+ softProofing = softProof;
+}
+
+void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingIntent intent)
+{
+ if (profile != monitorProfile) {
+ monitorProfile = profile;
+ isColorProfileDirty = true;
+ }
+ if (intent != monitorIntent) {
+ monitorIntent = intent;
+ isColorProfileDirty = true;
+ }
+}
+
+void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent)
+{
+ profile = monitorProfile;
+ intent = monitorIntent;
+}
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb)
{
diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h
index ef981fe6a..901804eba 100644
--- a/rtengine/improccoordinator.h
+++ b/rtengine/improccoordinator.h
@@ -72,11 +72,18 @@ protected:
ImProcFunctions ipf;
+ Glib::ustring monitorProfile;
+
+ eRenderingIntent monitorIntent;
+
int scale;
bool highDetailPreprocessComputed;
bool highDetailRawComputed;
bool allocated;
+ bool isColorProfileDirty;
+ bool softProofing;
+
void freeAll ();
// Precomputed values used by DetailedCrop ----------------------------------------------
@@ -249,6 +256,10 @@ public:
void getSpotWB (int x, int y, int rectSize, double& temp, double& green);
void getAutoCrop (double ratio, int &x, int &y, int &w, int &h);
+ void setMonitorProfile (Glib::ustring profile, eRenderingIntent intent);
+ void getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent);
+ void setSoftProofing (bool softProof);
+
bool updateTryLock ()
{
return updaterThreadStart.trylock();
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index c9fa3c6c8..e99daa79a 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -186,12 +186,11 @@ void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params)
}
}
*/
-void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram)
+
+
+void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing)
{
-
// set up monitor transform
- Glib::ustring wprofile = params->icm.working;
-
if (monitorTransform != NULL) {
cmsDeleteTransform (monitorTransform);
}
@@ -210,36 +209,30 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
#if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB
-#if defined(WIN32)
-
- cmsHPROFILE monitor = settings->autoMonitorProfile
- ? iccStore->getDefaultMonitorProfile ()
- : iccStore->getProfile (params->icm.monitorProfile);
-
-#else
-
- cmsHPROFILE monitor = iccStore->getProfile (params->icm.monitorProfile);
-
-#endif
+ cmsHPROFILE monitor = iccStore->getProfile (monitorProfile);
+ printf("ImProcFunctions::updateColorProfiles / monitor profile = %s / intent = %d\n", monitorProfile.c_str(), monitorIntent);
if (monitor) {
MyMutex::MyLock lcmsLock (*lcmsMutex);
cmsHPROFILE iprof = cmsCreateLab4Profile(NULL);
- monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent,
+ printf(" - monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent);
+ 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;
- if (params->icm.output != "" && params->icm.output != ColorManagementParams::NoICMString) {
- outputProfile = params->icm.output;
+ if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) {
+ outputProfile = icm.output;
cmsHPROFILE jprof = iccStore->getProfile(outputProfile);
if (jprof) {
- lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
+ //TODO: Create a dedicated softproof transformation (line below to be finished)
+ //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING );
- if (monitor) {
- output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
- }
+ printf(" - lab2outputTransform = cmsCreateTransform / intent=%d\n", icm.outputIntent);
+ lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
+ printf(" - output2monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent);
+ output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
}
}
@@ -247,6 +240,13 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
}
#endif
+}
+
+void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram)
+{
+
+ Glib::ustring wprofile = params->icm.working;
+
// calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments
int T = 1;
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index cfabbba64..c34219c0d 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -233,6 +233,7 @@ public:
bool needsPCVignetting ();
void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16);
+ void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing);
void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf);
@@ -265,7 +266,7 @@ public:
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage);
float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh);
- void lab2monitorRgb (LabImage* lab, Image8* image);
+ void lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing=false);
void resize (Image16* src, Image16* dst, float dScale);
void Lanczos (const LabImage* src, LabImage* dst, float scale);
void Lanczos (const Image16* src, Image16* dst, float scale);
@@ -379,9 +380,9 @@ public:
void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad);
void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom);
- Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma);
- Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output
- Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw);//without gamma ==>default
+ Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma);
+ Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output
+ Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw);//without gamma ==>default
// CieImage *ciec;
bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL);
diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc
index cc01b783f..a727423ef 100644
--- a/rtengine/iplab2rgb.cc
+++ b/rtengine/iplab2rgb.cc
@@ -39,7 +39,7 @@ const double (*iwprof[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz,
const char* wprofnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"};
const int numprof = 7;
-void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
+void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing)
{
//gamutmap(lab);
@@ -78,7 +78,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
buffer[iy++] = rb[j] / 327.68f;
}
- if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) {
+ if (softProofing && !settings->HistogramWorking && output2monitorTransform && lab2outputTransform) {
AlignedBuffer buf(3 * W);
cmsDoTransform (lab2outputTransform, buffer, buf.data, W);
cmsDoTransform (output2monitorTransform, buf.data, data + ix, W);
@@ -134,7 +134,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
}
}
-Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma)
+Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma)
{
//gamutmap(lab);
@@ -167,7 +167,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
lcmsMutex->lock ();
cmsHPROFILE hLab = cmsCreateLab4Profile(NULL);
- cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC,
+ cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent,
cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety
cmsCloseProfile(hLab);
lcmsMutex->unlock ();
@@ -259,7 +259,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
return image;
}
// for default (not gamma)
-Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw)
+Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw)
{
//gamutmap(lab);
@@ -322,7 +322,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
cmsHPROFILE iprof = iccStore->getXYZProfile ();
lcmsMutex->lock ();
- cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
+ cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
lcmsMutex->unlock ();
image->ExecCMSTransform(hTransform);
@@ -363,7 +363,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
// for gamma options (BT709...sRGB linear...)
-Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, 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)
+Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw)
{
//gamutmap(lab);
@@ -593,7 +593,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int
cmsHPROFILE iprof = iccStore->getXYZProfile ();
lcmsMutex->lock ();
- cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
+ cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
lcmsMutex->unlock ();
image->ExecCMSTransform(hTransform);
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 4dbbad07c..4609c674a 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -454,6 +454,9 @@ enum ProcEvent {
EvLbaselog = 424,
// EvLgrbl = 425,
EvRetinexlhcurve = 425,
+ EvOIntent = 426,
+ EvSoftProof = 427,
+ EvMonitorTransform = 428,
NUMOFEVENTS
};
}
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 44c02a531..2c93bfd47 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -894,8 +894,7 @@ void ColorManagementParams::setDefaults()
dcpIlluminant = 0;
working = "ProPhoto";
output = "RT_sRGB";
- monitorProfile = Glib::ustring ();
- monitorIntent = 1;
+ outputIntent = RI_PERCEPTUAL;
gamma = "default";
gampos = 2.22;
slpos = 4.5;
@@ -2550,6 +2549,20 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_string ("Color Management", "OutputProfile", icm.output);
}
+ if (!pedited || pedited->icm.outputIntent) {
+ Glib::ustring intent;
+ if (icm.outputIntent == RI_PERCEPTUAL) {
+ intent = "Perceptual";
+ } else if (icm.outputIntent == RI_RELATIVE) {
+ intent = "Relative";
+ } else if (icm.outputIntent == RI_SATURATION) {
+ intent = "Saturation";
+ } else if (icm.outputIntent == RI_ABSOLUTE) {
+ intent = "Absolute";
+ }
+ keyFile.set_string ("Color Management", "OutputProfileIntent", intent);
+ }
+
if (!pedited || pedited->icm.gamma) {
keyFile.set_string ("Color Management", "Gammafree", icm.gamma);
}
@@ -5674,6 +5687,23 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
}
}
+ if (keyFile.has_key ("Color Management", "OutputProfileIntent")) {
+ Glib::ustring intent = keyFile.get_string ("Color Management", "OutputProfileIntent");
+ if (intent == "Perceptual") {
+ icm.outputIntent = RI_PERCEPTUAL;
+ } else if (intent == "Relative") {
+ icm.outputIntent = RI_RELATIVE;
+ } else if (intent == "Saturation") {
+ icm.outputIntent = RI_SATURATION;
+ } else if (intent == "Absolute") {
+ icm.outputIntent = RI_ABSOLUTE;
+ }
+
+ if (pedited) {
+ pedited->icm.outputIntent = true;
+ }
+ }
+
if (keyFile.has_key ("Color Management", "Gammafree")) {
icm.gamma = keyFile.get_string ("Color Management", "Gammafree");
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 77c1004e8..cbbbed7a5 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include "LUT.h"
#include "coord.h"
@@ -41,6 +42,14 @@ class WavOpacityCurveW;
class WavOpacityCurveWL;
class RetinextransmissionCurve;
+typedef enum RenderingIntent {
+ RI_PERCEPTUAL = INTENT_PERCEPTUAL,
+ RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC,
+ RI_SATURATION = INTENT_SATURATION,
+ RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC,
+ RI__COUNT
+} eRenderingIntent;
+
namespace procparams
{
@@ -941,8 +950,7 @@ public:
int dcpIlluminant;
Glib::ustring working;
Glib::ustring output;
- Glib::ustring monitorProfile; // Not stored persistently as it is just an optional settings override.
- int monitorIntent; // Not store persistently as it is just an optional settings override.
+ eRenderingIntent outputIntent;
static const Glib::ustring NoICMString;
Glib::ustring gamma;
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 3505da24f..37d0f52b4 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -64,9 +64,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
DARKFRAME, // EvLCPUseVign,
TRANSFORM, // EvLCPUseCA,
M_VOID, // EvFixedExp
- WHITEBALANCE, // EvWBMethod,
- WHITEBALANCE, // EvWBTemp,
- WHITEBALANCE, // EvWBGreen,
+ ALLNORAW, // EvWBMethod,
+ ALLNORAW, // EvWBTemp,
+ ALLNORAW, // EvWBGreen,
RGBCURVE, // EvToneCurveMode1,
RGBCURVE, // EvToneCurve2,
RGBCURVE, // EvToneCurveMode2,
@@ -75,7 +75,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
0, // EvCDNEnabled:obsolete,
ALL, // EvBlendCMSMatrix,
RGBCURVE, // EvDCPToneCurve,
- INPUTPROFILE, // EvDCPIlluminant,
+ ALLNORAW, // EvDCPIlluminant,
RETINEX, // EvSHEnabled,
RGBCURVE, // EvSHHighlights,
RGBCURVE, // EvSHShadows,
@@ -97,7 +97,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
ALLNORAW, // EvHRMethod,
ALLNORAW, // EvWProfile,
OUTPUTPROFILE, // EvOProfile,
- INPUTPROFILE, // EvIProfile,
+ ALLNORAW, // EvIProfile,
TRANSFORM, // EvVignettingAmount,
RGBCURVE, // EvChMixer,
RESIZE, // EvResizeScale,
@@ -234,8 +234,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, // EvCATbadpix
LUMINANCECURVE, // EvCATAutoadap
DEFRINGE, // EvPFCurve
- WHITEBALANCE, // EvWBequal
- WHITEBALANCE, // EvWBequalbo
+ ALLNORAW, // EvWBequal
+ ALLNORAW, // EvWBequalbo
TRANSFORM, // EvGradientDegree
TRANSFORM, // EvGradientEnabled
TRANSFORM, // EvPCVignetteStrength
@@ -421,7 +421,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
DIRPYREQUALIZER, // EvWavNeutral
RGBCURVE, // EvDCPApplyLookTable,
RGBCURVE, // EvDCPApplyBaselineExposureOffset,
- INPUTPROFILE, // EvDCPApplyHueSatMap
+ ALLNORAW, // EvDCPApplyHueSatMap
DIRPYREQUALIZER, // EvWavenacont
DIRPYREQUALIZER, // EvWavenachrom
DIRPYREQUALIZER, // EvWavenaedge
@@ -452,7 +452,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
DEMOSAIC, // EvLslope
RETINEX, // EvLhighl
DEMOSAIC, // EvLbaselog
-// DEMOSAIC, // EvLgrbl
- DEMOSAIC // EvRetinexlhcurve
+// DEMOSAIC, // EvLgrbl
+ DEMOSAIC, // EvRetinexlhcurve
+ ALLNORAW, // EvOIntent
+ ALLNORAW, // EvSoftProof
+ MONITORTRANSFORM // EvMonitorTransform
+
};
diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h
index e24d0c422..23e179f9f 100644
--- a/rtengine/refreshmap.h
+++ b/rtengine/refreshmap.h
@@ -20,15 +20,16 @@
#define __REFRESHMAP__
// Use M_VOID if you wish to update the proc params without updating the preview at all !
-#define M_VOID (1<<15)
+#define M_VOID (1<<16)
// Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview")
// Must NOT be used with other event (i.e. will be used for MINUPDATE only)
-#define M_MINUPDATE (1<<14)
+#define M_MINUPDATE (1<<15)
// Force high quality
-#define M_HIGHQUAL (1<<13)
+#define M_HIGHQUAL (1<<14)
// Elementary functions that can be done to
// the preview image when an event occurs
+#define M_MONITOR (1<<13)
#define M_RETINEX (1<<12)
#define M_CROP (1<<11)
#define M_PREPROC (1<<10)
@@ -45,31 +46,30 @@
// Bitfield of functions to do to the preview image when an event occurs
// Use those or create new ones for your new events
-#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL
-#define 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 TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
-#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
-#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
-#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE)
-#define SHARPENING M_LUMINANCE
-#define IMPULSEDENOISE M_LUMINANCE
-#define DEFRINGE M_LUMINANCE
-#define WHITEBALANCE (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
-#define DEMOSAIC (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 DIRPYRDENOISE (M_COLOR|M_LUMINANCE)
-#define CROP M_CROP
-#define RESIZE M_VOID
-#define EXIF M_VOID
-#define IPTC M_VOID
-#define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE)
-#define OUTPUTPROFILE (M_INIT|M_COLOR|M_LUMINANCE)
-#define INPUTPROFILE WHITEBALANCE
-#define GAMMA (M_COLOR|M_LUMINANCE)
-#define MINUPDATE M_MINUPDATE
-#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
-#define RETINEX (M_RETINEX|ALLNORAW)
+#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 ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL
+#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE|M_COLOR)
+#define SHARPENING (M_LUMINANCE|M_COLOR)
+#define IMPULSEDENOISE (M_LUMINANCE|M_COLOR)
+#define DEFRINGE (M_LUMINANCE|M_COLOR)
+#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR)
+#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR)
+#define GAMMA (M_LUMINANCE|M_COLOR)
+#define CROP M_CROP
+#define RESIZE M_VOID
+#define EXIF M_VOID
+#define IPTC M_VOID
+#define MINUPDATE M_MINUPDATE
+#define RETINEX (M_RETINEX|ALLNORAW)
+#define MONITORTRANSFORM M_MONITOR
+#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM)
extern int refreshmap[];
#endif
diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h
index 195911a3a..d10acb561 100644
--- a/rtengine/rtengine.h
+++ b/rtengine/rtengine.h
@@ -35,7 +35,7 @@
#include "LUT.h"
/**
* @file
- * This file contains the main functionality of the raw therapee engine.
+ * This file contains the main functionality of the RawTherapee engine.
*
*/
@@ -413,9 +413,13 @@ public:
virtual void setAutoBWListener (AutoBWListener* l) = 0;
virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0;
virtual void setAutoChromaListener (AutoChromaListener* l) = 0;
- virtual void setRetinexListener (RetinexListener* l) = 0;
+ virtual void setRetinexListener (RetinexListener* l) = 0;
virtual void setWaveletListener (WaveletListener* l) = 0;
+ virtual void setMonitorProfile (Glib::ustring monitorProfile, eRenderingIntent intent) = 0;
+ virtual void getMonitorProfile (Glib::ustring &monitorProfile, eRenderingIntent &intent) = 0;
+ virtual void setSoftProofing (bool softProof) = 0;
+
virtual ~StagedImageProcessor () {}
/** Returns a staged, cached image processing manager supporting partial updates
diff --git a/rtengine/settings.h b/rtengine/settings.h
index bd37faaf2..98c85ba6f 100644
--- a/rtengine/settings.h
+++ b/rtengine/settings.h
@@ -19,6 +19,8 @@
#ifndef _RTSETTINGS_
#define _RTSETTINGS_
+#include "procparams.h"
+
namespace rtengine
{
@@ -37,7 +39,7 @@ public:
int leveldnautsimpl; // STD or EXPERT
Glib::ustring monitorProfile; ///< ICC profile name used for the monitor
- int monitorIntent; ///< Colorimetric intent used with the above profile
+ eRenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile
bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile
bool autocielab;
bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index 5ea834b2d..1edfa590c 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -1151,7 +1151,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
cmsFloat64Number Parameters[7];
double ga0, ga1, ga2, ga3, ga4, ga5, ga6;
// if(params.blackwhite.enabled) params.toneCurve.hrenabled=false;
- readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, 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.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 );
customGamma = true;
//or selected Free gamma
@@ -1343,7 +1343,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
bwonly = false;
}
- readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, bwonly);
+ readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, bwonly);
if (settings->verbose) {
printf("Output profile_: \"%s\"\n", params.icm.output.c_str());
diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc
index c6d2804c1..a762fc95b 100644
--- a/rtgui/editorpanel.cc
+++ b/rtgui/editorpanel.cc
@@ -35,88 +35,171 @@ using namespace rtengine::procparams;
class MonitorProfileSelector
{
private:
- Gtk::ComboBoxText profileBox;
- Gtk::ComboBoxText intentBox;
+ Gtk::ToggleButton* softProof;
+ MyComboBoxText* profileBox;
+ //PopUpButton* intentBox;
+ MyComboBoxText* intentBox;
+ sigc::connection profileConn, intentConn;
- rtengine::StagedImageProcessor* const& processor;
+ rtengine::StagedImageProcessor* processor;
private:
- MonitorProfileSelector(const MonitorProfileSelector&);
- MonitorProfileSelector& operator=(const MonitorProfileSelector&);
+ void prepareSoftProofButton ()
+ {
+ Gtk::Image *softProofImg = Gtk::manage (new RTImage("softProof.png"));
+ softProofImg->set_padding(0, 0);
+ softProof = Gtk::manage(new Gtk::ToggleButton());
+ softProof->add(*softProofImg);
+ softProof->set_relief(Gtk::RELIEF_NONE);
+ softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled));
+ }
void prepareProfileBox ()
{
- profileBox.append_text (M("PREFERENCES_PROFILE_NONE"));
- profileBox.set_active (0);
+ profileBox = Gtk::manage(new MyComboBoxText());
+ profileBox->set_size_request(100,-1);
- const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles ();
- for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator)
- profileBox.append_text (*iterator);
+ profileBox->append_text (M("PREFERENCES_PROFILE_NONE"));
+ #if defined(WIN32)
+ profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileStr() + ")");
+ profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0);
+ #else
+ profileBox->set_active (0);
+ #endif
+
+ const std::vector profiles = rtengine::iccStore->getProfiles ();
+ for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) {
+ profileBox->append_text (*iterator);
+ }
+ profileConn = profileBox->signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters));
}
void prepareIntentBox ()
{
- intentBox.append_text (M("PREFERENCES_INTENT_RELATIVE"));
- intentBox.append_text (M("PREFERENCES_INTENT_PERCEPTUAL"));
- intentBox.set_active (0);
+ intentBox = Gtk::manage(new MyComboBoxText());
+ intentBox->set_size_request(-1,-1);
+ //intentBox = Gtk::manage(new PopUpButton());
+
+ intentBox->append_text (M("PREFERENCES_INTENT_PERCEPTUAL"));
+ intentBox->append_text (M("PREFERENCES_INTENT_RELATIVE"));
+ //intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE"));
+ //intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL"));
+ //intentBox->setSelected(0);
+ intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters));
+ //intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent));
+ }
+
+ void softProofToggled ()
+ {
+ if (processor) {
+ processor->setSoftProofing( softProof->get_active() );
+ processor->endUpdateParams ( rtengine::EvMonitorTransform );
+ }
+ }
+
+ void updateIntent (int i)
+ {
+ updateParameters();
}
void updateParameters ()
{
- const Glib::ustring profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring();
+ Glib::ustring profile;
+#ifdef WIN32
+ if (profileBox->get_active_row_number () == 1) {
+ profile = rtengine::iccStore->getDefaultMonitorProfileStr ();
+ if (profile.empty()) {
+ profile = options.rtSettings.monitorProfile;
+ }
+ if (profile.empty()) {
+ profile = "sRGB IEC61966-2.1"; // assuming this profile always exist on Windows
+ }
+ } else if (profileBox->get_active_row_number () > 1) {
+ profile = profileBox->get_active_text ();
+ }
+#else
+ profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring();
+#endif
- std::uint8_t supportedIntents = rtengine::ICCStore::getInstance ()->getProofIntents (profile);
+ std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile);
const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL;
const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC;
if (supportsPerceptual && supportsRelativeColorimetric) {
- intentBox.set_sensitive (true);
+ intentBox->set_sensitive (true);
}
else {
- intentBox.set_sensitive (false);
- intentBox.set_active (supportsPerceptual ? 1 : 0);
+ bool wasBlocked = intentConn.block(true);
+ intentBox->set_active(supportsPerceptual ? 0 : 1);
+ //intentBox->setSelected(supportsPerceptual ? 0 : 1);
+ intentBox->set_sensitive (false);
+ intentConn.block(wasBlocked);
}
- const int intent = intentBox.get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC;
+ //rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE;
+ rtengine::eRenderingIntent intent = intentBox->get_active_row_number() > 0 ? rtengine::RI_RELATIVE : rtengine::RI_PERCEPTUAL;
- if (!processor)
+ if (!processor) {
return;
+ }
- rtengine::ProcParams* parameters = processor->beginUpdateParams ();
+ // either store them in the options file for the default value when opening the next EditorPanel
+ //options.rtSettings.monitorProfile = profile;
+ //options.rtSettings.monitorIntent = intent;
- parameters->icm.monitorProfile = profile;
- parameters->icm.monitorIntent = intent;
-
- processor->endUpdateParams (rtengine::EvOProfile);
+ // ...or store them locally
+ printf("Appel de processor->setMonitorProfile(%s, %d)\n", profile.c_str(), intent);
+ processor->setMonitorProfile(profile, intent);
+ printf("Appel de processor->endUpdateParams(%d)\n", rtengine::EvMonitorTransform);
+ processor->endUpdateParams (rtengine::EvMonitorTransform);
}
public:
- MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) :
- profileBox (),
- intentBox (),
- processor (ipc)
+ MonitorProfileSelector () :
+ processor (NULL)
{
+ prepareSoftProofButton ();
prepareProfileBox ();
prepareIntentBox ();
reset ();
-
- profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters));
- intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters));
}
- void pack_end (Gtk::Box* box)
+ // HOMBRE: renamed to 'pack_end_in', because 'pack_end' already widely used by Gtk::Widget in a different way
+ void pack_end_in (Gtk::Box* box)
{
- box->pack_end (intentBox, Gtk::PACK_SHRINK, 0);
- box->pack_end (profileBox, Gtk::PACK_SHRINK, 0);
+ box->pack_end (*softProof, Gtk::PACK_SHRINK, 0);
+ box->pack_end (*intentBox, Gtk::PACK_SHRINK, 0);
+ box->pack_end (*profileBox, Gtk::PACK_EXPAND_WIDGET, 0);
}
void reset ()
{
- setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0);
- intentBox.set_active (options.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0);
+ bool wasBlocked;
+#ifdef WIN32
+ wasBlocked = profileConn.block(true);
+ if (options.rtSettings.autoMonitorProfile) {
+ setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 1);
+ } else {
+ setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0);
+ }
+ profileConn.block(wasBlocked);
+#else
+ wasBlocked = profileConn.block(true);
+ setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0);
+ profileConn.block(wasBlocked);
+#endif
+ wasBlocked = intentConn.block(true);
+ intentBox->set_active (options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1);
+ //intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1);
+ intentConn.block(wasBlocked);
- updateParameters ();
+ // useless, set_active will trigger the signal_changed event
+ //updateParameters ();
+ }
+
+ void setImageProcessor (rtengine::StagedImageProcessor* imageProc) {
+ processor = imageProc;
}
};
@@ -269,6 +352,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
// Save buttons
Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ());
+ iops->set_spacing(2);
//Gtk::Image *saveButtonImage = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON));
Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("gtk-save-large.png"));
@@ -346,14 +430,16 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
navSync->set_relief(Gtk::RELIEF_NONE);
navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP"));
+ iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0);
iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0);
iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0);
iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0);
- iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0);
}
- monitorProfile.reset(new MonitorProfileSelector (ipc));
- monitorProfile->pack_end (iops);
+ // Monitor profile buttons
+ iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0);
+ monitorProfile = new MonitorProfileSelector ();
+ monitorProfile->pack_end_in (iops);
editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0);
editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0);
@@ -491,6 +577,7 @@ EditorPanel::~EditorPanel ()
delete ppframe;
delete leftbox;
delete vboxright;
+ delete monitorProfile;
//delete saveAsDialog;
if(catalogPane) {
@@ -612,6 +699,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
this->isrc = isrc;
ipc = rtengine::StagedImageProcessor::create (isrc);
+ monitorProfile->setImageProcessor(ipc);
ipc->setProgressListener (this);
ipc->setPreviewImageListener (previewHandler);
ipc->setPreviewScale (10); // Important
@@ -662,6 +750,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
history->resetSnapShotNumber();
+ //HOMBRE: not sure if we want to reset on opening a new image
monitorProfile->reset ();
}
diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h
index ffb8a93a4..0575b7f92 100644
--- a/rtgui/editorpanel.h
+++ b/rtgui/editorpanel.h
@@ -86,7 +86,7 @@ protected:
Gtk::Button* navNext;
Gtk::Button* navPrev;
- std::auto_ptr monitorProfile;
+ MonitorProfileSelector* monitorProfile;
ImageAreaPanel* iareapanel;
PreviewHandler* previewHandler;
diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc
index d40b7d720..0112f9ebf 100644
--- a/rtgui/filecatalog.cc
+++ b/rtgui/filecatalog.cc
@@ -1139,6 +1139,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas
params.icm.input = options.fastexport_icm_input ;
params.icm.working = options.fastexport_icm_working ;
params.icm.output = options.fastexport_icm_output ;
+ params.icm.outputIntent = options.fastexport_icm_outputIntent ;
params.icm.gamma = options.fastexport_icm_gamma ;
params.resize.enabled = options.fastexport_resize_enabled ;
params.resize.scale = options.fastexport_resize_scale ;
diff --git a/rtgui/history.cc b/rtgui/history.cc
index 57f7549db..689ea6394 100644
--- a/rtgui/history.cc
+++ b/rtgui/history.cc
@@ -24,7 +24,6 @@ using namespace rtengine;
using namespace rtengine::procparams;
Glib::ustring eventDescrArray[NUMOFEVENTS];
-extern Glib::ustring argv0;
History::History (bool bookmarkSupport) : blistener(NULL), tpc (NULL), bmnum (1)
{
@@ -204,8 +203,8 @@ void History::bookmarkSelectionChanged ()
void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited)
{
- // to prevent recursion, we filter out the events triggered by the history
- if (ev == EvHistoryBrowsed) {
+ // to prevent recursion, we filter out the events triggered by the history and events that should not be registered
+ if (ev == EvHistoryBrowsed || ev == EvMonitorTransform) {
return;
}
diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc
index 51ee408a2..55e8e1a6e 100644
--- a/rtgui/icmpanel.cc
+++ b/rtgui/icmpanel.cc
@@ -193,6 +193,18 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
onames->set_active (0);
+ // Rendering intent
+
+ Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_OUTPUTPROFILEINTENT")));
+ oVBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK);
+ ointent = Gtk::manage (new MyComboBoxText ());
+ oVBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET);
+ ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL"));
+ ointent->append_text (M("PREFERENCES_INTENT_RELATIVE"));
+ ointent->append_text (M("PREFERENCES_INTENT_SATURATION"));
+ ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE"));
+ ointent->set_active(0);
+
// Output gamma
Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ());
@@ -282,6 +294,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) );
onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) );
+ ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) );
wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) );
dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) );
@@ -507,6 +520,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
if (onames->get_active_row_number() == -1) {
onames->set_active_text (M("TP_ICM_NOICM"));
}
+ ointent->set_active(pp->icm.outputIntent);
ckbToneCurve->set_active (pp->icm.toneCurve);
lastToneCurve = pp->icm.toneCurve;
@@ -545,6 +559,10 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
onames->set_active_text(M("GENERAL_UNCHANGED"));
}
+ if (!pedited->icm.outputIntent) {
+ ointent->set_active_text(M("GENERAL_UNCHANGED"));
+ }
+
if (!pedited->icm.dcpIlluminant) {
dcpIll->set_active_text(M("GENERAL_UNCHANGED"));
}
@@ -605,6 +623,13 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
pp->icm.output = onames->get_active_text();
}
+ int ointentVal = ointent->get_active_row_number();
+ if (ointentVal >= 0 && ointentVal < RI__COUNT) {
+ pp->icm.outputIntent = static_cast(ointentVal);
+ } else {
+ pp->icm.outputIntent = rtengine::RI_PERCEPTUAL;
+ }
+
pp->icm.freegamma = freegamma->get_active();
DCPProfile* dcp = NULL;
@@ -641,6 +666,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
pedited->icm.input = !iunchanged->get_active ();
pedited->icm.working = wnames->get_active_text() != M("GENERAL_UNCHANGED");
pedited->icm.output = onames->get_active_text() != M("GENERAL_UNCHANGED");
+ pedited->icm.outputIntent = ointent->get_active_text() != M("GENERAL_UNCHANGED");
pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED");
pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent ();
pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent ();
@@ -876,7 +902,7 @@ void ICMPanel::opChanged ()
{
if (listener) {
- listener->panelChanged (EvOProfile, onames->get_active_text());
+ listener->panelChanged (EvOProfile, Glib::ustring(onames->get_active_text())+Glib::ustring("\n")+ointent->get_active_text());
}
}
@@ -979,6 +1005,7 @@ void ICMPanel::setBatchMode (bool batchMode)
iVBox->reorder_child (*iunchanged, 5);
removeIfThere (this, saveRef);
onames->append_text (M("GENERAL_UNCHANGED"));
+ ointent->append_text (M("GENERAL_UNCHANGED"));
wnames->append_text (M("GENERAL_UNCHANGED"));
wgamma->append_text (M("GENERAL_UNCHANGED"));
dcpIll->append_text (M("GENERAL_UNCHANGED"));
diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h
index 93828f5fd..e10f42b20 100644
--- a/rtgui/icmpanel.h
+++ b/rtgui/icmpanel.h
@@ -78,6 +78,7 @@ private:
MyComboBoxText* wgamma;
MyComboBoxText* onames;
+ MyComboBoxText* ointent;
Gtk::RadioButton* ofromdir;
Gtk::RadioButton* ofromfile;
Gtk::RadioButton* iunchanged;
diff --git a/rtgui/options.cc b/rtgui/options.cc
index ce85acc09..1ffc74e2b 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -470,6 +470,7 @@ void Options::setDefaults ()
fastexport_icm_input = "(camera)";
fastexport_icm_working = "ProPhoto";
fastexport_icm_output = "RT_sRGB";
+ fastexport_icm_outputIntent = rtengine::RI_PERCEPTUAL;
fastexport_icm_gamma = "default";
fastexport_resize_enabled = true;
fastexport_resize_scale = 1;
@@ -636,7 +637,7 @@ void Options::setDefaults ()
rtSettings.leveldnautsimpl = 0;
rtSettings.monitorProfile = Glib::ustring();
- rtSettings.monitorIntent = 1;
+ rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL;
rtSettings.autoMonitorProfile = false;
rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows)
rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile"
@@ -1461,7 +1462,7 @@ int Options::readFromFile (Glib::ustring fname)
}
if (keyFile.has_key ("Color Management", "Intent")) {
- rtSettings.monitorIntent = keyFile.get_integer("Color Management", "Intent");
+ rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent"));
}
if (keyFile.has_key ("Color Management", "CRI")) {
@@ -1712,6 +1713,10 @@ int Options::readFromFile (Glib::ustring fname)
fastexport_icm_output = keyFile.get_string ("Fast Export", "fastexport_icm_output" );
}
+ if (keyFile.has_key ("Fast Export", "fastexport_icm_output_intent" )) {
+ fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" ));
+ }
+
if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) {
fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" );
}
@@ -2075,6 +2080,7 @@ int Options::saveToFile (Glib::ustring fname)
keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input );
keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working );
keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output );
+ keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent );
keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma );
keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled );
keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale );
diff --git a/rtgui/options.h b/rtgui/options.h
index 614042fa2..969b66642 100644
--- a/rtgui/options.h
+++ b/rtgui/options.h
@@ -264,6 +264,7 @@ public:
Glib::ustring fastexport_icm_input;
Glib::ustring fastexport_icm_working;
Glib::ustring fastexport_icm_output;
+ rtengine::eRenderingIntent fastexport_icm_outputIntent;
Glib::ustring fastexport_icm_gamma;
bool fastexport_resize_enabled;
double fastexport_resize_scale;
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index ac2fe6523..28d4c13b8 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -816,6 +816,7 @@ void ParamsEdited::initFrom (const std::vector
icm.dcpIlluminant = icm.dcpIlluminant && p.icm.dcpIlluminant == other.icm.dcpIlluminant;
icm.working = icm.working && p.icm.working == other.icm.working;
icm.output = icm.output && p.icm.output == other.icm.output;
+ icm.outputIntent = icm.outputIntent && p.icm.outputIntent == other.icm.outputIntent;
icm.gamma = icm.gamma && p.icm.gamma == other.icm.gamma;
icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma;
icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos;
@@ -2119,6 +2120,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.icm.output = mods.icm.output;
}
+ if (icm.outputIntent) {
+ toEdit.icm.outputIntent = mods.icm.outputIntent;
+ }
+
//if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos;
//if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos;
if (icm.gampos) {
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 3fa753013..1993c7aaa 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -530,6 +530,7 @@ public:
bool dcpIlluminant;
bool working;
bool output;
+ bool outputIntent;
bool gamma;
bool gampos;
bool slpos;
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index 4aa1d2427..56fb63c3e 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -1434,7 +1434,7 @@ void Preferences::storePreferences ()
#if !defined(__APPLE__) // monitor profile not supported on apple
moptions.rtSettings.monitorProfile = monProfile->get_active_text ();
- moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC;
+ moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE;
#if defined(WIN32)
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
#endif
diff --git a/tools/source_icons/scalable/intent-absolute.file b/tools/source_icons/scalable/intent-absolute.file
new file mode 100644
index 000000000..57278bff2
--- /dev/null
+++ b/tools/source_icons/scalable/intent-absolute.file
@@ -0,0 +1 @@
+intent-absolute.png,w25,actions
diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg
new file mode 100644
index 000000000..497ce9c66
--- /dev/null
+++ b/tools/source_icons/scalable/intent-absolute.svg
@@ -0,0 +1,1378 @@
+
+
+
+
diff --git a/tools/source_icons/scalable/intent-perceptual.file b/tools/source_icons/scalable/intent-perceptual.file
new file mode 100644
index 000000000..3e7520042
--- /dev/null
+++ b/tools/source_icons/scalable/intent-perceptual.file
@@ -0,0 +1 @@
+intent-perceptual.png,w25,actions
diff --git a/tools/source_icons/scalable/intent-perceptual.svg b/tools/source_icons/scalable/intent-perceptual.svg
new file mode 100644
index 000000000..ab34b86b7
--- /dev/null
+++ b/tools/source_icons/scalable/intent-perceptual.svg
@@ -0,0 +1,1366 @@
+
+
+
+
diff --git a/tools/source_icons/scalable/intent-relative.file b/tools/source_icons/scalable/intent-relative.file
new file mode 100644
index 000000000..5191a25c3
--- /dev/null
+++ b/tools/source_icons/scalable/intent-relative.file
@@ -0,0 +1 @@
+intent-relative.png,w25,actions
diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg
new file mode 100644
index 000000000..31a2fb342
--- /dev/null
+++ b/tools/source_icons/scalable/intent-relative.svg
@@ -0,0 +1,1374 @@
+
+
+
+
diff --git a/tools/source_icons/scalable/intent-saturation.file b/tools/source_icons/scalable/intent-saturation.file
new file mode 100644
index 000000000..9f33b978e
--- /dev/null
+++ b/tools/source_icons/scalable/intent-saturation.file
@@ -0,0 +1 @@
+intent-saturation.png,w25,actions
diff --git a/tools/source_icons/scalable/intent-saturation.svg b/tools/source_icons/scalable/intent-saturation.svg
new file mode 100644
index 000000000..638df39f2
--- /dev/null
+++ b/tools/source_icons/scalable/intent-saturation.svg
@@ -0,0 +1,1366 @@
+
+
+
+
diff --git a/tools/source_icons/scalable/softProof.file b/tools/source_icons/scalable/softProof.file
new file mode 100644
index 000000000..e275113ec
--- /dev/null
+++ b/tools/source_icons/scalable/softProof.file
@@ -0,0 +1 @@
+softProof.png,w22,actions
diff --git a/tools/source_icons/scalable/softProof.svg b/tools/source_icons/scalable/softProof.svg
new file mode 100644
index 000000000..7d142fc4c
--- /dev/null
+++ b/tools/source_icons/scalable/softProof.svg
@@ -0,0 +1,1389 @@
+
+
+
+