From 91f67f0cb6760cc2703cfaeb698bd4fa12ee6064 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 12 Aug 2015 13:27:45 +0200 Subject: [PATCH] Issue 2846: Filter preview through output profile when using a monitor profile. - Removed the "Rendering intent" setting from Preferences, - Hard-code "relative colorimetric" intent everywhere, - Filter through output profile before filtering through monitor profile if using a monitor profile, - If not using a monitor profile, a direct sRGB conversion is done, --- rtengine/improcfun.cc | 39 +++++++++++++++++++++++++++++++++++--- rtengine/improcfun.h | 4 +++- rtengine/iplab2rgb.cc | 18 ++++++++++++------ rtengine/refreshmap.h | 2 +- rtengine/stdimagesource.cc | 2 +- rtgui/preferences.cc | 12 +++++++----- 6 files changed, 60 insertions(+), 17 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index e6b05095f..bd6d5704c 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -98,6 +98,14 @@ ImProcFunctions::~ImProcFunctions () if (monitorTransform != NULL) { cmsDeleteTransform (monitorTransform); } + + if (output2monitorTransform != NULL) { + cmsDeleteTransform (output2monitorTransform); + } + + if (lab2outputTransform != NULL) { + cmsDeleteTransform (lab2outputTransform); + } } void ImProcFunctions::setScale (double iscale) @@ -184,11 +192,21 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par // set up monitor transform Glib::ustring wprofile = params->icm.working; - if (monitorTransform) { + if (monitorTransform != NULL) { cmsDeleteTransform (monitorTransform); } + if (output2monitorTransform != NULL) { + cmsDeleteTransform (output2monitorTransform); + } + + if (lab2outputTransform != NULL) { + cmsDeleteTransform (lab2outputTransform); + } + monitorTransform = NULL; + output2monitorTransform = NULL; + lab2outputTransform = NULL; #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB Glib::ustring monitorProfile = settings->monitorProfile; @@ -205,10 +223,25 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par if (monitor) { lcmsMutex->lock (); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_DBL, monitor, TYPE_RGB_8, settings->colorimetricIntent, + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision - cmsCloseProfile(iprof); + Glib::ustring outputProfile; + + if (params->icm.output != "" && params->icm.output != ColorManagementParams::NoICMString) { + outputProfile = params->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 ); + + if (monitor) { + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + } + } + } + + cmsCloseProfile(iprof); lcmsMutex->unlock (); } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c18d7ea69..8857677a8 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -60,6 +60,8 @@ class ImProcFunctions static LUTf gamma2curve; cmsHTRANSFORM monitorTransform; + cmsHTRANSFORM lab2outputTransform; + cmsHTRANSFORM output2monitorTransform; const ProcParams* params; double scale; @@ -222,7 +224,7 @@ public: static void cleanupCache (); ImProcFunctions (const ProcParams* iparams, bool imultiThread = true) - : monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {} + : monitorTransform(NULL), lab2outputTransform(NULL), output2monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {} ~ImProcFunctions (); void setScale (double iscale); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 169516181..cc01b783f 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -54,8 +54,8 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) #pragma omp parallel firstprivate(lab, data, W, H) #endif { - AlignedBuffer pBuf(3 * lab->W); - double *buffer = pBuf.data; + AlignedBuffer pBuf(3 * lab->W); + float *buffer = pBuf.data; #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -78,7 +78,13 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) buffer[iy++] = rb[j] / 327.68f; } - cmsDoTransform (monitorTransform, buffer, data + ix, W); + if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { + AlignedBuffer 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 @@ -161,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, settings->colorimetricIntent, + cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety cmsCloseProfile(hLab); lcmsMutex->unlock (); @@ -316,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, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); @@ -587,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, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index 16ccc73a8..7aefcbcc3 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -64,7 +64,7 @@ #define EXIF M_VOID #define IPTC M_VOID #define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE) -#define OUTPUTPROFILE (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 diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 1604c9c6d..aabb35a30 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -279,7 +279,7 @@ void StdImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams } lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, settings->colorimetricIntent, + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index dd02b38b9..9c0918189 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -676,12 +676,14 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_border_width (4); - Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT") + ":", Gtk::ALIGN_LEFT)); + /* + Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":", Gtk::ALIGN_LEFT)); intent = Gtk::manage (new Gtk::ComboBoxText ()); intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); intent->append_text (M("PREFERENCES_INTENT_SATURATION")); intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + */ iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_LEFT)); @@ -707,8 +709,8 @@ Gtk::Widget* Preferences::getColorManagementPanel () #endif Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2)); - colt->attach (*intlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*intent, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + //colt->attach (*intlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + //colt->attach (*intent, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); colt->attach (*pdlabel, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); colt->attach (*iccDir, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #if !defined(__APPLE__) // monitor profile not supported on apple @@ -1425,7 +1427,7 @@ void Preferences::storePreferences () moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif moptions.rtSettings.iccDirectory = iccDir->get_filename (); - moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); + //moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); moptions.rtSettings.viewingdevice = view->get_active_row_number (); moptions.rtSettings.viewingdevicegrey = grey->get_active_row_number (); moptions.rtSettings.viewinggreySc = greySc->get_active_row_number (); @@ -1554,7 +1556,7 @@ void Preferences::fillPreferences () iccDir->set_current_folder (moptions.rtSettings.iccDirectory); } - intent->set_active (moptions.rtSettings.colorimetricIntent); + //intent->set_active (moptions.rtSettings.colorimetricIntent); view->set_active (moptions.rtSettings.viewingdevice); grey->set_active (moptions.rtSettings.viewingdevicegrey); greySc->set_active (moptions.rtSettings.viewinggreySc);