diff --git a/rtdata/languages/default b/rtdata/languages/default index f0c4a64ac..656ade3cb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1118,7 +1118,6 @@ HISTORY_MSG_864;Local - Wavelet dir contrast attenuation HISTORY_MSG_865;Local - Wavelet dir contrast delta HISTORY_MSG_866;Local - Wavelet dir compression HISTORY_MSG_869;Local - Denoise by level - HISTORY_MSG_870;Local - Wavelet mask curve H HISTORY_MSG_871;Local - Wavelet mask curve C HISTORY_MSG_872;Local - Wavelet mask curve L @@ -1204,9 +1203,15 @@ HISTORY_MSG_954;Local - Show-hide tools HISTORY_MSG_955;Local - Enable Spot HISTORY_MSG_956;Local - CH Curve HISTORY_MSG_957;Local - Denoise mode -HISTORY_MSG_958;Local - Show/hide settings HISTORY_MSG_959;Local - Inverse blur +HISTORY_MSG_958;Local - Show/hide settings HISTORY_MSG_960;Local - Log encoding - cat02 +HISTORY_MSG_961;Local - Log encoding Ciecam +HISTORY_MSG_962;Local - Log encoding Absolute luminance source +HISTORY_MSG_963;Local - Log encoding Absolute luminance target +HISTORY_MSG_964;Local - Log encoding Surround +HISTORY_MSG_965;Local - Log encoding Saturation s +HISTORY_MSG_966;Local - Log encoding Contrast J HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_BLURWAV;Blur luminance @@ -2446,6 +2451,9 @@ TP_LOCALLAB_CHROMASKCOL;Chroma TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). TP_LOCALLAB_CHROMASK_TOOLTIP;You can use this slider to desaturated background (inverse mask - curve near 0).\nAlso to attenuate or enhance the action of a mask on the chroma TP_LOCALLAB_CHRRT;Chroma +TP_LOCALLAB_CIEC;Use Ciecam environment parameters +//TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM02 color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nOnly the third Ciecam process (Viewing conditions - Target) is taken into account, as well as part of the second (contrast J, saturation s) , as well as some data from the first process (Scene conditions - Source) which is used for the Log encoding.\nIt also adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. +TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM02 color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of the shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. TP_LOCALLAB_CIRCRADIUS;Spot size TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the RT-spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for treating foliage.\nHigh values may be useful for treating skin TP_LOCALLAB_CLARICRES;Merge chroma @@ -2473,6 +2481,7 @@ TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping TP_LOCALLAB_COMPRESS_TOOLTIP;Use if necessary the module 'Clarity & Sharp mask and Blend & Soften Images' by adjusting 'Soft radius' to reduce artifacts. TP_LOCALLAB_CONTCOL;Contrast threshold TP_LOCALLAB_CONTFRA;Contrast by level +TP_LOCALLAB_CONTL;Contrast (J) TP_LOCALLAB_CONTTHMASK_TOOLTIP;Allows you to determine which parts of the image will be impacted based on the texture. TP_LOCALLAB_CONTRAST;Contrast TP_LOCALLAB_CONTRASTCURVMASK1_TOOLTIP;Allows you to freely modify the contrast of the mask (gamma & slope), instead of using a continuous & progressive curve. However it can create artifacts that have to be dealt with using the “Smooth radius” or “Laplacian threshold sliders”. @@ -2667,15 +2676,23 @@ TP_LOCALLAB_LOGAUTO;Automatic TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and Source Gray Point (if "Automatic Source Gray Point” enabled).\nPress the button again to adjust the automatically calculated values. TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP;Estimated values of Dynamic Range i.e. Black Ev and White Ev +TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM02 takes into account the increase in perceived coloration with luminance. +TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. +TP_LOCALLAB_LOGCATAD_TOOLTIP;The chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance is far from reference D50.\nAdapts colors to the illuminant of the output device. TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process : 1) Dynamic Range calculation 2) Manual adjustment -TP_LOCALLAB_LOGFRA;Source -TP_LOCALLAB_LOG2FRA;Target -TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the Source Gray Point for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\n Takes into account exposure compensation in the main-menu Exposure tab. +TP_LOCALLAB_LOGFRA;Scene Conditions +TP_LOCALLAB_LOG1FRA;Image Adjustments +TP_LOCALLAB_LOG2FRA;Viewing Conditions +TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the Source Gray Point for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nTakes into account exposure compensation in the main-menu Exposure tab.\nAlso calculates the absolute luminance at the time of the shooting. +TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables (mainly Contrast 'J' and Saturation 's'). TP_LOCALLAB_LOGLIN;Logarithm mode TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM02 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium and highlights tones +TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. TP_LOCALLAB_LOGSRCGREY_TOOLTIP;Estimated gray point value of the image. TP_LOCALLAB_LOGTARGGREY_TOOLTIP;You can adjust this value to suit. TP_LOCALLAB_LOG_TOOLNAME;Log Encoding - 0 +TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer,..), as well as its environment. TP_LOCALLAB_LUM;Curves LL - CC TP_LOCALLAB_LUMADARKEST;Darkest TP_LOCALLAB_LUMASK;Background color for luminance and color masks @@ -2815,6 +2832,7 @@ TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted TP_LOCALLAB_ROW_NVIS;Not visible TP_LOCALLAB_ROW_VIS;Visible TP_LOCALLAB_SATUR;Saturation +TP_LOCALLAB_SATURV;Saturation (s) TP_LOCALLAB_SAVREST;Save - Restore Current Image TP_LOCALLAB_SCALEGR;Scale TP_LOCALLAB_SCALERETI;Scale @@ -2892,6 +2910,7 @@ TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to TP_LOCALLAB_SOFTRETI;Reduce ΔE artifacts TP_LOCALLAB_SOFTRETI_TOOLTIP;Take into account deltaE to improve Transmission map TP_LOCALLAB_SOFT_TOOLNAME;Soft Light & Original Retinex - 6 +TP_LOCALLAB_SOURCE_ABS;Absolute luminance TP_LOCALLAB_SOURCE_GRAY;Mean luminance (Yb%) TP_LOCALLAB_SPECCASE;Specific cases TP_LOCALLAB_SPECIAL;Special use of RGB curves diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index f9c4b786c..a564676ef 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -745,6 +745,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float *sourceg = nullptr; sourceg = new float[sizespot]; + float *sourceab = nullptr; + sourceab = new float[sizespot]; float *targetg = nullptr; targetg = new float[sizespot]; bool *log = nullptr; @@ -777,6 +779,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) blackev[sp] = params->locallab.spots.at(sp).blackEv; whiteev[sp] = params->locallab.spots.at(sp).whiteEv; sourceg[sp] = params->locallab.spots.at(sp).sourceGray; + sourceab[sp] = params->locallab.spots.at(sp).sourceabs; Autogr[sp] = params->locallab.spots.at(sp).Autogray; targetg[sp] = params->locallab.spots.at(sp).targetGray; locx[sp] = params->locallab.spots.at(sp).loc.at(0) / 2000.0; @@ -806,14 +809,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) xend = 1.f; } - ipf.getAutoLogloc(sp, imgsrc, sourceg, blackev, whiteev, Autogr, fw, fh, xsta, xend, ysta, yend, SCALE); + ipf.getAutoLogloc(sp, imgsrc, sourceg, blackev, whiteev, Autogr, sourceab, fw, fh, xsta, xend, ysta, yend, SCALE); params->locallab.spots.at(sp).blackEv = blackev[sp]; params->locallab.spots.at(sp).whiteEv = whiteev[sp]; params->locallab.spots.at(sp).sourceGray = sourceg[sp]; + params->locallab.spots.at(sp).sourceabs = sourceab[sp]; if (locallListener) { - locallListener->logencodChanged(blackev[sp], whiteev[sp], sourceg[sp], targetg[sp]); + locallListener->logencodChanged(blackev[sp], whiteev[sp], sourceg[sp], sourceab[sp], targetg[sp]); } } } @@ -829,6 +833,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete [] whiteev; delete [] blackev; delete [] targetg; + delete [] sourceab; delete [] sourceg; delete [] log; delete [] autocomput; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index a237e7c82..3f0d2c0e4 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -175,7 +175,7 @@ public: void moyeqt(Imagefloat* working, float &moyS, float &eqty); void luminanceCurve(LabImage* lold, LabImage* lnew, const LUTf &curve); - void ciecamloc_02float(int sp, LabImage* lab); + void ciecamloc_02float(int sp, LabImage* lab, int call); void ciecam_02float(CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const procparams::ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, @@ -264,7 +264,7 @@ public: //3 functions from Alberto Griggio, adapted J.Desmis 2019 void filmGrain(Imagefloat *rgb, int isogr, int strengr, int scalegr, int bfw, int bfh); void log_encode(Imagefloat *rgb, struct local_params & lp, bool multiThread, int bfw, int bfh); - void getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE); + void getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE); void MSRLocal(int call, int sp, bool fftw, int lum, float** reducDE, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 53d37ecad..a6e46b53a 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -36,7 +36,6 @@ #include "rt_algo.h" #include "settings.h" #include "../rtgui/options.h" - #include "utils.h" #ifdef _OPENMP #include @@ -1576,7 +1575,8 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool dynamic_range = 0.5f; } const float noise = pow_F(2.f, -16.f); - const float log2 = xlogf(lp.baselog); + // const float log2 = xlogf(lp.baselog); + const float log2 = xlogf(2.f); const float base = lp.targetgray > 1 && lp.targetgray < 100 && dynamic_range > 0 ? find_gray(std::abs(lp.blackev) / dynamic_range, lp.targetgray / 100.f) : 0.f; const float linbase = rtengine::max(base, 0.f); TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); @@ -1731,7 +1731,7 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool } } -void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE) +void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE) { //BENCHFUN //adpatation to local adjustments Jacques Desmis 12 2019 @@ -1837,10 +1837,41 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, } } } - const float gray = sourceg[sp] / 100.f; whiteev[sp] = xlogf(maxVal / gray) / log2; blackev[sp] = whiteev[sp] - dynamic_range; + + + //calculate La - Absolute luminance shooting + + const FramesMetaData* metaData = imgsrc->getMetaData(); + int imgNum = 0; + + if (imgsrc->isRAW()) { + if (imgsrc->getSensorType() == ST_BAYER) { + imgNum = rtengine::LIM(params->raw.bayersensor.imageNum, 0, metaData->getFrameCount() - 1); + } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { + //imgNum = rtengine::LIM(params->raw.xtranssensor.imageNum, 0, metaData->getFrameCount() - 1); + } + } + + float fnum = metaData->getFNumber(imgNum); // F number + float fiso = metaData->getISOSpeed(imgNum) ; // ISO + float fspeed = metaData->getShutterSpeed(imgNum) ; // Speed + double fcomp = metaData->getExpComp(imgNum); // Compensation +/- + double adap; + + if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong + adap = 2000.; + } else { + double E_V = fcomp + std::log2(double ((fnum * fnum) / fspeed / (fiso / 100.f))); + E_V += params->toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV + E_V += std::log2(params->raw.expos); // exposure raw white point ; log2 ==> linear to EV + adap = pow(2.0, E_V - 3.0); // cd / m2 + // end calculation adaptation scene luminosity + } + + sourceab[sp] = adap; } } @@ -2072,11 +2103,13 @@ void tone_eq(array2D &R, array2D &G, array2D &B, const str } -void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) +void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab, int call) { - //be careful quasi duplicate with branch cat02wb //BENCHFUN - + bool ciec = false; + if (params->locallab.spots.at(sp).ciecam && params->locallab.spots.at(sp).explog && call == 1) { + ciec = true; + } int width = lab->W, height = lab->H; float Yw; Yw = 1.0f; @@ -2088,18 +2121,119 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) double Xwout, Zwout; double Xwsc, Zwsc; - int tempo = 5000; + LUTu hist16J; + //for J light and contrast + LUTf CAMBrightCurveJ; + CAMBrightCurveJ(32768, LUT_CLIP_ABOVE); + CAMBrightCurveJ.dirty = true; - if (params->locallab.spots.at(sp).warm > 0) { - tempo = 5000 - 30 * params->locallab.spots.at(sp).warm; - } else if (params->locallab.spots.at(sp).warm < 0){ - tempo = 5000 - 49 * params->locallab.spots.at(sp).warm; + if (CAMBrightCurveJ.dirty) { + hist16J(32768); + hist16J.clear(); + + double sum = 0.0; // use double precision for large summations + +#ifdef _OPENMP + const int numThreads = min(max(width * height / 65536, 1), omp_get_max_threads()); + #pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif + { + LUTu hist16Jthr; + hist16Jthr(hist16J.getSize()); + hist16Jthr.clear(); + +#ifdef _OPENMP + #pragma omp for reduction(+:sum) +#endif + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { //rough correspondence between L and J + float currL = lab->L[i][j] / 327.68f; + float koef; //rough correspondence between L and J + + if (currL > 50.f) { + if (currL > 70.f) { + if (currL > 80.f) { + if (currL > 85.f) { + koef = 0.97f; + } else { + koef = 0.93f; + } + } else { + koef = 0.87f; + } + } else { + if (currL > 60.f) { + koef = 0.85f; + } else { + koef = 0.8f; + } + } + } else { + if (currL > 10.f) { + if (currL > 20.f) { + if (currL > 40.f) { + koef = 0.75f; + } else { + koef = 0.7f; + } + } else { + koef = 0.9f; + } + } else { + koef = 1.0; + } + } + + hist16Jthr[(int)((koef * lab->L[i][j]))]++; //evaluate histogram luminance L # J + sum += static_cast(koef) * static_cast(lab->L[i][j]); //evaluate mean J to calculate Yb + //sum not used, but perhaps... + } + } + +#ifdef _OPENMP + #pragma omp critical +#endif + { + hist16J += hist16Jthr; + } + } +#ifdef _OPENMP + static_cast(numThreads); // to silence cppcheck warning +#endif + + //evaluate lightness, contrast + } + + + + + + float contL = 0.f; + if (ciec) { + contL = 0.6f *params->locallab.spots.at(sp).contl;//0.6 less effect, no need 1. + + if (CAMBrightCurveJ.dirty) { + Ciecam02::curveJfloat(0.f, contL, hist16J, CAMBrightCurveJ); //contrast J + CAMBrightCurveJ /= 327.68f; + CAMBrightCurveJ.dirty = false; + } + } + int tempo = 5000; + if(params->locallab.spots.at(sp).expvibrance && call == 2) { + if (params->locallab.spots.at(sp).warm > 0) { + tempo = 5000 - 30 * params->locallab.spots.at(sp).warm; + } else if (params->locallab.spots.at(sp).warm < 0){ + tempo = 5000 - 70 * params->locallab.spots.at(sp).warm; + } } - if (params->locallab.spots.at(sp).catad > 0) { - tempo = 5000 - 30 * params->locallab.spots.at(sp).catad; - } else if (params->locallab.spots.at(sp).catad < 0){ - tempo = 5000 - 49 * params->locallab.spots.at(sp).catad; + if(ciec) { + if (params->locallab.spots.at(sp).catad > 0) { + tempo = 5000 - 30 * params->locallab.spots.at(sp).catad; + } else if (params->locallab.spots.at(sp).catad < 0){ + tempo = 5000 - 70 * params->locallab.spots.at(sp).catad; + } } @@ -2113,8 +2247,25 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) nc = 1.00f; //viewing condition for surround f2 = 1.0f, c2 = 0.69f, nc2 = 1.0f; - //with which algorithm - // alg = 0; + if(ciec) { + //viewing condition for surround + if (params->locallab.spots.at(sp).surround == "Average") { + f2 = 1.0f, c2 = 0.69f, nc2 = 1.0f; + } else if (params->locallab.spots.at(sp).surround == "Dim") { + f2 = 0.9f; + c2 = 0.59f; + nc2 = 0.9f; + } else if (params->locallab.spots.at(sp).surround == "Dark") { + f2 = 0.8f; + c2 = 0.525f; + nc2 = 0.8f; + } else if (params->locallab.spots.at(sp).surround == "ExtremelyDark") { + f2 = 0.8f; + c2 = 0.41f; + nc2 = 0.8f; + } + } + xwd = 100.0 * Xwout; @@ -2126,18 +2277,42 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) yws = 100.f; - yb2 = 18; //La and la2 = ambiant luminosity scene and viewing la = 400.f; - const float la2 = 400.f; + float la2 = 400.f; + if(ciec) { + la = params->locallab.spots.at(sp).sourceabs; + + la2 = params->locallab.spots.at(sp).targabs; + } + const float pilot = 2.f; const float pilotout = 2.f; //algoritm's params - // const float rstprotection = 100. ;//- params->colorappearance.rstprotection; - LUTu hist16J; LUTu hist16Q; float yb = 18.f; + yb2 = 18; + if(ciec) { + yb = params->locallab.spots.at(sp).targetGray;//target because we are after Log encoding + + yb2 = params->locallab.spots.at(sp).targetGray; + } + + float schr = 0.f; + + if (ciec) { + schr = params->locallab.spots.at(sp).saturl; + + if (schr > 0.f) { + schr = schr / 2.f; //divide sensibility for saturation + } + + if (schr == -100.f) { + schr = -99.8f; + } + } + float d, dj; // const int gamu = 0; //(params->colorappearance.gamut) ? 1 : 0; @@ -2145,7 +2320,11 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) yw = 100.f * Yw; zw = 100.0 * Zw; float xw1 = xws, yw1 = yws, zw1 = zws, xw2 = xwd, yw2 = ywd, zw2 = zwd; - +/* + xw1 = 96.46f; //use RT WB; CAT 02 is used for output device (see prefreneces) + yw1 = 100.0f; + zw1 = 82.445f; +*/ float cz, wh, pfl; Ciecam02::initcam1float(yb, pilot, f, la, xw, yw, zw, n, d, nbb, ncb, cz, aw, wh, pfl, fl, c); // const float chr = 0.f; @@ -2156,6 +2335,8 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) const float reccmcz = 1.f / (c2 * czj); #endif const float pow1n = pow_F(1.64f - pow_F(0.29f, nj), 0.73f); + const float coe = pow_F(fl, 0.25f); + const float QproFactor = (0.4f / c) * (aw + 4.0f) ; #ifdef __SSE2__ int bufferLength = ((width + 3) / 4) * 4; // bufferLength has to be a multiple of 4 @@ -2267,7 +2448,21 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) spro = s; /* */ - + if(ciec) { + Jpro = CAMBrightCurveJ[Jpro * 327.68f]; //CIECAM02 + contrast + float sres; + float rstprotection = 50.f;//arbitrary 50% protection skin tones + float Sp = spro / 100.0f; + float parsat = 1.5f; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) + Ciecam02::curvecolorfloat(schr, Sp, sres, parsat); + float dred = 100.f; // in C mode + float protect_red = 80.0f; // in C mode + dred = 100.0f * sqrtf((dred * coe) / Qpro); + protect_red = 100.0f * sqrtf((protect_red * coe) / Qpro); + Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red, 0, rstprotection, 100.f, spro); + Qpro = QproFactor * sqrtf(Jpro); + Cpro = (spro * spro * Qpro) / (10000.0f); + } //retrieve values C,J...s C = Cpro; @@ -9693,8 +9888,8 @@ void ImProcFunctions::Lab_Local( log_encode(tmpImage.get(), lp, multiThread, bfw, bfh); rgb2lab(*(tmpImage.get()), *bufexpfin, params->icm.workingProfile); tmpImage.reset(); - if (params->locallab.spots.at(sp).catad != 0) { - ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get()); + if (params->locallab.spots.at(sp).ciecam) { + ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get(), 1); } //here begin graduated filter @@ -10819,7 +11014,7 @@ void ImProcFunctions::Lab_Local( ImProcFunctions::vibrance(bufexpfin.get(), vibranceParams, params->toneCurve.hrenabled, params->icm.workingProfile); if (params->locallab.spots.at(sp).warm != 0) { - ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get()); + ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get(), 2); } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index b9d815612..22b967ee7 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -983,6 +983,12 @@ enum ProcEventCode { Evlocallabhishow = 957, Evlocallabinvbl = 958, Evlocallabcatad = 959, + Evlocallabciecam = 960, + Evlocallabsourceabs = 961, + Evlocallabtargabs = 962, + Evlocallabsurround = 963, + Evlocallabsaturl = 964, + Evlocallabcontl = 965, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 574123762..7a56248bf 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3837,14 +3837,20 @@ LocallabParams::LocallabSpot::LocallabSpot() : explog(false), autocompute(false), sourceGray(10.), + sourceabs(2000.), + targabs(16.), targetGray(18.), catad(0.), + saturl(0.), + contl(0.), Autogray(true), fullimage(true), + ciecam(false), blackEv(-5.0), whiteEv(10.0), detail(0.6), sensilog(60), + surround("Average"), baselog(2.), strlog(0.0), anglog(0.0), @@ -4415,15 +4421,21 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && explog == other.explog && autocompute == other.autocompute && sourceGray == other.sourceGray + && sourceabs == other.sourceabs + && targabs == other.targabs && targetGray == other.targetGray && catad == other.catad + && saturl == other.saturl + && contl == other.contl && Autogray == other.Autogray && fullimage == other.fullimage + && ciecam == other.ciecam && blackEv == other.blackEv && whiteEv == other.whiteEv && detail == other.detail && sensilog == other.sensilog && baselog == other.baselog + && surround == other.surround && strlog == other.strlog && anglog == other.anglog // mask @@ -5950,15 +5962,21 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->explog, "Locallab", "Explog_" + index_str, spot.explog, keyFile); saveToKeyfile(!pedited || spot_edited->autocompute, "Locallab", "Autocompute_" + index_str, spot.autocompute, keyFile); saveToKeyfile(!pedited || spot_edited->sourceGray, "Locallab", "SourceGray_" + index_str, spot.sourceGray, keyFile); + saveToKeyfile(!pedited || spot_edited->sourceabs, "Locallab", "Sourceabs_" + index_str, spot.sourceabs, keyFile); + saveToKeyfile(!pedited || spot_edited->targabs, "Locallab", "Targabs_" + index_str, spot.targabs, keyFile); saveToKeyfile(!pedited || spot_edited->targetGray, "Locallab", "TargetGray_" + index_str, spot.targetGray, keyFile); saveToKeyfile(!pedited || spot_edited->catad, "Locallab", "Catad_" + index_str, spot.catad, keyFile); + saveToKeyfile(!pedited || spot_edited->saturl, "Locallab", "Saturl_" + index_str, spot.saturl, keyFile); + saveToKeyfile(!pedited || spot_edited->contl, "Locallab", "Contl_" + index_str, spot.contl, keyFile); saveToKeyfile(!pedited || spot_edited->Autogray, "Locallab", "Autogray_" + index_str, spot.Autogray, keyFile); saveToKeyfile(!pedited || spot_edited->fullimage, "Locallab", "Fullimage_" + index_str, spot.fullimage, keyFile); + saveToKeyfile(!pedited || spot_edited->ciecam, "Locallab", "Ciecam_" + index_str, spot.ciecam, keyFile); saveToKeyfile(!pedited || spot_edited->blackEv, "Locallab", "BlackEv_" + index_str, spot.blackEv, keyFile); saveToKeyfile(!pedited || spot_edited->whiteEv, "Locallab", "WhiteEv_" + index_str, spot.whiteEv, keyFile); saveToKeyfile(!pedited || spot_edited->detail, "Locallab", "Detail_" + index_str, spot.detail, keyFile); saveToKeyfile(!pedited || spot_edited->sensilog, "Locallab", "Sensilog_" + index_str, spot.sensilog, keyFile); saveToKeyfile(!pedited || spot_edited->baselog, "Locallab", "Baselog_" + index_str, spot.baselog, keyFile); + saveToKeyfile(!pedited || spot_edited->surround, "Locallab", "Surround_" + index_str, spot.surround, keyFile); saveToKeyfile(!pedited || spot_edited->strlog, "Locallab", "Strlog_" + index_str, spot.strlog, keyFile); saveToKeyfile(!pedited || spot_edited->anglog, "Locallab", "Anglog_" + index_str, spot.anglog, keyFile); } @@ -7727,15 +7745,21 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Autocompute_" + index_str, pedited, spot.autocompute, spotEdited.autocompute); assignFromKeyfile(keyFile, "Locallab", "SourceGray_" + index_str, pedited, spot.sourceGray, spotEdited.sourceGray); + assignFromKeyfile(keyFile, "Locallab", "Sourceabs_" + index_str, pedited, spot.sourceabs, spotEdited.sourceabs); + assignFromKeyfile(keyFile, "Locallab", "Targabs_" + index_str, pedited, spot.targabs, spotEdited.targabs); assignFromKeyfile(keyFile, "Locallab", "TargetGray_" + index_str, pedited, spot.targetGray, spotEdited.targetGray); assignFromKeyfile(keyFile, "Locallab", "Catad_" + index_str, pedited, spot.catad, spotEdited.catad); + assignFromKeyfile(keyFile, "Locallab", "Saturl_" + index_str, pedited, spot.saturl, spotEdited.saturl); + assignFromKeyfile(keyFile, "Locallab", "Contl_" + index_str, pedited, spot.contl, spotEdited.contl); assignFromKeyfile(keyFile, "Locallab", "AutoGray_" + index_str, pedited, spot.Autogray, spotEdited.Autogray); assignFromKeyfile(keyFile, "Locallab", "Fullimage_" + index_str, pedited, spot.fullimage, spotEdited.fullimage); + assignFromKeyfile(keyFile, "Locallab", "Ciecam_" + index_str, pedited, spot.ciecam, spotEdited.ciecam); assignFromKeyfile(keyFile, "Locallab", "BlackEv_" + index_str, pedited, spot.blackEv, spotEdited.blackEv); assignFromKeyfile(keyFile, "Locallab", "WhiteEv_" + index_str, pedited, spot.whiteEv, spotEdited.whiteEv); assignFromKeyfile(keyFile, "Locallab", "Detail_" + index_str, pedited, spot.detail, spotEdited.detail); assignFromKeyfile(keyFile, "Locallab", "Sensilog_" + index_str, pedited, spot.sensilog, spotEdited.sensilog); assignFromKeyfile(keyFile, "Locallab", "Baselog_" + index_str, pedited, spot.baselog, spotEdited.baselog); + assignFromKeyfile(keyFile, "Locallab", "Surround_" + index_str, pedited, spot.surround, spotEdited.surround); assignFromKeyfile(keyFile, "Locallab", "Strlog_" + index_str, pedited, spot.strlog, spotEdited.strlog); assignFromKeyfile(keyFile, "Locallab", "Anglog_" + index_str, pedited, spot.anglog, spotEdited.anglog); // mask diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 53a008a29..1ba0f5e80 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1424,14 +1424,20 @@ struct LocallabParams { bool explog; bool autocompute; double sourceGray; + double sourceabs; + double targabs; double targetGray; double catad; + double saturl; + double contl; bool Autogray; bool fullimage; + bool ciecam; double blackEv; double whiteEv; double detail; int sensilog; + Glib::ustring surround; double baselog; double strlog; double anglog; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 6daf01621..593e5b9c9 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -986,7 +986,13 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvlocallabquaMethod LUMINANCECURVE, //Evlocallabhishow LUMINANCECURVE, // Evlocallabinvbl - LUMINANCECURVE // Evlocallabcatad + LUMINANCECURVE, // Evlocallabcatad + LUMINANCECURVE, // Evlocallabciecam + LUMINANCECURVE, // Evlocallabsourceabs + LUMINANCECURVE, // Evlocallabtargabs + LUMINANCECURVE, // Evlocallabsurround + LUMINANCECURVE, // Evlocallabsaturl + LUMINANCECURVE // Evlocallabcontl }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6f6baccd4..74214737e 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -439,7 +439,7 @@ public: virtual ~LocallabListener() = default; virtual void refChanged(const std::vector &ref, int selspot) = 0; virtual void minmaxChanged(const std::vector &minmax, int selspot) = 0; - virtual void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float targetg) = 0; + virtual void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) = 0; }; class AutoColorTonListener diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 1710a060f..5ca46bc99 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -1017,10 +1017,10 @@ void Locallab::minmaxChanged(const std::vector &minmax, int } } -void Locallab::logencodChanged(const float blackev, const float whiteev, const float sourceg, const float targetg) +void Locallab::logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) { // Update Locallab Log Encoding accordingly - explog->updateAutocompute(blackev, whiteev, sourceg, targetg); + explog->updateAutocompute(blackev, whiteev, sourceg, sourceab, targetg); } void Locallab::refChanged(const std::vector &ref, int selspot) diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 44e408d49..a6491ebd6 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -141,7 +141,7 @@ public: void minmaxChanged(const std::vector &minmax, int selspot) override; // Locallab Log Encoding autocompute function - void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float targetg) override; + void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) override; // Locallab tools mask background management function void refChanged(const std::vector &ref, int selspot) override; diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index ff4062f0f..ff8d6e6f6 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -1190,27 +1190,39 @@ class LocallabLog: public LocallabTool { private: + Gtk::CheckButton* const ciecam; Gtk::ToggleButton* const autocompute; Gtk::Frame* const logPFrame; Adjuster* const blackEv; Adjuster* const whiteEv; Gtk::CheckButton* const fullimage; + Gtk::Frame* const logFrame; Gtk::CheckButton* const Autogray; Adjuster* const sourceGray; + Adjuster* const sourceabs; + Gtk::Frame* const log1Frame; Gtk::Frame* const log2Frame; Adjuster* const targetGray; Adjuster* const detail; Adjuster* const catad; + Adjuster* const contl; + Adjuster* const saturl; + Adjuster* const targabs; + MyComboBoxText* const surround; + Gtk::HBox* const surrHBox; + Adjuster* const baselog; Adjuster* const sensilog; Adjuster* const strlog; Adjuster* const anglog; - sigc::connection autoconn, fullimageConn, AutograyConn; + sigc::connection autoconn, ciecamconn, fullimageConn, AutograyConn; + sigc::connection surroundconn; public: LocallabLog(); void updateAdviceTooltips(const bool showTooltips) override; + void surroundChanged(); void disableListener() override; void enableListener() override; @@ -1219,7 +1231,7 @@ public: void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged(Adjuster* a, double newval) override; - void updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float targetg); + void updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg); private: void enabledChanged() override; @@ -1227,8 +1239,10 @@ private: void autocomputeToggled(); void fullimageChanged(); void AutograyChanged(); + void ciecamChanged(); void updateLogGUI(); + void updateLogGUI2(); }; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 67917c700..a87e35786 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -4652,18 +4652,28 @@ LocallabLog::LocallabLog(): LocallabTool(this, M("TP_LOCALLAB_LOG_TOOLNAME"), M("TP_LOCALLAB_LOG"), false, false), // Log encoding specific widgets + ciecam(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_CIEC")))), autocompute(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_LOGAUTO")))), logPFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGPFRA")))), blackEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.0, 0.0, 0.1, -5.0))), whiteEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0., 32.0, 0.1, 10.0))), fullimage(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FULLIMAGE")))), + logFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA")))), Autogray(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AUTOGRAY")))), sourceGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_GRAY"), 1.0, 100.0, 0.1, 10.0))), + sourceabs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 2000.0))), + log1Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG1FRA")))), log2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), targetGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1, 18.0))), detail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 1., 0.01, 0.6))), - catad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0.))), - baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 8., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + catad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-orange-small.png"))))), + contl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CONTL"), -100., 100., 0.5, 0.))), + saturl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SATURV"), -100., 100., 0.5, 0.))), + targabs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 16.0))), + surround(Gtk::manage (new MyComboBoxText ())), + surrHBox(Gtk::manage(new Gtk::HBox())), + + baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 3., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), sensilog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), strlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2.0, 2.0, 0.05, 0.))), anglog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))) @@ -4676,6 +4686,7 @@ LocallabLog::LocallabLog(): whiteEv->setLogScale(16, 0); whiteEv->setAdjusterListener(this); + ciecamconn = ciecam->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::ciecamChanged)); fullimageConn = fullimage->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::fullimageChanged)); @@ -4683,12 +4694,24 @@ LocallabLog::LocallabLog(): sourceGray->setAdjusterListener(this); + sourceabs->setLogScale(500, 0); + + sourceabs->setAdjusterListener(this); + targetGray->setAdjusterListener(this); detail->setAdjusterListener(this); catad->setAdjusterListener(this); + saturl->setAdjusterListener(this); + + contl->setAdjusterListener(this); + + targabs->setLogScale(500, 0); + + targabs->setAdjusterListener(this); + baselog->setAdjusterListener(this); sensilog->setAdjusterListener(this); @@ -4697,7 +4720,21 @@ LocallabLog::LocallabLog(): anglog->setAdjusterListener(this); +// Gtk::HBox* surrHBox = Gtk::manage (new Gtk::HBox ()); + surrHBox->set_spacing (2); + surrHBox->set_tooltip_markup (M ("TP_COLORAPP_SURROUND_TOOLTIP")); + Gtk::Label* surrLabel = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_SURROUND") + ":")); + surrHBox->pack_start (*surrLabel, Gtk::PACK_SHRINK); + surround->append (M ("TP_COLORAPP_SURROUND_AVER")); + surround->append (M ("TP_COLORAPP_SURROUND_DIM")); + surround->append (M ("TP_COLORAPP_SURROUND_DARK")); + surround->append (M ("TP_COLORAPP_SURROUND_EXDARK")); + surround->set_active (0); + surrHBox->pack_start (*surround); + surroundconn = surround->signal_changed().connect ( sigc::mem_fun (*this, &LocallabLog::surroundChanged) ); + // Add Log encoding specific widgets to GUI + pack_start(*ciecam); logPFrame->set_label_align(0.025, 0.5); ToolParamBlock* const logPBox = Gtk::manage(new ToolParamBlock()); logPBox->pack_start(*autocompute); @@ -4706,19 +4743,28 @@ LocallabLog::LocallabLog(): logPBox->pack_start(*fullimage); logPFrame->add(*logPBox); pack_start(*logPFrame); - Gtk::Frame* const logFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA"))); +// Gtk::Frame* const logFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA"))); logFrame->set_label_align(0.025, 0.5); ToolParamBlock* const logFBox = Gtk::manage(new ToolParamBlock()); logFBox->pack_start(*Autogray); logFBox->pack_start(*sourceGray); - logFBox->pack_start(*baselog); + logFBox->pack_start(*sourceabs); +// logFBox->pack_start(*baselog); logFrame->add(*logFBox); pack_start(*logFrame); - log2Frame->set_label_align(0.025, 0.5); + log1Frame->set_label_align(0.025, 0.5); + ToolParamBlock* const logP1Box = Gtk::manage(new ToolParamBlock()); + logP1Box->pack_start(*detail); + logP1Box->pack_start(*contl); + logP1Box->pack_start(*saturl); + log1Frame->add(*logP1Box); + pack_start(*log1Frame); + log2Frame->set_label_align(0.025, 0.5); ToolParamBlock* const logP2Box = Gtk::manage(new ToolParamBlock()); logP2Box->pack_start(*targetGray); - logP2Box->pack_start(*detail); + logP2Box->pack_start(*targabs); logP2Box->pack_start(*catad); + logP2Box->pack_start (*surrHBox); log2Frame->add(*logP2Box); pack_start(*log2Frame); // pack_start(*baselog); @@ -4737,31 +4783,44 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) if (showTooltips) { exp->set_tooltip_text(M("TP_LOCALLAB_LOGENCOD_TOOLTIP")); logPFrame->set_tooltip_text(M("TP_LOCALLAB_LOGFRAME_TOOLTIP")); + logFrame->set_tooltip_text(M("TP_LOCALLAB_LOGSCENE_TOOLTIP")); + log1Frame->set_tooltip_text(M("TP_LOCALLAB_LOGIMAGE_TOOLTIP")); + log2Frame->set_tooltip_text(M("TP_LOCALLAB_LOGVIEWING_TOOLTIP")); autocompute->set_tooltip_text(M("TP_LOCALLAB_LOGAUTO_TOOLTIP")); // blackEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); // whiteEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); blackEv->set_tooltip_text(""); whiteEv->set_tooltip_text(""); sourceGray->set_tooltip_text(""); - targetGray->set_tooltip_text(M("TP_LOCALLAB_LOGTARGGREY_TOOLTIP")); + sourceabs->set_tooltip_text(M("TP_COLORAPP_ADAPSCEN_TOOLTIP")); + targabs->set_tooltip_text(M("TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP")); + targetGray->set_tooltip_text(M("TP_COLORAPP_YBOUT_TOOLTIP")); baselog->set_tooltip_text(M("TP_LOCALLAB_LOGBASE_TOOLTIP")); strlog->set_tooltip_text(M("TP_LOCALLAB_GRADGEN_TOOLTIP")); anglog->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); - + contl->set_tooltip_text(M("TP_LOCALLAB_LOGCONTL_TOOLTIP")); + saturl->set_tooltip_text(M("TP_LOCALLAB_LOGSATURL_TOOLTIP")); + detail->set_tooltip_text(M("TP_LOCALLAB_LOGDETAIL_TOOLTIP")); + catad->set_tooltip_text(M("TP_LOCALLAB_LOGCATAD_TOOLTIP")); // detail->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); // Autogray->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); // sensilog->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); - detail->set_tooltip_text(""); Autogray->set_tooltip_text(""); sensilog->set_tooltip_text(M("TP_LOCALLAB_SENSI_TOOLTIP")); fullimage->set_tooltip_text(M("TP_LOCALLAB_FULLIMAGELOG_TOOLTIP")); + ciecam->set_tooltip_text(M("TP_LOCALLAB_CIECAMLOG_TOOLTIP")); } else { exp->set_tooltip_text(""); logPFrame->set_tooltip_text(""); + logFrame->set_tooltip_text(""); + log1Frame->set_tooltip_text(""); + log2Frame->set_tooltip_text(""); autocompute->set_tooltip_text(""); blackEv->set_tooltip_text(""); whiteEv->set_tooltip_text(""); sourceGray->set_tooltip_text(""); + sourceabs->set_tooltip_text(""); + targabs->set_tooltip_text(""); targetGray->set_tooltip_text(""); baselog->set_tooltip_text(""); strlog->set_tooltip_text(""); @@ -4770,7 +4829,10 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) Autogray->set_tooltip_text(""); sensilog->set_tooltip_text(""); fullimage->set_tooltip_text(""); - + ciecam->set_tooltip_text(""); + contl->set_tooltip_text(""); + saturl->set_tooltip_text(""); + catad->set_tooltip_text(""); } } @@ -4780,6 +4842,8 @@ void LocallabLog::disableListener() autoconn.block(true); fullimageConn.block(true); + ciecamconn.block(true); + surroundconn.block (true); AutograyConn.block(true); } @@ -4789,6 +4853,8 @@ void LocallabLog::enableListener() autoconn.block(false); fullimageConn.block(false); + ciecamconn.block(false); + surroundconn.block (false); AutograyConn.block(false); } @@ -4816,9 +4882,25 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE whiteEv->setValue(1.5); } */ + if (spot.surround == "Average") { + surround->set_active (0); + } else if (spot.surround == "Dim") { + surround->set_active (1); + } else if (spot.surround == "Dark") { + surround->set_active (2); + } else if (spot.surround == "ExtremelyDark") { + surround->set_active (3); + } + + ciecam->set_active(spot.ciecam); fullimage->set_active(spot.fullimage); Autogray->set_active(spot.Autogray); sourceGray->setValue(spot.sourceGray); + sourceabs->setValue(spot.sourceabs); + catad->setValue(spot.catad); + saturl->setValue(spot.saturl); + contl->setValue(spot.contl); + targabs->setValue(spot.targabs); targetGray->setValue(spot.targetGray); detail->setValue(spot.detail); baselog->setValue(spot.baselog); @@ -4832,6 +4914,7 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE // Update Log Encoding GUI according to autocompute button state updateLogGUI(); + updateLogGUI2(); // Note: No need to manage pedited as batch mode is deactivated for Locallab } @@ -4850,15 +4933,32 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.blackEv = blackEv->getValue(); spot.whiteEv = whiteEv->getValue(); spot.fullimage = fullimage->get_active(); + spot.ciecam = ciecam->get_active(); spot.Autogray = Autogray->get_active(); spot.sourceGray = sourceGray->getValue(); + spot.sourceabs = sourceabs->getValue(); + spot.targabs = targabs->getValue(); spot.targetGray = targetGray->getValue(); spot.catad = catad->getValue(); + spot.saturl = saturl->getValue(); + spot.contl = contl->getValue(); spot.detail = detail->getValue(); spot.baselog = baselog->getValue(); spot.sensilog = sensilog->getIntValue(); spot.strlog = strlog->getValue(); spot.anglog = anglog->getValue(); + + + if (surround->get_active_row_number() == 0) { + spot.surround = "Average"; + } else if (surround->get_active_row_number() == 1) { + spot.surround = "Dim"; + } else if (surround->get_active_row_number() == 2) { + spot.surround = "Dark"; + } else if (surround->get_active_row_number() == 3) { + spot.surround = "ExtremelyDark"; + } + } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -4875,8 +4975,12 @@ void LocallabLog::setDefaults(const rtengine::procparams::ProcParams* defParams, blackEv->setDefault(defSpot.blackEv); whiteEv->setDefault(defSpot.whiteEv); sourceGray->setDefault(defSpot.sourceGray); + sourceabs->setDefault(defSpot.sourceabs); + targabs->setDefault(defSpot.targabs); targetGray->setDefault(defSpot.targetGray); catad->setDefault(defSpot.catad); + saturl->setDefault(defSpot.saturl); + contl->setDefault(defSpot.contl); detail->setDefault(defSpot.detail); baselog->setDefault(defSpot.baselog); sensilog->setDefault((double)defSpot.sensilog); @@ -4911,6 +5015,20 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == sourceabs) { + if (listener) { + listener->panelChanged(Evlocallabsourceabs, + sourceabs->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + + if (a == targabs) { + if (listener) { + listener->panelChanged(Evlocallabtargabs, + targabs->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + if (a == targetGray) { if (listener) { listener->panelChanged(EvlocallabtargetGray, @@ -4925,6 +5043,20 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == saturl) { + if (listener) { + listener->panelChanged(Evlocallabsaturl, + saturl->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + + if (a == contl) { + if (listener) { + listener->panelChanged(Evlocallabcontl, + contl->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + if (a == detail) { if (listener) { listener->panelChanged(Evlocallabdetail, @@ -4962,10 +5094,10 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } -void LocallabLog::updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float targetg) +void LocallabLog::updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) { idle_register.add( - [this, blackev, whiteev, sourceg, targetg]() -> bool { + [this, blackev, whiteev, sourceg, sourceab, targetg]() -> bool { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected // Update adjuster values according to autocomputed ones @@ -4974,6 +5106,7 @@ void LocallabLog::updateAutocompute(const float blackev, const float whiteev, co blackEv->setValue(blackev); whiteEv->setValue(whiteev); sourceGray->setValue(sourceg); + sourceabs->setValue(sourceab); targetGray->setValue(targetg); enableListener(); @@ -4998,6 +5131,16 @@ void LocallabLog::enabledChanged() } } +void LocallabLog::surroundChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + listener->panelChanged(Evlocallabsurround, + surround->get_active_text() + " (" + escapeHtmlChars(spotName) + ")"); + } + } +} + void LocallabLog::autocomputeToggled() { // Update Log Encoding GUI according to autocompute button state @@ -5016,6 +5159,43 @@ void LocallabLog::autocomputeToggled() } } +void LocallabLog::ciecamChanged() +{ + if(ciecam->get_active()){ + /* sourceabs->set_sensitive(true); + targabs->set_sensitive(true); + catad->set_sensitive(true); + surrHBox->set_sensitive(true); + */ + sourceabs->show(); + targabs->show(); + catad->show(); + saturl->show(); + contl->show(); + surrHBox->show(); + } else { + sourceabs->hide(); + targabs->hide(); + saturl->hide(); + contl->hide(); + catad->hide(); + surrHBox->hide(); + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (ciecam->get_active()) { + listener->panelChanged(Evlocallabciecam, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(spotName) + ")"); + } else { + listener->panelChanged(Evlocallabciecam, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(spotName) + ")"); + } + } + } +} + + void LocallabLog::fullimageChanged() { if (isLocActivated && exp->getEnabled()) { @@ -5046,16 +5226,42 @@ void LocallabLog::AutograyChanged() } } +void LocallabLog::updateLogGUI2() +{ + if(ciecam->get_active()){ + sourceabs->show(); + targabs->show(); + catad->show(); + saturl->show(); + contl->show(); + surrHBox->show(); + } else { + sourceabs->hide(); + targabs->hide(); + catad->hide(); + saturl->hide(); + contl->hide(); + surrHBox->hide(); + } +} + + void LocallabLog::updateLogGUI() { if (autocompute->get_active()) { blackEv->set_sensitive(false); whiteEv->set_sensitive(false); sourceGray->set_sensitive(false); + sourceabs->set_sensitive(false); } else { blackEv->set_sensitive(true); whiteEv->set_sensitive(true); sourceGray->set_sensitive(true); + if(ciecam->get_active()){ + sourceabs->set_sensitive(true); + } else { + sourceabs->set_sensitive(false); + } } } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ae756feeb..fbe9d7315 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1496,13 +1496,19 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).explog = locallab.spots.at(j).explog && pSpot.explog == otherSpot.explog; locallab.spots.at(j).autocompute = locallab.spots.at(j).autocompute && pSpot.autocompute == otherSpot.autocompute; locallab.spots.at(j).sourceGray = locallab.spots.at(j).sourceGray && pSpot.sourceGray == otherSpot.sourceGray; + locallab.spots.at(j).sourceabs = locallab.spots.at(j).sourceabs && pSpot.sourceabs == otherSpot.sourceabs; + locallab.spots.at(j).targabs = locallab.spots.at(j).targabs && pSpot.targabs == otherSpot.targabs; locallab.spots.at(j).targetGray = locallab.spots.at(j).targetGray && pSpot.targetGray == otherSpot.targetGray; locallab.spots.at(j).catad = locallab.spots.at(j).catad && pSpot.catad == otherSpot.catad; + locallab.spots.at(j).saturl = locallab.spots.at(j).saturl && pSpot.saturl == otherSpot.saturl; + locallab.spots.at(j).contl = locallab.spots.at(j).contl && pSpot.contl == otherSpot.contl; locallab.spots.at(j).Autogray = locallab.spots.at(j).Autogray && pSpot.Autogray == otherSpot.Autogray; locallab.spots.at(j).fullimage = locallab.spots.at(j).fullimage && pSpot.fullimage == otherSpot.fullimage; + locallab.spots.at(j).ciecam = locallab.spots.at(j).ciecam && pSpot.ciecam == otherSpot.ciecam; locallab.spots.at(j).blackEv = locallab.spots.at(j).blackEv && pSpot.blackEv == otherSpot.blackEv; locallab.spots.at(j).whiteEv = locallab.spots.at(j).whiteEv && pSpot.whiteEv == otherSpot.whiteEv; locallab.spots.at(j).detail = locallab.spots.at(j).detail && pSpot.detail == otherSpot.detail; + locallab.spots.at(j).surround = locallab.spots.at(j).surround && pSpot.surround == otherSpot.surround; locallab.spots.at(j).sensilog = locallab.spots.at(j).sensilog && pSpot.sensilog == otherSpot.sensilog; locallab.spots.at(j).baselog = locallab.spots.at(j).baselog && pSpot.baselog == otherSpot.baselog; locallab.spots.at(j).strlog = locallab.spots.at(j).strlog && pSpot.strlog == otherSpot.strlog; @@ -4852,6 +4858,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).sourceGray = mods.locallab.spots.at(i).sourceGray; } + if (locallab.spots.at(i).sourceabs) { + toEdit.locallab.spots.at(i).sourceabs = mods.locallab.spots.at(i).sourceabs; + } + + if (locallab.spots.at(i).targabs) { + toEdit.locallab.spots.at(i).targabs = mods.locallab.spots.at(i).targabs; + } + if (locallab.spots.at(i).targetGray) { toEdit.locallab.spots.at(i).targetGray = mods.locallab.spots.at(i).targetGray; } @@ -4860,6 +4874,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).catad = mods.locallab.spots.at(i).catad; } + if (locallab.spots.at(i).saturl) { + toEdit.locallab.spots.at(i).saturl = mods.locallab.spots.at(i).saturl; + } + + if (locallab.spots.at(i).contl) { + toEdit.locallab.spots.at(i).contl = mods.locallab.spots.at(i).contl; + } + if (locallab.spots.at(i).Autogray) { toEdit.locallab.spots.at(i).Autogray = mods.locallab.spots.at(i).Autogray; } @@ -4868,6 +4890,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).fullimage = mods.locallab.spots.at(i).fullimage; } + if (locallab.spots.at(i).ciecam) { + toEdit.locallab.spots.at(i).ciecam = mods.locallab.spots.at(i).ciecam; + } + if (locallab.spots.at(i).blackEv) { toEdit.locallab.spots.at(i).blackEv = mods.locallab.spots.at(i).blackEv; } @@ -4888,6 +4914,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).baselog = mods.locallab.spots.at(i).baselog; } + if (locallab.spots.at(i).surround) { + toEdit.locallab.spots.at(i).surround = mods.locallab.spots.at(i).surround; + } + if (locallab.spots.at(i).strlog) { toEdit.locallab.spots.at(i).strlog = mods.locallab.spots.at(i).strlog; } @@ -6645,13 +6675,19 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : explog(v), autocompute(v), sourceGray(v), + sourceabs(v), + targabs(v), targetGray(v), catad(v), + saturl(v), + contl(v), Autogray(v), fullimage(v), + ciecam(v), blackEv(v), whiteEv(v), detail(v), + surround(v), sensilog(v), baselog(v), strlog(v), @@ -7141,13 +7177,19 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) explog = v; autocompute = v; sourceGray = v; + sourceabs = v; + targabs = v; targetGray = v; catad = v; + saturl = v; + contl = v; Autogray = v; fullimage = v; + ciecam = v; blackEv = v; whiteEv = v; detail = v; + surround = v; sensilog = v; baselog = v; strlog = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 2a50b2cf1..a66399883 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -832,13 +832,19 @@ public: bool explog; bool autocompute; bool sourceGray; + bool sourceabs; + bool targabs; bool targetGray; bool catad; + bool saturl; + bool contl; bool Autogray; bool fullimage; + bool ciecam; bool blackEv; bool whiteEv; bool detail; + bool surround; bool sensilog; bool baselog; bool strlog;