diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 3f73e8c40..2a87a74d4 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -2,7 +2,8 @@ file (GLOB PROFILEFILES "profiles/*.pp3") file (GLOB LANGUAGEFILES "languages/*") file (GLOB SOUNDFILES "sounds/*") -file (GLOB ICCFILES "iccprofiles/*") +file (GLOB INPUTICCFILES "iccprofiles/input/*") +file (GLOB OUTPUTICCFILES "iccprofiles/output/*") # THEMEDIR includes subfolders for image resources for some themes; doing the normal glob won't work. set (THEMEDIR "themes") set (IMAGESDIR "images") @@ -30,7 +31,8 @@ install (FILES ${IMAGEFILES} DESTINATION ${DATADIR}/images) install (FILES ${LANGUAGEFILES} DESTINATION ${DATADIR}/languages) install (FILES ${PROFILEFILES} DESTINATION ${DATADIR}/profiles) install (FILES ${SOUNDFILES} DESTINATION ${DATADIR}/sounds) -install (FILES ${ICCFILES} DESTINATION ${DATADIR}/iccprofiles) +install (FILES ${INPUTICCFILES} DESTINATION ${DATADIR}/iccprofiles/input) +install (FILES ${OUTPUTICCFILES} DESTINATION ${DATADIR}/iccprofiles/output) install (DIRECTORY ${THEMEDIR} DESTINATION ${DATADIR}) install (DIRECTORY ${IMAGESDIR} DESTINATION ${DATADIR} FILES_MATCHING PATTERN "index.theme") install (DIRECTORY ${IMAGESDIR} DESTINATION ${DATADIR} FILES_MATCHING PATTERN "*.png") diff --git a/rtdata/iccprofiles/Canon EOS 20D.icc b/rtdata/iccprofiles/input/Canon EOS 20D.icc similarity index 100% rename from rtdata/iccprofiles/Canon EOS 20D.icc rename to rtdata/iccprofiles/input/Canon EOS 20D.icc diff --git a/rtdata/iccprofiles/Canon EOS 450D.icc b/rtdata/iccprofiles/input/Canon EOS 450D.icc similarity index 100% rename from rtdata/iccprofiles/Canon EOS 450D.icc rename to rtdata/iccprofiles/input/Canon EOS 450D.icc diff --git a/rtdata/iccprofiles/Canon EOS 550D.icc b/rtdata/iccprofiles/input/Canon EOS 550D.icc similarity index 100% rename from rtdata/iccprofiles/Canon EOS 550D.icc rename to rtdata/iccprofiles/input/Canon EOS 550D.icc diff --git a/rtdata/iccprofiles/Canon EOS Digital Rebel XSi.icc b/rtdata/iccprofiles/input/Canon EOS Digital Rebel XSi.icc similarity index 100% rename from rtdata/iccprofiles/Canon EOS Digital Rebel XSi.icc rename to rtdata/iccprofiles/input/Canon EOS Digital Rebel XSi.icc diff --git a/rtdata/iccprofiles/Canon EOS Rebel T2i.icc b/rtdata/iccprofiles/input/Canon EOS Rebel T2i.icc similarity index 100% rename from rtdata/iccprofiles/Canon EOS Rebel T2i.icc rename to rtdata/iccprofiles/input/Canon EOS Rebel T2i.icc diff --git a/rtdata/iccprofiles/Canon EOS-1D Mark III.icc b/rtdata/iccprofiles/input/Canon EOS-1D Mark III.icc similarity index 100% rename from rtdata/iccprofiles/Canon EOS-1D Mark III.icc rename to rtdata/iccprofiles/input/Canon EOS-1D Mark III.icc diff --git a/rtdata/iccprofiles/Nikon D200.icc b/rtdata/iccprofiles/input/Nikon D200.icc similarity index 100% rename from rtdata/iccprofiles/Nikon D200.icc rename to rtdata/iccprofiles/input/Nikon D200.icc diff --git a/rtdata/iccprofiles/Nikon D3S.icc b/rtdata/iccprofiles/input/Nikon D3S.icc similarity index 100% rename from rtdata/iccprofiles/Nikon D3S.icc rename to rtdata/iccprofiles/input/Nikon D3S.icc diff --git a/rtdata/iccprofiles/Nikon D700.icc b/rtdata/iccprofiles/input/Nikon D700.icc similarity index 100% rename from rtdata/iccprofiles/Nikon D700.icc rename to rtdata/iccprofiles/input/Nikon D700.icc diff --git a/rtdata/iccprofiles/Nikon D7000.icc b/rtdata/iccprofiles/input/Nikon D7000.icc similarity index 100% rename from rtdata/iccprofiles/Nikon D7000.icc rename to rtdata/iccprofiles/input/Nikon D7000.icc diff --git a/rtdata/iccprofiles/Olympus E-P2.icc b/rtdata/iccprofiles/input/Olympus E-P2.icc similarity index 100% rename from rtdata/iccprofiles/Olympus E-P2.icc rename to rtdata/iccprofiles/input/Olympus E-P2.icc diff --git a/rtdata/iccprofiles/Panasonic DMC-FZ150.icc b/rtdata/iccprofiles/input/Panasonic DMC-FZ150.icc similarity index 100% rename from rtdata/iccprofiles/Panasonic DMC-FZ150.icc rename to rtdata/iccprofiles/input/Panasonic DMC-FZ150.icc diff --git a/rtdata/iccprofiles/Panasonic DMC-FZ35.icc b/rtdata/iccprofiles/input/Panasonic DMC-FZ35.icc similarity index 100% rename from rtdata/iccprofiles/Panasonic DMC-FZ35.icc rename to rtdata/iccprofiles/input/Panasonic DMC-FZ35.icc diff --git a/rtdata/iccprofiles/Panasonic DMC-FZ38.icc b/rtdata/iccprofiles/input/Panasonic DMC-FZ38.icc similarity index 100% rename from rtdata/iccprofiles/Panasonic DMC-FZ38.icc rename to rtdata/iccprofiles/input/Panasonic DMC-FZ38.icc diff --git a/rtdata/iccprofiles/Panasonic DMC-G1.icc b/rtdata/iccprofiles/input/Panasonic DMC-G1.icc similarity index 100% rename from rtdata/iccprofiles/Panasonic DMC-G1.icc rename to rtdata/iccprofiles/input/Panasonic DMC-G1.icc diff --git a/rtdata/iccprofiles/Panasonic DMC-G3.icc b/rtdata/iccprofiles/input/Panasonic DMC-G3.icc similarity index 100% rename from rtdata/iccprofiles/Panasonic DMC-G3.icc rename to rtdata/iccprofiles/input/Panasonic DMC-G3.icc diff --git a/rtdata/iccprofiles/Panasonic DMC-GH1.icc b/rtdata/iccprofiles/input/Panasonic DMC-GH1.icc similarity index 100% rename from rtdata/iccprofiles/Panasonic DMC-GH1.icc rename to rtdata/iccprofiles/input/Panasonic DMC-GH1.icc diff --git a/rtdata/iccprofiles/Panasonic DMC-GH2.icc b/rtdata/iccprofiles/input/Panasonic DMC-GH2.icc similarity index 100% rename from rtdata/iccprofiles/Panasonic DMC-GH2.icc rename to rtdata/iccprofiles/input/Panasonic DMC-GH2.icc diff --git a/rtdata/iccprofiles/Pentax K200D.icc b/rtdata/iccprofiles/input/Pentax K200D.icc similarity index 100% rename from rtdata/iccprofiles/Pentax K200D.icc rename to rtdata/iccprofiles/input/Pentax K200D.icc diff --git a/rtdata/iccprofiles/Sony DSLR-A700.icc b/rtdata/iccprofiles/input/Sony DSLR-A700.icc similarity index 100% rename from rtdata/iccprofiles/Sony DSLR-A700.icc rename to rtdata/iccprofiles/input/Sony DSLR-A700.icc diff --git a/rtdata/iccprofiles/output/RT_Large_g10.icc b/rtdata/iccprofiles/output/RT_Large_g10.icc new file mode 100644 index 000000000..27e78f8e0 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Large_g10.icc differ diff --git a/rtdata/iccprofiles/output/RT_Large_gBT709.icc b/rtdata/iccprofiles/output/RT_Large_gBT709.icc new file mode 100644 index 000000000..a3949e6e2 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Large_gBT709.icc differ diff --git a/rtdata/iccprofiles/output/RT_Large_gsRGB.icc b/rtdata/iccprofiles/output/RT_Large_gsRGB.icc new file mode 100644 index 000000000..22bed9770 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Large_gsRGB.icc differ diff --git a/rtdata/iccprofiles/output/RT_Middle_gsRGB.icc b/rtdata/iccprofiles/output/RT_Middle_gsRGB.icc new file mode 100644 index 000000000..7e7b9bb1c Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Middle_gsRGB.icc differ diff --git a/rtdata/iccprofiles/output/RT_sRGB.icm b/rtdata/iccprofiles/output/RT_sRGB.icm new file mode 100644 index 000000000..1dad52380 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_sRGB.icm differ diff --git a/rtdata/iccprofiles/output/RT_sRGB_g10.icm b/rtdata/iccprofiles/output/RT_sRGB_g10.icm new file mode 100644 index 000000000..3a46f125a Binary files /dev/null and b/rtdata/iccprofiles/output/RT_sRGB_g10.icm differ diff --git a/rtdata/iccprofiles/output/RT_sRGB_gBT709.icm b/rtdata/iccprofiles/output/RT_sRGB_gBT709.icm new file mode 100644 index 000000000..e9c607c61 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_sRGB_gBT709.icm differ diff --git a/rtdata/iccprofiles/sRGB_IEC61966-2-1_black_scaled.icc b/rtdata/iccprofiles/sRGB_IEC61966-2-1_black_scaled.icc deleted file mode 100644 index 71e338302..000000000 Binary files a/rtdata/iccprofiles/sRGB_IEC61966-2-1_black_scaled.icc and /dev/null differ diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index e62a9d11d..8217fa03b 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -193,25 +193,31 @@ ProfileContent ICCStore::getContent (Glib::ustring name) { } // Reads all profiles from the given profiles dir -void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring stdICCDir) { +void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) { Glib::Mutex::Lock lock(mutex_); - // Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir) + // + fileProfiles.clear(); + fileProfileContents.clear(); + // RawTherapee's profiles take precedence if a user's profile of the same name exists + loadICCs(Glib::build_filename(rtICCDir, "output"), false, fileProfiles, fileProfileContents); loadICCs(usrICCDir, false, fileProfiles, fileProfileContents); - loadICCs(stdICCDir, true, fileStdProfiles, fileStdProfileContents); + + // Input profiles + // Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir) + fileStdProfiles.clear(); + fileStdProfileContents.clear(); + loadICCs(Glib::build_filename(rtICCDir, "input"), true, fileStdProfiles, fileStdProfileContents); } void ICCStore::loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map &resultProfileContents) { - resultProfiles.clear (); - resultProfileContents.clear (); - if (rootDirName!="") { // process directory Glib::ustring dirname = rootDirName; Glib::Dir* dir = NULL; try { - if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) return; + if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) return; dir = new Glib::Dir (dirname); } catch (Glib::Exception& fe) { @@ -293,6 +299,23 @@ ProfileContent::ProfileContent (const ProfileContent& other) { data = NULL; } +ProfileContent::ProfileContent (cmsHPROFILE hProfile) { + + data = NULL; + length = 0; + if (hProfile != NULL) { + cmsUInt32Number bytesNeeded = 0; + cmsSaveProfileToMem(hProfile, 0, &bytesNeeded); + if (bytesNeeded > 0) + { + data = new char[bytesNeeded+1]; + cmsSaveProfileToMem(hProfile, data, &bytesNeeded); + length = (int)bytesNeeded; + } + } +} + + ProfileContent& ProfileContent::operator= (const ProfileContent other) { length = other.length; diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 0086e4e35..16630c90a 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef __ICCSTORE__ +#ifndef __ICCSTORE__ #define __ICCSTORE__ #include @@ -36,7 +36,8 @@ class ProfileContent { ProfileContent (): data(NULL), length(0) {} ProfileContent (Glib::ustring fileName); - ProfileContent (const ProfileContent& other); + ProfileContent (const ProfileContent& other); + ProfileContent (cmsHPROFILE hProfile); ~ProfileContent (); ProfileContent& operator= (const ProfileContent other); cmsHPROFILE toProfile (); @@ -60,17 +61,17 @@ class ICCStore { cmsHPROFILE xyz; cmsHPROFILE srgb; - Glib::Mutex mutex_; + Glib::Mutex mutex_; ICCStore (); void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map &resultProfileContents); public: - static ICCStore* getInstance(void); - - Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS - void findDefaultMonitorProfile(); + static ICCStore* getInstance(void); + + Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS + void findDefaultMonitorProfile(); int numOfWProfiles (); cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma=false, Glib::ustring name=""); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c238b9801..41e5c2eaa 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -150,7 +150,7 @@ class ImProcFunctions { void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh); Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile); - 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);// for gamma output + 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);// for gamma output Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);//without gamma ==>default 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); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index d7ec3c1e6..6f67bd6bf 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -307,7 +307,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) { +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) { //gamutmap(lab); @@ -319,10 +319,11 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int Image16* image = new Image16 (cw, ch); cmsBool rc = TRUE; float p1,p2,p3,p4,p5,p6;//primaries - double ga0,ga1,ga2,ga3,ga4,ga5=0.0,ga6=0.0;//gamma parameters + //double ga0,ga1,ga2,ga3,ga4,ga5=0.0,ga6=0.0;//gamma parameters double g_a0,g_a1,g_a2,g_a3,g_a4,g_a5;//gamma parameters double pwr; double ts; + ga6=0.0; pwr=1.0/gampos; ts=slpos; int mode=0, imax=0; @@ -331,6 +332,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int int select_temp =1;//5003K 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=="ProPhoto") {p1=0.7347; p2=0.2653; p3=0.1596; p4=0.8404; p5=0.0366; p6=0.0001;select_temp=1;}//Prophoto primaries else if (profi=="WideGamut") {p1=0.7350; p2=0.2650; p3=0.1150; p4=0.8260; p5=0.1570; p6=0.0180;select_temp=1;}//Widegamut primaries else if (profi=="Adobe RGB") {p1=0.6400; p2=0.3300; p3=0.2100; p4=0.7100; p5=0.1500; p6=0.0600;select_temp=2;}//Adobe primaries diff --git a/rtengine/settings.h b/rtengine/settings.h index 6eac8b625..a8231987c 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -35,11 +35,15 @@ namespace rtengine { bool LCMSSafeMode; // If true, not OMP Glib::ustring adobe; // default name of AdobeRGB1998 Glib::ustring prophoto; // default name of Prophoto + Glib::ustring prophoto10; // default name of Prophoto + Glib::ustring widegamut; //default name of WidegamutRGB Glib::ustring beta; // default name of BetaRGB Glib::ustring best; // default name of BestRGB Glib::ustring bruce; // default name of Bruce Glib::ustring srgb; // default name of SRGB space profile + Glib::ustring srgb10; // default name of SRGB space profile + bool gamutICC; // /** Creates a new instance of Settings. diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index bebdfed81..8e868df33 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -125,8 +125,6 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p } // update blurmap - - SHMap* shmap = NULL; if (params.sh.enabled) { shmap = new SHMap (fw, fh, true); @@ -152,10 +150,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p } // at this stage, we can flush the raw data to free up quite an important amount of memory - imgsrc->flushRawData(); - - // at this stage, we can flush the raw data to free up quite an important amount of memory - imgsrc->flushRGB(); + // commented out because it make the application crash when batch processing... + // TODO: find a better place to flush rawData and rawRGB + //imgsrc->flushRawData(); + //imgsrc->flushRGB(); LUTf curve1 (65536,0); LUTf curve2 (65536,0); @@ -170,8 +168,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation); + // Freeing baseImg because not used anymore + delete baseImg; + baseImg = NULL; + if (shmap) delete shmap; + shmap = NULL; if (pl) pl->setProgress (0.5); @@ -228,225 +231,208 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p cw = params.crop.w; ch = params.crop.h; } - if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 + + Image16* readyImg = NULL; + cmsHPROFILE jprof = NULL; + bool customGamma = false; + bool useLCMS; + + 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; + 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 ); + customGamma = true; + //or selected Free gamma - Image16* readyImgP; - Image16* 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); - readyImgP=readyImg; - delete labView; - if (pl) pl->setProgress (0.70); - int drapeau=0; - // get the resize parameters - int refw, refh; - double tmpScale; + useLCMS=false; + bool pro=false; Glib::ustring chpro, outProfile; - int present_space[7]={0,0,0,0,0,0,0}; + bool present_space[9]={false,false,false,false,false,false,false,false,false}; std::vector opnames = iccStore->getOutputProfiles (); //test if files are in system - for (int j=0; j<7;j++) { - // one can modify "option" [Color Management] to adapt name of profile if there are different for windows, MacOS, Linux ?? - if(j==0) chpro=options.rtSettings.prophoto; + for (int j=0; j<9; 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; - for (int i=0; isetProgressStr ("Missing file.."); - pl->setProgress (0.0);// display file not present: not very good display information...!! - if (settings->verbose) printf("Missing file: %s \n", chpro.c_str()); - } //c_str() + 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 - if (params.icm.working=="ProPhoto" && present_space[0]==1) outProfile=options.rtSettings.prophoto;//in option we can change the name of file - if different... - else if (params.icm.working=="Adobe RGB" && present_space[1]==1) outProfile=options.rtSettings.adobe; - else if (params.icm.working=="WideGamut" && present_space[2]==1) outProfile=options.rtSettings.widegamut; - else if (params.icm.working=="Beta RGB" && present_space[3]==1) outProfile=options.rtSettings.beta; - else if (params.icm.working=="BestRGB" && present_space[4]==1) outProfile=options.rtSettings.best; - else if (params.icm.working=="BruceRGB" && present_space[5]==1) outProfile=options.rtSettings.bruce; - else if (params.icm.working== "sRGB" && present_space[6]==1) outProfile=options.rtSettings.srgb; - //OutProfile become Profile's system - else {if (settings->verbose) printf("No file:%s in system - use LCMS2 substitution\n",params.icm.working.c_str() ); drapeau=1; } - - if (settings->verbose && drapeau==0) printf("Output profile: %s \n", outProfile.c_str()); //c_str() - - - if (params.resize.enabled) { - - if (params.crop.enabled && params.resize.appliesTo == "Cropped area") { - // the resize values applies to the crop dimensions - refw = cw; - refh = ch; - } - else { - // the resize values applies to the image dimensions - // if a crop exists, it will be resized to the calculated scale - refw = fw; - refh = fh; - } - - switch(params.resize.dataspec) { - case (1): - // Width - tmpScale = (double)params.resize.width/(double)refw; - break; - case (2): - // Height - tmpScale = (double)params.resize.height/(double)refh; - break; - case (3): - // FitBox - if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height) - tmpScale = (double)params.resize.width/(double)refw; - else - tmpScale = (double)params.resize.height/(double)refh; - break; - default: - // Scale - tmpScale = params.resize.scale; - break; - } - - // resize image - if (fabs(tmpScale-1.0)>1e-5) { - int imw, imh; - if (params.crop.enabled && params.resize.appliesTo == "Full image") { - imw = cw; - imh = ch; - } - else { - imw = refw; - imh = refh; - } - imw = (int)( (double)imw * tmpScale + 0.5 ); - imh = (int)( (double)imh * tmpScale + 0.5 ); - Image16* tempImage = new Image16 (imw, imh); - ipf.resize (readyImg, tempImage, tmpScale); - delete readyImg; - readyImg = tempImage; - } + // 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 { + // Should not occurs + if (settings->verbose) printf("\"%s\": unknown working profile! - use LCMS2 substitution\n", params.icm.working.c_str() ); + useLCMS=true; } - - if (tunnelMetaData) - readyImg->setMetadata (ii->getMetaData()->getExifData ()); - else - readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); - - - ProfileContent pc; - - if (drapeau==0) pc = iccStore->getContent (outProfile);// use profile in system (Prophoto.icm, sRGB.icm, etc.) if present, otherwise use LCMS2 profile generate by lab2rgb16b - - readyImg->setOutputProfile (pc.data, pc.length); - - delete baseImg; - - if (!job->initialImage) - ii->decreaseRef (); - - delete job; - if (pl) - pl->setProgress (0.75); - - return readyImg; + //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]; + 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 + // 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] ); + } + } } else { - //if default mode : profil = selection by choice in list (Prophoto.icm, sRGB.icm, etc., etc.) , gamma = gamma of profile or not selected Free gamma - Image16* readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); - delete labView; - if (pl) pl->setProgress (0.70); + // if Default gamma mode: we use the profile selected in the "Output profile" combobox; + // gamma come from the selected profile, otherwise it comes from "Free gamma" tool + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); + if (settings->verbose) printf("Output profile: \"%s\"\n", params.icm.output.c_str()); + } + + delete labView; + labView = NULL; + + if (pl) pl->setProgress (0.70); + + if (params.resize.enabled) { // get the resize parameters int refw, refh; double tmpScale; - - if (params.resize.enabled) { - - if (params.crop.enabled && params.resize.appliesTo == "Cropped area") { - // the resize values applies to the crop dimensions - refw = cw; - refh = ch; - } - else { - // the resize values applies to the image dimensions - // if a crop exists, it will be resized to the calculated scale - refw = fw; - refh = fh; - } - - switch(params.resize.dataspec) { - case (1): - // Width - tmpScale = (double)params.resize.width/(double)refw; - break; - case (2): - // Height - tmpScale = (double)params.resize.height/(double)refh; - break; - case (3): - // FitBox - if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height) - tmpScale = (double)params.resize.width/(double)refw; - else - tmpScale = (double)params.resize.height/(double)refh; - break; - default: - // Scale - tmpScale = params.resize.scale; - break; - } - - // resize image - if (fabs(tmpScale-1.0)>1e-5) { - int imw, imh; - if (params.crop.enabled && params.resize.appliesTo == "Full image") { - imw = cw; - imh = ch; - } - else { - imw = refw; - imh = refh; - } - imw = (int)( (double)imw * tmpScale + 0.5 ); - imh = (int)( (double)imh * tmpScale + 0.5 ); - Image16* tempImage = new Image16 (imw, imh); - ipf.resize (readyImg, tempImage, tmpScale); - delete readyImg; - readyImg = tempImage; - } + if (params.crop.enabled && params.resize.appliesTo == "Cropped area") { + // the resize values applies to the crop dimensions + refw = cw; + refh = ch; + } + else { + // the resize values applies to the image dimensions + // if a crop exists, it will be resized to the calculated scale + refw = fw; + refh = fh; } + switch(params.resize.dataspec) { + case (1): + // Width + tmpScale = (double)params.resize.width/(double)refw; + break; + case (2): + // Height + tmpScale = (double)params.resize.height/(double)refh; + break; + case (3): + // FitBox + if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height) + tmpScale = (double)params.resize.width/(double)refw; + else + tmpScale = (double)params.resize.height/(double)refh; + break; + default: + // Scale + tmpScale = params.resize.scale; + break; + } - if (tunnelMetaData) - readyImg->setMetadata (ii->getMetaData()->getExifData ()); - else - readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); - - - ProfileContent pc; - if (params.icm.output!="" && params.icm.output!=ColorManagementParams::NoICMString) - pc = iccStore->getContent (params.icm.output); - - readyImg->setOutputProfile (pc.data, pc.length); - - delete baseImg; - - if (!job->initialImage) - ii->decreaseRef (); - - delete job; - if (pl) - pl->setProgress (0.75); - - return readyImg; - + // resize image + if (fabs(tmpScale-1.0)>1e-5) { + int imw, imh; + if (params.crop.enabled && params.resize.appliesTo == "Full image") { + imw = cw; + imh = ch; + } + else { + imw = refw; + imh = refh; + } + imw = (int)( (double)imw * tmpScale + 0.5 ); + imh = (int)( (double)imh * tmpScale + 0.5 ); + Image16* tempImage = new Image16 (imw, imh); + ipf.resize (readyImg, tempImage, tmpScale); + delete readyImg; + readyImg = tempImage; + } } + + + if (tunnelMetaData) + readyImg->setMetadata (ii->getMetaData()->getExifData ()); + else + readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); + + + // Setting the output curve to readyImg + if (customGamma) { + if (!useLCMS) { + // use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generate by lab2rgb16b + ProfileContent pc(jprof); + readyImg->setOutputProfile (pc.data, pc.length); + } + } + else { + // use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b + Glib::ustring outputProfile; + if (params.icm.output!="" && params.icm.output!=ColorManagementParams::NoICMString) { + outputProfile = params.icm.output; + } + else { + // use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b + if (settings->verbose) printf("No output profiles set ; looking for the default sRGB profile (\"%s\")...\n", options.rtSettings.srgb.c_str()); + outputProfile = options.rtSettings.srgb; + } + + // if iccStore->getProfile send back an object, then iccStore->getContent will do too + cmsHPROFILE jprof = iccStore->getProfile(outputProfile); //get outProfile + if (jprof == NULL) { + if (settings->verbose) printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", outputProfile.c_str()); + } + else { + if (settings->verbose) printf("Using \"%s\" output profile\n", outputProfile.c_str()); + ProfileContent pc = iccStore->getContent (outputProfile); + readyImg->setOutputProfile (pc.data, pc.length); + } + } + + if (!job->initialImage) + ii->decreaseRef (); + + delete job; + if (pl) + pl->setProgress (0.75); + + return readyImg; } void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) { diff --git a/rtgui/options.cc b/rtgui/options.cc index 69c313115..7271ff56b 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -234,10 +234,12 @@ void Options::setDefaults () { rtSettings.monitorProfile = ""; rtSettings.autoMonitorProfile = false; rtSettings.LCMSSafeMode = true; - rtSettings.adobe = "AdobeRGB1998"; // put the name of yours profiles (here windows) - rtSettings.prophoto = "ProPhoto"; // these names appear in the menu "output profile" + rtSettings.adobe = "RT_Middle_gsRGB"; // put the name of yours profiles (here windows) + rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" + rtSettings.prophoto10 = "RT_Large_g10"; // these names appear in the menu "output profile" + rtSettings.srgb10 = "RT_sRGB_g10"; rtSettings.widegamut = "WideGamutRGB"; - rtSettings.srgb = "sRGB Color Space Profile"; + rtSettings.srgb = "RT_sRGB_gBT709"; rtSettings.bruce = "Bruce"; rtSettings.beta = "BetaRGB"; rtSettings.best = "BestRGB"; @@ -432,10 +434,14 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize"); if( keyFile.has_key ("Color Management", "GamutICC")) rtSettings.gamutICC = keyFile.get_boolean("Color Management", "GamutICC"); - if( keyFile.has_key ("Color Management", "Adobe_RGB")) rtSettings.adobe = keyFile.get_string("Color Management", "Adobe_RGB"); - if( keyFile.has_key ("Color Management", "Pro_Photo")) rtSettings.prophoto = keyFile.get_string("Color Management","Pro_Photo"); + if( keyFile.has_key ("Color Management", "RT_Adobe_RGB")) rtSettings.adobe = keyFile.get_string("Color Management", "RT_Adobe_RGB"); + if( keyFile.has_key ("Color Management", "RT_Pro_Photo")) rtSettings.prophoto = keyFile.get_string("Color Management","RT_Pro_Photo"); + if( keyFile.has_key ("Color Management", "RT_Pro_Photo10")) rtSettings.prophoto10 = keyFile.get_string("Color Management","RT_Pro_Photo10"); + if( keyFile.has_key ("Color Management", "Wide_Gamut")) rtSettings.widegamut = keyFile.get_string("Color Management","Wide_Gamut"); - if( keyFile.has_key ("Color Management", "S_rgb")) rtSettings.srgb = keyFile.get_string("Color Management","S_rgb"); + if( keyFile.has_key ("Color Management", "RT_S_rgb")) rtSettings.srgb = keyFile.get_string("Color Management","RT_S_rgb"); + if( keyFile.has_key ("Color Management", "RT_S_rgb10")) rtSettings.srgb10 = keyFile.get_string("Color Management","RT_S_rgb10"); + if( keyFile.has_key ("Color Management", "B_eta")) rtSettings.beta = keyFile.get_string("Color Management","B_eta"); if( keyFile.has_key ("Color Management", "B_est")) rtSettings.best = keyFile.get_string("Color Management","B_est"); if( keyFile.has_key ("Color Management", "B_ruce")) rtSettings.bruce = keyFile.get_string("Color Management","B_ruce"); @@ -609,10 +615,14 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); keyFile.set_boolean ("Color Management", "LCMSSafeMode", rtSettings.LCMSSafeMode); - keyFile.set_string ("Color Management", "Adobe_RGB", rtSettings.adobe); - keyFile.set_string ("Color Management", "Pro_Photo", rtSettings.prophoto); + keyFile.set_string ("Color Management", "RT_Adobe_RGB", rtSettings.adobe); + keyFile.set_string ("Color Management", "RT_Pro_Photo", rtSettings.prophoto); + keyFile.set_string ("Color Management", "RT_Pro_Photo10", rtSettings.prophoto10); + keyFile.set_string ("Color Management", "Wide_Gamut", rtSettings.widegamut); - keyFile.set_string ("Color Management", "S_rgb", rtSettings.srgb); + keyFile.set_string ("Color Management", "RT_S_rgb", rtSettings.srgb); + keyFile.set_string ("Color Management", "RT_S_rgb10", rtSettings.srgb10); + keyFile.set_string ("Color Management", "B_eta", rtSettings.beta); keyFile.set_string ("Color Management", "B_est", rtSettings.best); keyFile.set_string ("Color Management", "B_ruce", rtSettings.bruce);