From 22ec6055ce025d18bfad44bdc4761b84a1a193bd Mon Sep 17 00:00:00 2001 From: Oliver Duis Date: Thu, 5 May 2011 18:04:11 +0200 Subject: [PATCH] Custom output gamma, on behalf of Jacques; see issue #666 --- rtdata/languages/default | 2 + rtdata/profiles/crisp.pp3 | 1 + rtdata/profiles/default.pp3 | 1 + rtdata/profiles/neutral.pp3 | 1 + rtengine/curves.cc | 9 ++- rtengine/iccstore.cc | 22 +++++- rtengine/improccoordinator.cc | 1 + rtengine/improcfun.h | 5 +- rtengine/iplab2rgb.cc | 135 +++++++++++++++++++++++++++++++++- rtengine/procevents.h | 3 +- rtengine/procparams.cc | 7 +- rtengine/procparams.h | 2 + rtengine/rawimagesource.cc | 1 + rtengine/rawimagesource.h | 5 +- rtengine/refreshmap.cc | 1 + rtengine/rtengine.h | 2 + rtengine/settings.h | 9 ++- rtengine/simpleprocess.cc | 131 ++++++++++++++++++++++++++++++++- rtgui/icmpanel.cc | 46 +++++++++++- rtgui/icmpanel.h | 3 + rtgui/options.cc | 14 ++++ rtgui/paramsedited.h | 1 + 22 files changed, 382 insertions(+), 20 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 99d3092ca..2369a7930 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -759,6 +759,8 @@ TP_FLATFIELD_BT_HORIZONTAL;Horizontal TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz. TP_FLATFIELD_BT_VERTICAL;Vertical TP_FLATFIELD_LABEL;Flat Field +TP_GAMMA_OUTPUT;Output gamma +TP_GAMMA_COMMENT;(output profile disabled except "default") TP_HLREC_CIELAB;CIELab Blending TP_HLREC_COLOR;Color Propagation TP_HLREC_LABEL;Highlight Reconstruction diff --git a/rtdata/profiles/crisp.pp3 b/rtdata/profiles/crisp.pp3 index 28c949dec..7e671d7d8 100644 --- a/rtdata/profiles/crisp.pp3 +++ b/rtdata/profiles/crisp.pp3 @@ -145,6 +145,7 @@ InputProfile=(camera) ApplyGammaBeforeInputProfile=false WorkingProfile=sRGB OutputProfile=No ICM: sRGB output +Gammafree=default [Equalizer] Enabled=false diff --git a/rtdata/profiles/default.pp3 b/rtdata/profiles/default.pp3 index 85dcb0c28..911d878e5 100644 --- a/rtdata/profiles/default.pp3 +++ b/rtdata/profiles/default.pp3 @@ -145,6 +145,7 @@ InputProfile=(camera) ApplyGammaBeforeInputProfile=false WorkingProfile=sRGB OutputProfile=No ICM: sRGB output +Gammafree=default [Equalizer] Enabled=false diff --git a/rtdata/profiles/neutral.pp3 b/rtdata/profiles/neutral.pp3 index d2f97c2f5..608ec9259 100644 --- a/rtdata/profiles/neutral.pp3 +++ b/rtdata/profiles/neutral.pp3 @@ -145,6 +145,7 @@ InputProfile=(camera) ApplyGammaBeforeInputProfile=false WorkingProfile=sRGB OutputProfile=No ICM: sRGB output +Gammafree=default [Equalizer] Enabled=false diff --git a/rtengine/curves.cc b/rtengine/curves.cc index e257a0eff..6c259714f 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -199,10 +199,17 @@ namespace rtengine { gamma= %f, skip= %d \n",def_mul,ecomp,black,hlcompr,shcompr,br,contr,defmul,gamma_,skip);*/ // compute parameters of the gamma curve - double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 ))); + /*double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 ))); double slope = 1.099 * pow (start, 1.0/gamma_-1) - 0.099/start; double mul = 1.099; double add = 0.099; + // gamma BT709*/ + + //normalize gamma to sRGB + double start = exp(gamma_*log( -0.055 / ((1.0/gamma_-1.0)*1.055 ))); + double slope = 1.055 * pow (start, 1.0/gamma_-1) - 0.055/start; + double mul = 1.055; + double add = 0.055; // a: slope of the curve, black: starting point at the x axis double a = pow (2.0, ecomp); diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 7a97a3548..1de273ca1 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -34,6 +34,23 @@ namespace rtengine { const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best}; const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz}; const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; +const char* wpgamma[] = {"default","BT709_g2.2_s4.5", "sRGB_g2.4_s12.92", "linear_g1.0", "standard_g2.2", "standard_g1.8", "High_g1.3_s3.35","Low_g2.6_s6.9"}; //gamma free +//default = gamma inside profile +//BT709 g=2.22 s=4.5 sRGB g=2.4 s=12.92 +//linear g=1.0 +//std22 g=2.2 std18 g=1.8 +// high g=1.3 s=3.35 for high dynamic images +//low g=2.6 s=6.9 for low contrast images + + +std::vector getGamma () {//return gamma + + std::vector res; + for (unsigned int i=0; i getWorkingProfiles () { @@ -320,7 +337,10 @@ cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, G if (gamma) { pcurve[2] = 1; - pcurve[3] = 0x1f00000; + // pcurve[3] = 0x1f00000;// pcurve for gamma BT709 : g=2.22 s=4.5 + // normalize gamma in RT, default (Emil's choice = sRGB) + pcurve[3] = 0x2390000;//pcurve for gamma sRGB : g:2.4 s=12.92 + } // constructing profile header diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 40d48f8e3..79eeb5999 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -150,6 +150,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { setScale (scale); imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm, params.raw); ipf.firstAnalysis (orig_prev, ¶ms, vhist16, imgsrc->getGamma()); + } readyphase++; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 311b7f45d..b51f2489e 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -56,11 +56,11 @@ class ImProcFunctions { bool needsRotation (); bool needsPerspective (); bool needsVignetting (); + // static cmsUInt8Number* Mempro = NULL; public: static LUTf cachef; - double lumimul[3]; static void initCache (); @@ -113,7 +113,8 @@ class ImProcFunctions { void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh, bool edges); Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile); - Image16* lab2rgb16 (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);// 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); bool transCoord (int W, int H, std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 65c5f9ade..47aee24d6 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include //#include #ifdef _OPENMP @@ -227,7 +230,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) { //gamutmap(lab); @@ -238,8 +241,9 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int if (cy+ch>lab->H) ch = lab->H-cy; Image16* image = new Image16 (cw, ch); - - cmsHPROFILE oprof = iccStore->getProfile (profile); + cmsHPROFILE oprof = iccStore->getProfile (profile); + + if (oprof) { #pragma omp parallel for if (multiThread) @@ -302,6 +306,131 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int } return image; } + + +// 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) { + + //gamutmap(lab); + + if (cx<0) cx = 0; + if (cy<0) cy = 0; + if (cx+cw>lab->W) cw = lab->W-cx; + if (cy+ch>lab->H) ch = lab->H-cy; + + Image16* image = new Image16 (cw, ch); + cmsBool rc = TRUE; + float p1,p2,p3,p4,p5,p6;//primaries + float ga0,ga1,ga2,ga3,ga4,ga5=0;//gamma parameters + int t50; + int select_temp =1;//5003K + double eps=0.000000001;// not divide by zero + //primaries + 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 + else if (profi=="sRGB") {p1=0.6400; p2=0.3300; p3=0.3000; p4=0.6000; p5=0.1500; p6=0.0600;select_temp=2;} // sRGB primaries + else if (profi=="BruceRGB") {p1=0.6400; p2=0.3300; p3=0.2800; p4=0.6500; p5=0.1500; p6=0.0600;select_temp=2;} // Bruce primaries + else if (profi=="Beta RGB") {p1=0.6888; p2=0.3112; p3=0.1986; p4=0.7551; p5=0.1265; p6=0.0352;select_temp=1;} // Beta primaries + else if (profi=="BestRGB") {p1=0.7347; p2=0.2653; p3=0.2150; p4=0.7750; p5=0.1300; p6=0.0350;select_temp=1;} // Best primaries + + // gamma : ga0,ga1,ga2,ga3,ga4,ga5 by calcul + if(gam=="BT709_g2.2_s4.5") {ga0=2.222;ga1=1./1.099258;ga2=0.099258/1.099258;ga3=1./4.5; ga4=0.01805;ga5=0;}//BT709 2.2 4.5 - my prefered as D.Coffin ga4=0.01805 + else if (gam=="sRGB_g2.4_s12.92") {ga0=2.3999 ; ga1=1./1.0550; ga2=0.0550/1.0550;ga3=1./12.92;ga4=0.039289;}//sRGB 2.4 12.92 - RT default as Lightroom + else if (gam=="High_g1.3_s3.35") {ga0=1.3 ; ga1=1./1.001724; ga2=0.001724/1.001724;ga3=1./3.35;ga4=0.001715;}//for high dynamic images + else if (gam== "Low_g2.6_s6.9") {ga0=2.6 ; ga1=1./1.12213; ga2=0.12213/1.12213;ga3=1./6.90;ga4=0.01;} //gamma 2.6 variable : for low contrast images + else if (gam=="linear_g1.0") {ga0=1.0; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;}//gamma=1 linear : for high dynamic images (cf : D.Coffin...) + else if (gam=="standard_g2.2") {ga0=2.2; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;}//gamma=2.2 (as gamma of Adobe, Widegamut...) + else if (gam=="standard_g1.8") {ga0=1.8; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;}//gamma=1.8 (as gamma of Prophoto) + + + if(select_temp==1) t50=5003;// for Widegamut, Prophoto Best, Beta D50 + else if (select_temp==2) t50=6504;// for sRGB, AdobeRGB, Bruce D65 + + cmsCIExyY xyD; + cmsCIExyYTRIPLE Primaries = {{p1, p2, 1.0},//red primaries + {p3, p4, 1.0}, // green + {p5, p6, 1.0} //blue + }; + cmsToneCurve* GammaTRC[3]; + cmsFloat64Number Parameters[7]; + Parameters[0] = ga0; + Parameters[1] = ga1; + Parameters[2] = ga2; + Parameters[3] = ga3; + Parameters[4] = ga4; + Parameters[5] = ga5; + Parameters[6] = 0; +// 6 parameters for smoother curves + cmsWhitePointFromTemp(&xyD, t50); + GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters);//5 = more smoother than 4 + cmsHPROFILE oprofdef = cmsCreateRGBProfileTHR(NULL, &xyD, &Primaries, GammaTRC); + + cmsFreeToneCurve(GammaTRC[0]); + + + if (oprofdef) { + #pragma omp parallel for if (multiThread) + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + short* xa = (short*)image->r[i-cy]; + short* ya = (short*)image->g[i-cy]; + short* za = (short*)image->b[i-cy]; + for (int j=cx; jgetXYZProfile (); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16_PLANAR, oprofdef, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE); + lcmsMutex->unlock (); + + cmsDoTransform (hTransform, image->data, image->data, image->planestride); + cmsDeleteTransform(hTransform); + } else { + // + #pragma omp parallel for if (multiThread) + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + for (int j=cx; jr[i-cy][j-cx] = (int)gamma2curve[(R)]; + image->g[i-cy][j-cx] = (int)gamma2curve[(G)]; + image->b[i-cy][j-cx] = (int)gamma2curve[(B)]; + } + } + } + return image; +} //#include "sRGBgamutbdy.cc" diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 1228d0f82..a46ecd8e9 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -154,7 +154,8 @@ enum ProcEvent { EvAutoDIST=129, EvDPDNLumCurve=130, EvDPDNChromCurve=131, - NUMOFEVENTS=132 + EvGAMMA=132, + NUMOFEVENTS=133 }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e7ec3764f..59d35e411 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -210,7 +210,8 @@ void ProcParams::setDefaults () { icm.gammaOnInput = false; icm.working = "sRGB"; icm.output = "sRGB"; - + icm.gamma = "default"; + equalizer.enabled = false; for(int i = 0; i < 8; i ++) { @@ -427,6 +428,7 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_boolean ("Color Management", "ApplyGammaBeforeInputProfile", icm.gammaOnInput); keyFile.set_string ("Color Management", "WorkingProfile", icm.working); keyFile.set_string ("Color Management", "OutputProfile", icm.output); + keyFile.set_string ("Color Management", "Gammafree", icm.gamma); // save wavelet equalizer parameters keyFile.set_boolean ("Equalizer", "Enabled", equalizer.enabled); @@ -741,6 +743,8 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "ApplyGammaBeforeInputProfile")) icm.gammaOnInput = keyFile.get_boolean ("Color Management", "ApplyGammaBeforeInputProfile"); if (keyFile.has_key ("Color Management", "WorkingProfile")) icm.working = keyFile.get_string ("Color Management", "WorkingProfile"); if (keyFile.has_key ("Color Management", "OutputProfile")) icm.output = keyFile.get_string ("Color Management", "OutputProfile"); + if (keyFile.has_key ("Color Management", "Gammafree")) icm.gamma = keyFile.get_string ("Color Management", "Gammafree"); + } // load wavelet equalizer parameters @@ -989,6 +993,7 @@ bool ProcParams::operator== (const ProcParams& other) { && icm.gammaOnInput == other.icm.gammaOnInput && icm.working == other.icm.working && icm.output == other.icm.output + && icm.gamma == other.icm.gamma && equalizer == other.equalizer && dirpyrequalizer == other.dirpyrequalizer && hsvequalizer.hcurve == other.hsvequalizer.hcurve diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 3d16e86ba..24d9133ca 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -331,6 +331,8 @@ class ColorManagementParams { bool gammaOnInput; Glib::ustring working; Glib::ustring output; + Glib::ustring gamma; + }; /** diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index ad295757c..7b6c52084 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1530,6 +1530,7 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams if (cmp.input == "(none)") return; + MyTime t1, t2, t3; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 7daef1748..bead5c509 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -127,8 +127,9 @@ class RawImageSource : public ImageSource { ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); double getDefGain () { return defGain; } - double getGamma () { return 2.2; } - + // double getGamma () { return 2.2; } + double getGamma () { return 2.4; }//normalize gamma to sRGB + void getFullSize (int& w, int& h, int tr = TR_NONE); void getSize (int tran, PreviewProps pp, int& w, int& h); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 9fa462e67..f1322fd9d 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -152,6 +152,7 @@ FLATFIELD, // EvFlatFieldBlurType, TRANSFORM, // EvAutoDIST, DIRPYRDENOISE, // EvDPDNLumCurve, DIRPYRDENOISE, // EvDPDNChromCurve, +ALL, // EvGAMMA }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index cbce0b301..233c9ec7e 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -319,6 +319,8 @@ namespace rtengine { /** Returns the available working profile names * @return a vector of the available working profile names */ std::vector getWorkingProfiles (); +/** return gamma */ + std::vector getGamma (); /** This class holds all the necessary informations to accomplish the full processing of the image */ class ProcessingJob { diff --git a/rtengine/settings.h b/rtengine/settings.h index b396ba15e..51e766118 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -34,7 +34,14 @@ namespace rtengine { Glib::ustring darkFramesPath; ///< The default directory for dark frames Glib::ustring flatFieldsPath; ///< The default directory for flat fields bool LCMSSafeMode; // If true, not OMP - + Glib::ustring adobe; + Glib::ustring prophoto; + Glib::ustring widegamut; + Glib::ustring beta; + Glib::ustring best; + Glib::ustring bruce; + Glib::ustring srgb; + /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ static Settings* create (); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 7394ee3a5..1bfba277a 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -24,16 +24,15 @@ #include #include #include - +#include #include - +#include #undef THREAD_PRIORITY_NORMAL #define CLIP(a) ((a)>0?((a)<65535?(a):65535):0) namespace rtengine { - IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData) { errorCode = 0; @@ -209,7 +208,130 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p cw = params.crop.w; ch = params.crop.h; } - Image16* readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); + + if(params.icm.gamma != "default") + { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 + Image16* readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.working, params.icm.gamma); + delete labView; + if (pl) pl->setProgress (0.70); + + // 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 (tunnelMetaData) + readyImg->setMetadata (ii->getMetaData()->getExifData ()); + else + readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); + + + ProfileContent pc; + Glib::ustring chpro; + int present_space[7]={0,0,0,0,0,0,0}; + std::vector opnames = rtengine::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 ih there are different for windows, MacOS, Linux ?? + 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...!! + } + //choose output profile + if(params.icm.working=="ProPhoto" && present_space[0]==1) params.icm.output=options.rtSettings.prophoto; + else if(params.icm.working=="Adobe RGB" && present_space[1]==1) params.icm.output=options.rtSettings.adobe; + else if(params.icm.working=="WideGamut" && present_space[2]==1) params.icm.output=options.rtSettings.widegamut; + else if(params.icm.working=="Beta RGB" && present_space[3]==1) params.icm.output=options.rtSettings.beta; + else if(params.icm.working=="BestRGB" && present_space[4]==1) params.icm.output=options.rtSettings.best; + else if(params.icm.working=="BruceRGB" && present_space[5]==1) params.icm.output=options.rtSettings.bruce; + else params.icm.output=options.rtSettings.srgb; //if not found or choice=srgb + + + if (params.icm.output.compare (0, 6, "No ICM") && params.icm.output!="") + 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; + } + else + {//if default mode : profil = selection by choice in list (Prophoto.icm, sRGB.icm, etc., etc.) , gamma = gamma of profile + Image16* readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); delete labView; if (pl) pl->setProgress (0.70); @@ -300,6 +422,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p return readyImg; + } } void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) { diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index f4bce96b2..dbeea3b4c 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -92,6 +92,22 @@ ICMPanel::ICMPanel () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL), std::vector wpnames = rtengine::getWorkingProfiles (); for (int i=0; iappend_text (wpnames[i]); + + Gtk::HSeparator* hsep22 = Gtk::manage (new Gtk::HSeparator ()); + pack_start (*hsep22, Gtk::PACK_SHRINK, 2); + + Gtk::Label* galab = Gtk::manage (new Gtk::Label ()); + galab->set_alignment (0.0, 0.5); + //galab->set_markup (Glib::ustring("") + M("TP_GAMMA_OUTPUT") + "" +M("TP_GAMMA_COMMENT")); + galab->set_markup (Glib::ustring("") + M("TP_GAMMA_OUTPUT") + ""); + + pack_start (*galab, Gtk::PACK_SHRINK, 4); + wgamma = Gtk::manage (new Gtk::ComboBoxText ()); + pack_start (*wgamma, Gtk::PACK_SHRINK, 4); + + std::vector wpgamma = rtengine::getGamma (); + for (int i=0; iappend_text (wpgamma[i]); onames->append_text (M("TP_ICM_NOICM")); onames->set_active (0); @@ -102,6 +118,7 @@ ICMPanel::ICMPanel () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL), wnames->set_active (0); onames->set_active (0); + wgamma->set_active (0); Gtk::FileFilter filter_icc; filter_icc.set_name(M("TP_ICM_FILEDLGFILTERICM")); @@ -124,6 +141,8 @@ ICMPanel::ICMPanel () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL), wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); + icamera->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); iembedded->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); ifromfile->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); @@ -157,7 +176,9 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { igamma->set_sensitive (true); } - wnames->set_active_text (pp->icm.working); + wnames->set_active_text (pp->icm.working); + wgamma->set_active_text (pp->icm.gamma); + if (pp->icm.output=="No ICM: sRGB output") onames->set_active_text (M("TP_ICM_NOICM")); else @@ -167,7 +188,8 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { onames->set_active_text (M("TP_ICM_NOICM")); igamma->set_active (pp->icm.gammaOnInput); - + onames->set_sensitive(wgamma->get_active_row_number()==0); //"default" + //thanks to Michael if (pedited) { iunchanged->set_active (!pedited->icm.input); igamma->set_sensitive (false); @@ -175,6 +197,9 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { wnames->set_active_text(M("GENERAL_UNCHANGED")); if (!pedited->icm.output) onames->set_active_text(M("GENERAL_UNCHANGED")); + if (!pedited->icm.gamma) + wgamma->set_active_text(M("GENERAL_UNCHANGED")); + } ipc.block (false); @@ -194,18 +219,21 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) { pp->icm.input = "file:"+ipDialog->get_filename (); pp->icm.working = wnames->get_active_text (); - + pp->icm.gamma = wgamma->get_active_text (); + if (onames->get_active_text()==M("TP_ICM_NOICM")) pp->icm.output = "No ICM: sRGB output"; else pp->icm.output = onames->get_active_text(); pp->icm.gammaOnInput = igamma->get_active (); - + if (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.gammaOnInput = !ifromfile->get_active (); + pedited->icm.gamma = wgamma->get_active_text()!=M("GENERAL_UNCHANGED"); + } } @@ -214,6 +242,14 @@ void ICMPanel::wpChanged () { if (listener) listener->panelChanged (EvWProfile, wnames->get_active_text ()); } +void ICMPanel::gpChanged () { + + if (listener) + {listener->panelChanged (EvGAMMA, wgamma->get_active_text ()); + onames->set_sensitive(wgamma->get_active_row_number()==0); //"default"//thanks to Michael + } + +} void ICMPanel::ipChanged () { @@ -297,5 +333,7 @@ void ICMPanel::setBatchMode (bool batchMode) { removeIfThere (this, saveRef); onames->append_text (M("GENERAL_UNCHANGED")); wnames->append_text (M("GENERAL_UNCHANGED")); + wgamma->append_text (M("GENERAL_UNCHANGED")); + } diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 7178f1b46..30c500aa9 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -37,6 +37,8 @@ class ICMPanel : public Gtk::VBox, public FoldableToolPanel { Gtk::RadioButton* ifromfile; Gtk::CheckButton* igamma; Gtk::ComboBoxText* wnames; + Gtk::ComboBoxText* wgamma; + Gtk::ComboBoxText* onames; Gtk::RadioButton* ofromdir; Gtk::RadioButton* ofromfile; @@ -58,6 +60,7 @@ class ICMPanel : public Gtk::VBox, public FoldableToolPanel { void wpChanged (); void opChanged (); void ipChanged (); + void gpChanged (); void ipSelectionChanged (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 9769cd64f..12a9cad46 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -152,6 +152,13 @@ void Options::setDefaults () { rtSettings.monitorProfile = ""; rtSettings.autoMonitorProfile = false; rtSettings.LCMSSafeMode = true; + rtSettings.adobe = "AdobeRGB1998"; + rtSettings.prophoto = "ProPhoto"; + rtSettings.widegamut = "WideGamutRGB"; + rtSettings.srgb = "sRGB Color Space Profile"; + rtSettings.bruce = "Bruce"; + rtSettings.beta = "BetaRGB"; + rtSettings.best = "BestRGB"; rtSettings.verbose = false; } @@ -458,6 +465,13 @@ 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", "Wide_Gamut", rtSettings.widegamut); + keyFile.set_string ("Color Management", "S_rgb", rtSettings.srgb); + 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); Glib::ArrayHandle bab = baBehav; keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 18e6c0d8d..7fc9701db 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -250,6 +250,7 @@ class ColorManagementParamsEdited { bool gammaOnInput; bool working; bool output; + bool gamma; }; class EqualizerParamsEdited {