diff --git a/rtengine/image16.cc b/rtengine/image16.cc index 47b365dd8..3b3fadc44 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -273,8 +273,12 @@ Image16::tofloat() const } // Parallized transformation; create transform with cmsFLAGS_NOCACHE! -void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform) { - #pragma omp parallel for - for (int i=0; i #include #include - #include #ifdef _OPENMP @@ -165,7 +164,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); monitorTransform = cmsCreateTransform (iprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, - cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + settings->LCMSSafeMode ? cmsFLAGS_NOOPTIMIZE : cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety lcmsMutex->unlock (); } diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 9df3423ee..94148e66e 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -150,7 +150,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_8, settings->colorimetricIntent, - cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + settings->LCMSSafeMode ? cmsFLAGS_NOOPTIMIZE : cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety lcmsMutex->unlock (); // cmsDoTransform is relatively expensive @@ -180,7 +180,9 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, buffer[iy++] = CLIP((int)z_); } + if (settings->LCMSSafeMode) lcmsMutex->lock (); cmsDoTransform (hTransform, buffer, image->data + ix, cw); + if (settings->LCMSSafeMode) lcmsMutex->unlock (); } cmsDeleteTransform(hTransform); @@ -265,10 +267,12 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int za[j-cx] = CLIP((int)z_); } } + cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16_PLANAR, oprof, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE); lcmsMutex->unlock (); + cmsDoTransform (hTransform, image->data, image->data, image->planestride); cmsDeleteTransform(hTransform); } else { diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index bb052309e..eec461ff9 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -1603,7 +1604,7 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (in, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), settings->colorimetricIntent, - cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + settings->LCMSSafeMode ? 0 : cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety lcmsMutex->unlock (); if (hTransform) { @@ -1622,15 +1623,15 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams } } - im->ExecCMSTransform(hTransform); + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); } else { // create the profile from camera lcmsMutex->lock (); hTransform = cmsCreateTransform (camprofile, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), settings->colorimetricIntent, - cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + settings->LCMSSafeMode ? cmsFLAGS_NOOPTIMIZE : cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety lcmsMutex->unlock (); - im->ExecCMSTransform(hTransform); + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); } cmsDeleteTransform(hTransform); @@ -1688,7 +1689,7 @@ void RawImageSource::colorSpaceConversion16 (Image16* im, ColorManagementParams cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_NOCACHE); //cmsFLAGS_MATRIXINPUT | cmsFLAGS_MATRIXOUTPUT);//cmsFLAGS_MATRIXINPUT | cmsFLAGS_MATRIXOUTPUT); lcmsMutex->unlock (); - im->ExecCMSTransform(hTransform); + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); cmsDeleteTransform(hTransform); */ // in this case we avoid using the slllllooooooowwww lcms @@ -1716,7 +1717,8 @@ TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working); out = iccStore->workingSpace (cmp.working); // out = iccStore->workingSpaceGamma (wProfile); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, + settings->LCMSSafeMode ? 0 : cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety lcmsMutex->unlock (); if (hTransform) { @@ -1733,14 +1735,15 @@ TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working); } } - im->ExecCMSTransform(hTransform); + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); } else { lcmsMutex->lock (); - hTransform = cmsCreateTransform (camprofile, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_NOCACHE); + hTransform = cmsCreateTransform (camprofile, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, + settings->LCMSSafeMode ? 0 : cmsFLAGS_NOCACHE); lcmsMutex->unlock (); - im->ExecCMSTransform(hTransform); + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); } cmsDeleteTransform(hTransform); diff --git a/rtengine/settings.h b/rtengine/settings.h index bd3c1f32a..b396ba15e 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -1,47 +1,48 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _RTSETTINGS_ -#define _RTSETTINGS_ - -namespace rtengine { - - /** This structure holds the global parameters used by the RT engine. */ - class Settings { - public: - bool dualThreadEnabled; ///< If true, the image processing operations with utilize two processor cores (if possible) - Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles - int colorimetricIntent; ///< Colorimetric intent used at color space conversions - Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _RTSETTINGS_ +#define _RTSETTINGS_ + +namespace rtengine { + + /** This structure holds the global parameters used by the RT engine. */ + class Settings { + public: + bool dualThreadEnabled; ///< If true, the image processing operations with utilize two processor cores (if possible) + Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles + int colorimetricIntent; ///< Colorimetric intent used at color space conversions + Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile - - bool verbose; - Glib::ustring darkFramesPath; ///< The default directory for dark frames - Glib::ustring flatFieldsPath; ///< The default directory for flat fields - - /** Creates a new instance of Settings. - * @return a pointer to the new Settings instance. */ - static Settings* create (); - /** Destroys an instance of Settings. - * @param s a pointer to the Settings instance to destroy. */ - static void destroy (Settings* s); - }; -} - -#endif - + + bool verbose; + Glib::ustring darkFramesPath; ///< The default directory for dark frames + Glib::ustring flatFieldsPath; ///< The default directory for flat fields + bool LCMSSafeMode; // If true, not OMP + + /** Creates a new instance of Settings. + * @return a pointer to the new Settings instance. */ + static Settings* create (); + /** Destroys an instance of Settings. + * @param s a pointer to the Settings instance to destroy. */ + static void destroy (Settings* s); + }; +} + +#endif + diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 558d61c64..2b5532825 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -328,10 +328,10 @@ void StdImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams if (cmp.input!="(none)") { lcmsMutex->lock (); cmsHTRANSFORM hTransform = cmsCreateTransform (in, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), settings->colorimetricIntent, - cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + settings->LCMSSafeMode ? cmsFLAGS_NOOPTIMIZE : cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); - im->ExecCMSTransform(hTransform); + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); cmsDeleteTransform(hTransform); } @@ -365,10 +365,11 @@ void StdImageSource::colorSpaceConversion16 (Image16* im, ColorManagementParams if (cmp.input!="(none)") { lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, + settings->LCMSSafeMode ? 0 : cmsFLAGS_NOCACHE); lcmsMutex->unlock (); - im->ExecCMSTransform(hTransform); + im->ExecCMSTransform(hTransform, settings->LCMSSafeMode); cmsDeleteTransform(hTransform); } diff --git a/rtgui/options.cc b/rtgui/options.cc index 1a6675f4f..8a892794e 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -151,6 +151,7 @@ void Options::setDefaults () { rtSettings.colorimetricIntent = 1; rtSettings.monitorProfile = ""; rtSettings.autoMonitorProfile = false; + rtSettings.LCMSSafeMode = false; rtSettings.verbose = false; } @@ -312,6 +313,8 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "AutoMonitorProfile")) rtSettings.autoMonitorProfile = keyFile.get_boolean ("Color Management", "AutoMonitorProfile"); if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); + + if (keyFile.has_key ("Color Management", "LCMSSafeMode")) rtSettings.LCMSSafeMode = keyFile.get_boolean ("Color Management", "LCMSSafeMode"); } if (keyFile.has_group ("Batch Processing")) { @@ -453,6 +456,7 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile); keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); + keyFile.set_boolean ("Color Management", "LCMSSafeMode", rtSettings.LCMSSafeMode); Glib::ArrayHandle bab = baBehav; keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab);