From 4b2563af6267cf0dac4fab3752ab85915c2efbee Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 10 Nov 2017 08:47:11 +0100 Subject: [PATCH] Add simplified Excluding Spot - fixed some bugs --- rtdata/languages/default | 14 + rtengine/dcrop.cc | 38 +- rtengine/dcrop.h | 1 + rtengine/dirpyr_equalizer.cc | 35 +- rtengine/improccoordinator.cc | 98 ++++- rtengine/improccoordinator.h | 6 + rtengine/improcfun.h | 13 +- rtengine/iplocallab.cc | 715 ++++++++++++++++++++++++++++++++-- rtengine/procevents.h | 3 + rtengine/procparams.cc | 40 ++ rtengine/procparams.h | 3 + rtengine/refreshmap.cc | 5 +- rtengine/simpleprocess.cc | 32 +- rtgui/history.cc | 30 +- rtgui/locallab.cc | 160 ++++++-- rtgui/locallab.h | 13 +- rtgui/paramsedited.cc | 17 + rtgui/paramsedited.h | 3 + 18 files changed, 1104 insertions(+), 122 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 7f3f6ca3f..a927296ef 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -828,6 +828,11 @@ HISTORY_MSG_577;Local - adjblur HISTORY_MSG_578;Local - cut past HISTORY_MSG_579;Local - cbdl chroma HISTORY_MSG_580;Local - Blur method +HISTORY_MSG_581;Local - D method +HISTORY_MSG_582;Local - LD +HISTORY_MSG_584;Local - Spot method +HISTORY_MSG_585;Local - Spot Excluding scope +HISTORY_MSG_586;Local - Spot Excluding struc HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1822,6 +1827,7 @@ TP_LOCALLAB_CURVCURR;Normal TP_LOCALLAB_CURVENH;Super TP_LOCALLAB_CUTPAST;Copy past buffer TP_LOCALLAB_DENOIS;Denoise +TP_LOCALLAB_DSMOV;Local TP_LOCALLAB_DUST;Dust Spot Removal TP_LOCALLAB_LUM;Curves TP_LOCALLAB_CHROMACBDL;Chroma @@ -1829,6 +1835,14 @@ TP_LOCALLAB_CHROMACB_TOOLTIP;Acts as an amplifier-reducer action compare to slid TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To be active, you must check button 'Enable curves' TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) has the same algorithm than slider lightness.\n'Super' the curve L=f(L) has an new improved algorithm, which can leeds in some cases to artifacts. +TP_LOCALLAB_EXCLUF;Excluding +TP_LOCALLAB_SENSIEXCLU;Scope +TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust color to include in exclusion! +TP_LOCALLAB_STRUC;Structure +TP_LOCALLAB_EXCLUTYPE;Spot method +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot use recursive data.\nExcluding spot reinitialize data to origin. +TP_LOCALLAB_EXNORM;Normal spot +TP_LOCALLAB_EXECLU;Excluding spot TP_LOCALLAB_EXPOSE;Exposure TP_LOCALLAB_NOISELUMFINE;Luminance fine TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index b32c24264..0034a3e23 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -51,7 +51,7 @@ namespace rtengine extern const Settings* settings; Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) - : PipetteBuffer (editDataProvider), origCrop (nullptr), laboCrop (nullptr), labnCrop (nullptr), + : PipetteBuffer (editDataProvider), origCrop (nullptr), laboCrop (nullptr), labnCrop (nullptr), reservCrop (nullptr), cropImg (nullptr), cbuf_real (nullptr), cshmap (nullptr), shbuf_real (nullptr), transCrop (nullptr), cieCrop (nullptr), cbuffer (nullptr), shbuffer (nullptr), updating (false), newUpdatePending (false), skip (10), cropx (0), cropy (0), cropw (-1), croph (-1), @@ -804,6 +804,7 @@ void Crop::update (int todo) //if (tutu) { // //I made a little change here. Rather than have luminanceCurve (and others) use in/out lab images, we can do more if we copy right here. labnCrop->CopyFrom (laboCrop); + reservCrop->CopyFrom (laboCrop); //parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve); @@ -1058,6 +1059,15 @@ void Crop::update (int todo) params.locallab.dustMethod = "pas" ; } + if (parent->exclumets[sp] == 0) { + params.locallab.Exclumethod = "norm" ; + } else if (parent->exclumets[sp] == 1) { + params.locallab.Exclumethod = "exc" ; + } + + params.locallab.sensiexclu = parent->sensiexclus[sp]; + params.locallab.struc = parent->strucs[sp]; + std::vector cretie; for (int j = 0; j < parent->sizeretics[sp]; j++) { @@ -1152,7 +1162,7 @@ void Crop::update (int todo) params.locallab.sobelref = parent->sobelrefs[sp]; - parent->ipf.Lab_Local (params.locallab, 1, sp, (float**)shbuffer, labnCrop, labnCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->fw, parent->fh, locutili, skip, locRETgainCurve, locallutili, lllocalcurve2, + parent->ipf.Lab_Local (params.locallab, 1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->fw, parent->fh, locutili, skip, locRETgainCurve, locallutili, lllocalcurve2, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve2.clear(); cclocalcurve2.clear(); @@ -1425,6 +1435,17 @@ void Crop::update (int todo) parent->dustmets[sp] = 2; } + if (parent->exclumets[sp] == 0) { + params.locallab.Exclumethod = "norm" ; + parent->exclumets[sp] = 0; + } else if (parent->exclumets[sp] == 1) { + params.locallab.Exclumethod = "exc" ; + parent->exclumets[sp] = 1; + } + + parent->sensiexclus[sp] = params.locallab.sensiexclu = parent->sensiexclus[0]; + parent->strucs[sp] = params.locallab.struc = parent->strucs[0]; + std::vector ccret; for (int j = 0; j < parent->sizeretics[sp]; j++) { @@ -1526,7 +1547,7 @@ void Crop::update (int todo) params.locallab.chromaref = parent->chromarefs[sp]; params.locallab.lumaref = parent->lumarefs[sp]; params.locallab.sobelref = parent->sobelrefs[sp]; - parent->ipf.Lab_Local (params.locallab, 1, sp, (float**)shbuffer, labnCrop, labnCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->fw, parent->fh, locutili, skip, locRETgainCurve, locallutili, lllocalcurve2, loclhCurve, lochhCurve, + parent->ipf.Lab_Local (params.locallab, 1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->fw, parent->fh, locutili, skip, locRETgainCurve, locallutili, lllocalcurve2, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve2.clear(); @@ -1779,6 +1800,11 @@ void Crop::freeAll () labnCrop = nullptr; } + if (reservCrop ) { + delete reservCrop; + reservCrop = nullptr; + } + /* if (lablocCrop ) { delete lablocCrop; lablocCrop = NULL; @@ -1983,6 +2009,12 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte labnCrop = new LabImage (cropw, croph); + if (reservCrop) { + delete reservCrop; // labnCrop can't be resized + } + + reservCrop = new LabImage (cropw, croph); + /* if (lablocCrop) { delete lablocCrop; // labnCrop can't be resized } diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index 7fc165008..d7f69be23 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -43,6 +43,7 @@ protected: Imagefloat* origCrop; // "one chunk" allocation LabImage* laboCrop; // "one chunk" allocation LabImage* labnCrop; // "one chunk" allocation + LabImage* reservCrop; // "one chunk" allocation Image8* cropImg; // "one chunk" allocation ; displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not float * cbuf_real; // "one chunk" allocation SHMap* cshmap; // per line allocation diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 8cd2a91d3..f46afbdd6 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -312,13 +312,17 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp (float ** src, float ** dst, if (lv >= 1) { if (scalefl[lv] < 1.f) { - if(mult[lv] > 1.f) multi[lv] = (atten123 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% + if (mult[lv] > 1.f) { + multi[lv] = (atten123 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% + } } else { multi[lv] = (float) mult[lv]; } } else { if (scalefl[lv] < 1.f) { - if(mult[lv] > 1.f) multi[lv] = (atten0 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% + if (mult[lv] > 1.f) { + multi[lv] = (atten0 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% + } } else { multi[lv] = (float) mult[lv]; } @@ -358,7 +362,8 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp (float ** src, float ** dst, level ++; } - float **tmpHue, **tmpChr; + float **tmpHue = nullptr; + float **tmpChr = nullptr; // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory float ** buffer = dirpyrlo[lastlevel - 1]; @@ -376,7 +381,7 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp (float ** src, float ** dst, for (int j = 0; j < srcwidth; j++) { dst[i][j] = src[i][j]; loctemp[i][j] = CLIP (buffer[i][j]); // TODO: Really a clip necessary? - // dst[i][j] = CLIP (buffer[i][j]); // TODO: Really a clip necessary? + // dst[i][j] = CLIP (buffer[i][j]); // TODO: Really a clip necessary? } } @@ -488,7 +493,7 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float float ** buffer = dirpyrlo[lastlevel - 1]; for (int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channelcam (dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold , h_p, C_p, skinprot, b_l, t_l, t_r); + idirpyr_eq_channelcam (dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); } idirpyr_eq_channelcam (dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); @@ -744,7 +749,7 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel (float ** data_fine, float ** d } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void ImProcFunctions::idirpyr_eq_channel_loc (float ** data_coarse, float ** data_fine, float ** loctemp, float ** buffer, int width, int height, int level, float mult[5], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r , int choice) +void ImProcFunctions::idirpyr_eq_channel_loc (float ** data_coarse, float ** data_fine, float ** loctemp, float ** buffer, int width, int height, int level, float mult[5], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice) { // const float skinprotneg = -skinprot; // const float factorHard = (1.f - skinprotneg / 100.f); @@ -838,7 +843,7 @@ void ImProcFunctions::idirpyr_eq_channel_loc (float ** data_coarse, float ** dat */ } -void ImProcFunctions::idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[6], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r , int choice) +void ImProcFunctions::idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[6], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice) { const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); @@ -890,8 +895,7 @@ void ImProcFunctions::idirpyr_eq_channel (float ** data_coarse, float ** data_fi float hipass = (data_fine[i][j] - data_coarse[i][j]); buffer[i][j] += irangefn[hipass + 0x10000] * hipass; } - } - else if (skinprot > 0.f) + } else if (skinprot > 0.f) #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -905,8 +909,7 @@ void ImProcFunctions::idirpyr_eq_channel (float ** data_coarse, float ** data_fi Color::SkinSatCbdl ((data_fine[i][j]) / 327.68f, modhue, modchro, skinprot, scale, true, b_l, t_l, t_r); buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ; } - } - else + } else #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -983,8 +986,7 @@ void ImProcFunctions::idirpyr_eq_channelcam (float ** data_coarse, float ** data float hipass = (data_fine[i][j] - data_coarse[i][j]); buffer[i][j] += irangefn[hipass + 0x10000] * hipass ; } - } - else if (skinprot > 0.f) + } else if (skinprot > 0.f) #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -992,11 +994,10 @@ void ImProcFunctions::idirpyr_eq_channelcam (float ** data_coarse, float ** data for (int j = 0; j < width; j++) { float hipass = (data_fine[i][j] - data_coarse[i][j]); float scale = 1.f; - Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j] , l_b_c[i][j], skinprot, scale, true, b_l, t_l, t_r); + Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j], skinprot, scale, true, b_l, t_l, t_r); buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ; } - } - else + } else #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -1006,7 +1007,7 @@ void ImProcFunctions::idirpyr_eq_channelcam (float ** data_coarse, float ** data float scale = 1.f; float correct; correct = irangefn[hipass + 0x10000]; - Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j] , skinprotneg, scale, false, b_l, t_l, t_r); + Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j], skinprotneg, scale, false, b_l, t_l, t_r); if (scale == 1.f) {//image hard buffer[i][j] += (1.f + (correct) * factorHard) * hipass ; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index a6d03a53a..47a1e375c 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -39,7 +39,7 @@ namespace rtengine extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () - : orig_prev (nullptr), oprevi (nullptr), oprevl (nullptr), nprevl (nullptr), previmg (nullptr), workimg (nullptr), + : orig_prev (nullptr), oprevi (nullptr), oprevl (nullptr), nprevl (nullptr), reserv (nullptr), previmg (nullptr), workimg (nullptr), ncie (nullptr), imgsrc (nullptr), shmap (nullptr), lastAwbEqual (0.), lastAwbTempBias (0.0), ipf (¶ms, true), monitorIntent (RI_RELATIVE), softProof (false), gamutCheck (false), scale (10), highDetailPreprocessComputed (false), highDetailRawComputed (false), allocated (false), bwAutoR (-9000.f), bwAutoG (-9000.f), bwAutoB (-9000.f), CAMMean (NAN), coordX (0), coordY (0), localX (0), localY (0), @@ -197,6 +197,9 @@ ImProcCoordinator::ImProcCoordinator () sizeskintonecurves (500, -10000), excurves (25000, -10000), sizeexcurves (500, -10000), + exclumets (500, -1000), + sensiexclus (500, -1000), + strucs (500, -1000), huerefs (500, -100000.f), chromarefs (500, -100000.f), lumarefs (500, -100000.f), @@ -761,6 +764,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) //scale = 1; if (todo & (M_LUMINANCE + M_COLOR) ) { nprevl->CopyFrom (oprevl); + reserv->CopyFrom (oprevl); + int maxspot = settings->nspot + 1; progress ("Applying Color Boost...", 100 * readyphase / numofphases); @@ -845,7 +850,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) }; - int maxdata = 82;//78;//73 for 10011 + int maxdata = 85;// 82 10015//78;//73 for 10011 if (fic0) { //find current version mip @@ -889,7 +894,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) //initilize newues when first utilisation of Locallab. Prepare creation of Mip files for (int sp = 1; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10015;//new value for each change + int t_mipversion = 10016;//new value for each change int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -1003,6 +1008,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_blurMethod = 0; int t_dustMethod = 1; + //10016 + int t_excludemeth = 0; + int t_sensiexclu = 19; + int t_struc = 0; + //all variables except locRETgainCurve 'coomon for all) fic << "Mipversion=" << t_mipversion << '@' << endl; @@ -1092,6 +1102,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fic << "BlurMethod=" << t_blurMethod << '@' << endl; fic << "DustMethod=" << t_dustMethod << '@' << endl; + fic << "ExcludeMethod=" << t_excludemeth << '@' << endl; + fic << "Sensiexclu=" << t_sensiexclu << '@' << endl; + fic << "Struc=" << t_struc << '@' << endl; + fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; fic << "curveLH=" << t_curvlh << '@' << endl; @@ -1335,8 +1349,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) dataspot[77][0] = dustmets[0] = 2; } + if (params.locallab.Exclumethod == "norm") { + dataspot[78][0] = exclumets[0] = 0; + } else if (params.locallab.Exclumethod == "exc") { + dataspot[78][0] = exclumets[0] = 1; + } - + dataspot[79][0] = sensiexclus[0] = params.locallab.sensiexclu; + dataspot[80][0] = strucs[0] = params.locallab.struc; // for all curves work around - I do not know how to do with params curves... //curve Reti local @@ -1615,6 +1635,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) maxind = 77; } + if (versionmip == 10015) { + maxind = 77; + } + while (getline (fich, line)) { spotline = line; std::size_t pos = spotline.find ("="); @@ -1821,6 +1845,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } + if (versionmip <= 10015) {// + for (int sp = 1; sp < maxspot; sp++) { // spots default + dataspot[78][sp] = 0; + dataspot[79][sp] = 19; + dataspot[80][sp] = 0; + + } + } + //here we change the number of spot if (ns < (maxspot - 1)) { @@ -1829,7 +1862,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) for (int sp = ns + 1 ; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10015; + int t_mipversion = 10016; int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -1935,6 +1968,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_blurMethod = 0; int t_dustMethod = 1; + //10016 + int t_excludemeth = 0; + int t_sensiexclu = 19; + int t_struc = 0; + fic << "Mipversion=" << t_mipversion << '@' << endl; fic << "Spot=" << t_sp << '@' << endl; fic << "Circrad=" << t_circrad << '@' << endl; @@ -2019,6 +2057,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fic << "BlurMethod=" << t_blurMethod << '@' << endl; fic << "DustMethod=" << t_dustMethod << '@' << endl; + fic << "ExcludeMethod=" << t_excludemeth << '@' << endl; + fic << "Sensiexclu=" << t_sensiexclu << '@' << endl; + fic << "Struc=" << t_struc << '@' << endl; + fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; fic << "curveLH=" << t_curvlh << '@' << endl; @@ -2349,7 +2391,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if (dataspot[77][sp] == 0) { dustmets[sp] = 0; params.locallab.dustMethod = "cop" ; - } else if (dataspot[76][sp] == 1) { + } else if (dataspot[77][sp] == 1) { dustmets[sp] = 1; params.locallab.dustMethod = "mov" ; } else if (dataspot[77][sp] == 2) { @@ -2357,6 +2399,18 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) params.locallab.dustMethod = "pas" ; } + if (dataspot[78][sp] == 0) { + exclumets[sp] = 0; + params.locallab.Exclumethod = "norm" ; + } else if (dataspot[78][sp] == 1) { + exclumets[sp] = 1; + params.locallab.Exclumethod = "exc" ; + } + + params.locallab.sensiexclu = sensiexclus[sp] = dataspot[79][sp]; + params.locallab.struc = strucs[sp] = dataspot[80][sp]; + + int *s_datc; s_datc = new int[70]; int siz; @@ -2582,7 +2636,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) dataspot[maxdata - 2][sp] = lumarefs[sp] = params.locallab.lumaref; dataspot[maxdata - 1][sp] = sobelrefs[sp] = params.locallab.sobelref; //printf("sp=%i huerefsp=%f\n", sp, huerefs[sp]); - ipf.Lab_Local (params.locallab, 3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, + ipf.Lab_Local (params.locallab, 3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve.clear(); cclocalcurve.clear(); @@ -2883,6 +2937,20 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) dataspot[77][sp] = 2; } + if (dataspot[78][0] == 0) { + params.locallab.Exclumethod = "norm" ; + exclumets[sp] = 0; + dataspot[78][sp] = 0; + } else if (dataspot[78][0] == 1) { + params.locallab.Exclumethod = "exc" ; + exclumets[sp] = 1; + dataspot[78][sp] = 1; + } + + dataspot[79][sp] = sensiexclus[sp] = params.locallab.sensiexclu = dataspot[79][0]; + dataspot[80][sp] = strucs[sp] = params.locallab.struc = dataspot[80][0]; + + int *s_datc; s_datc = new int[70]; int siz; @@ -3106,7 +3174,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) params.locallab.lumaref = lumarefs[sp]; params.locallab.sobelref = sobelrefs[sp]; - ipf.Lab_Local (params.locallab, 3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, + ipf.Lab_Local (params.locallab, 3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve.clear(); cclocalcurve.clear(); @@ -3122,7 +3190,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) for (int spe = 1; spe < maxspot; spe++) { int t_sp = spe; - int t_mipversion = 10015; + int t_mipversion = 10016; int t_circrad = dataspot[2][spe]; int t_locX = dataspot[3][spe]; int t_locY = dataspot[4][spe]; @@ -3206,6 +3274,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_blurMethod = dataspot[76][spe]; int t_dustMethod = dataspot[77][spe]; + int t_excludemeth = dataspot[78][spe]; + int t_sensiexclu = dataspot[79][spe]; + int t_struc = dataspot[80][spe]; + int t_hueref = dataspot[maxdata - 4][spe]; int t_chromaref = dataspot[maxdata - 3][spe]; int t_lumaref = dataspot[maxdata - 2][spe]; @@ -3307,6 +3379,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fou << "BlurMethod=" << t_blurMethod << '@' << endl; fou << "DustMethod=" << t_dustMethod << '@' << endl; + fou << "ExcludeMethod=" << t_excludemeth << '@' << endl; + fou << "Sensiexclu=" << t_sensiexclu << '@' << endl; + fou << "Struc=" << t_struc << '@' << endl; + fou << "hueref=" << t_hueref << '@' << endl; fou << "chromaref=" << t_chromaref << '@' << endl; fou << "lumaref=" << t_lumaref << '@' << endl; @@ -3605,6 +3681,8 @@ void ImProcCoordinator::freeAll () oprevl = nullptr; delete nprevl; nprevl = nullptr; + delete reserv; + reserv = nullptr; if (ncie) { delete ncie; @@ -3672,6 +3750,8 @@ void ImProcCoordinator::setScale (int prevscale) oprevi = orig_prev; oprevl = new LabImage (pW, pH); nprevl = new LabImage (pW, pH); + reserv = new LabImage (pW, pH); + // nprevloc = new LabImage (pW, pH); //ncie is only used in ImProcCoordinator::updatePreviewImage, it will be allocated on first use and deleted if not used anymore previmg = new Image8 (pW, pH); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index b6fc465fc..cb3017528 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -60,6 +60,8 @@ protected: Imagefloat *oprevi; LabImage *oprevl; LabImage *nprevl; + LabImage *reserv; + Image8 *previmg; // displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not Image8 *workimg; // internal image in output color space for analysis CieImage *ncie; @@ -347,6 +349,10 @@ protected: LUTi excurves; LUTi sizeexcurves; + LUTi exclumets; + LUTi sensiexclus; + LUTi strucs; + LUTf huerefs; LUTf chromarefs; LUTf lumarefs; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index efc161894..421ee71ad 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -46,11 +46,11 @@ class ImProcFunctions bool lastcutpast; - int lastcxbuf; - int lastcybuf; - int lastcount; + int lastcxbuf; + int lastcybuf; + int lastcount; LabImage *spotbuffer; - + cmsHTRANSFORM monitorTransform; cmsHTRANSFORM lab2outputTransform; cmsHTRANSFORM output2monitorTransform; @@ -209,7 +209,7 @@ public: double lumimul[3]; ImProcFunctions (const ProcParams* iparams, bool imultiThread = true) - : lastcutpast (false), lastcxbuf (0), lastcybuf (0), lastcount (0), spotbuffer (nullptr) , monitorTransform (nullptr), lab2outputTransform (nullptr), output2monitorTransform (nullptr), params (iparams), scale (1), multiThread (imultiThread), lumimul{} {} + : lastcutpast (false), lastcxbuf (0), lastcybuf (0), lastcount (0), spotbuffer (nullptr), monitorTransform (nullptr), lab2outputTransform (nullptr), output2monitorTransform (nullptr), params (iparams), scale (1), multiThread (imultiThread), lumimul{} {} ~ImProcFunctions (); bool needsLuminanceOnly() { @@ -295,7 +295,7 @@ public: void calc_ref (int call, int sp, float** shbuffer, LabImage* original, LabImage* transformed, int sx, int sy, int cx, int cy, int oW, int oH, int fw, int fh, bool locutili, int sk, const LocretigainCurve & locRETgainCcurve, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, LUTf & sklocalcurve, double &huere, double &chromare, double &lumare, double &sobelref); void copy_ref (int call, int sp, LabImage* spotbuffer, LabImage* original, LabImage* transformed, int sx, int sy, int cx, int cy, int oW, int oH, int fw, int fh, int sk, const struct local_params & lp, double &huerefspot, double &chromarefspot, double &lumarefspot); void paste_ref (int call, int sp, LabImage* spotbuffer, LabImage* original, LabImage* transformed, int sx, int sy, int cx, int cy, int oW, int oH, int fw, int fh, int sk, const struct local_params & lp, double &huerefspot, double &chromarefspot, double &lumarefspot); - void Lab_Local (LocallabParams &loc, int call, int sp, float** shbuffer, LabImage* original, LabImage* transformed, int sx, int sy, int cx, int cy, int oW, int oH, int fw, int fh, bool locutili, int sk, const LocretigainCurve & locRETgainCcurve, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, double &hueref, double &chromaref, double &lumaref, double &sobelref); + void Lab_Local (LocallabParams &loc, int call, int sp, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, int sx, int sy, int cx, int cy, int oW, int oH, int fw, int fh, bool locutili, int sk, const LocretigainCurve & locRETgainCcurve, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, double &hueref, double &chromaref, double &lumaref, double &sobelref); void addGaNoise (LabImage *lab, LabImage *dst, const float mean, const float variance, const int sk); void BlurNoise_Localold (int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); void InverseBlurNoise_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); @@ -310,6 +310,7 @@ public: void vibrancelocal (const local_params& lp, int bfw, int bfh, LabImage* lab, LabImage* dest, bool & localskutili, LUTf & sklocalcurve); void Expose_Local (int sen, int call, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy); void exlabLocal (const local_params& lp, int bfh, int bfw, LabImage* bufexporig, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve); + void Exclude_Local (int sen, int call, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * rsv, int cx, int cy); void DeNoise_Local (int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 2e98f9be1..4ce90c287 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -74,7 +74,7 @@ float calcLocalFactor (const float lox, const float loy, const float lcx, const return 0.5f * (1.f + xcosf (degrad * ap + bp)); //trigo cos transition } - +/* float calcLocalFactorinv (const float lox, const float loy, const float lcx, const float dx, const float lcy, const float dy, const float ach) { //elipse x2/a2 + y2/b2=1 @@ -92,7 +92,7 @@ float calcLocalFactorinv (const float lox, const float loy, const float lcx, con } - +*/ } namespace rtengine @@ -112,7 +112,7 @@ struct local_params { int cir; float thr; int prox; - int chro, cont, sens, sensh, senscb, sensbn, senstm, sensex; + int chro, cont, sens, sensh, senscb, sensbn, senstm, sensex, sensexclu; float ligh; int shamo, shdamp, shiter, senssha, sensv; double shrad; @@ -158,10 +158,13 @@ struct local_params { int hlcomp; int hlcompthr; double expcomp; + int excmet; + int strucc; + }; -static void SobelCannyLuma (LabImage *sobelL, LabImage *deltasobelL, LabImage *luma, int bfw, int bfh) +static void SobelCannyLuma (float **sobelL, float **deltasobelL, float **luma, int bfw, int bfh, float radius) { //base of the process to detect shape in complement of deltaE //use for calcualte Spot reference @@ -203,47 +206,60 @@ static void SobelCannyLuma (LabImage *sobelL, LabImage *deltasobelL, LabImage *l GY[2][1] = -2; GY[2][2] = -1; //inspired from Chen Guanghua Zhang Xiaolong + /* + //Gaussian 1.4 to blur and denoise + for (int i = 2; i < bfh - 2; i++) { + for (int j = 2; j < bfw - 2; j++) { + //Gaussian 1.4 + // 2 4 5 4 2 + // 4 9 12 9 4 + // 5 12 15 12 5 + // 4 9 12 9 4 + // 2 4 5 4 2 + // divi 159 + tmL[i][j] = (15.f * luma->L[i][j] + 12.f * luma->L[i - 1][j] + 12.f * luma->L[i + 1][j] + + 12.f * luma->L[i][j + 1] + 12.f * luma->L[i][j - 1] + 9.f * luma->L[i - 1][j - 1] + + 9.f * luma->L[i - 1][j + 1] + 9.f * luma->L[i + 1][j - 1] + 9.f * luma->L[i + 1][j + 1] + + 5.f * luma->L[i - 2][j] + 5.f * luma->L[i + 2][j] + 5.f * luma->L[i][j - 2] + 5.f * luma->L[i][j + 2] + + 4.f * luma->L[i - 2][j - 1] + 4.f * luma->L[i - 2][j + 1] + 4.f * luma->L[i + 2][j + 1] + 4.f * luma->L[i + 2][j - 1] + + 4.f * luma->L[i - 1][j - 2] + 4.f * luma->L[i - 1][j + 2] + 4.f * luma->L[i + 1][j + 2] + 4.f * luma->L[i + 1][j - 2] + + 2.f * luma->L[i - 2][j - 2] + 2.f * luma->L[i - 2][j + 2] + 2.f * luma->L[i + 2][j - 2] + 2.f * luma->L[i + 2][j + 2] + ) * 0.0062893f; - //Gaussian 1.4 to blur and denoise - for (int i = 2; i < bfh - 2; i++) { - for (int j = 2; j < bfw - 2; j++) { - //Gaussian 1.4 - // 2 4 5 4 2 - // 4 9 12 9 4 - // 5 12 15 12 5 - // 4 9 12 9 4 - // 2 4 5 4 2 - // divi 159 - tmL[i][j] = (15.f * luma->L[i][j] + 12.f * luma->L[i - 1][j] + 12.f * luma->L[i + 1][j] - + 12.f * luma->L[i][j + 1] + 12.f * luma->L[i][j - 1] + 9.f * luma->L[i - 1][j - 1] - + 9.f * luma->L[i - 1][j + 1] + 9.f * luma->L[i + 1][j - 1] + 9.f * luma->L[i + 1][j + 1] - + 5.f * luma->L[i - 2][j] + 5.f * luma->L[i + 2][j] + 5.f * luma->L[i][j - 2] + 5.f * luma->L[i][j + 2] - + 4.f * luma->L[i - 2][j - 1] + 4.f * luma->L[i - 2][j + 1] + 4.f * luma->L[i + 2][j + 1] + 4.f * luma->L[i + 2][j - 1] - + 4.f * luma->L[i - 1][j - 2] + 4.f * luma->L[i - 1][j + 2] + 4.f * luma->L[i + 1][j + 2] + 4.f * luma->L[i + 1][j - 2] - + 2.f * luma->L[i - 2][j - 2] + 2.f * luma->L[i - 2][j + 2] + 2.f * luma->L[i + 2][j - 2] + 2.f * luma->L[i + 2][j + 2] - ) * 0.0062893f; - + } } - } + */ +// gaussianBlur (luma, tmL, bfw, bfh, radius); { for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw ; x++) { - sobelL->L[y][x] = 0.f; - deltasobelL->L[y][x] = 0.f; + sobelL[y][x] = 0.f; + deltasobelL[y][x] = 0.f; + tmL[y][x] = luma[y][x]; } } +//if(radius > 1.f) { + radius /= 2.f; - for (int y = 2; y < bfh - 2 ; y++) { - for (int x = 2; x < bfw - 2 ; x++) { + if (radius < 0.5f) { + radius = 0.5f; + } + + // printf ("raiusssss=%f\n", radius); + gaussianBlur (luma, tmL, bfw, bfh, radius); + +//} + for (int y = 0; y < bfh ; y++) { + for (int x = 0; x < bfw ; x++) { sumXL = 0.f; sumYL = 0.f; - if (y == 2 || y == bfh - 3) { + if (y == 0 || y == bfh - 1) { SUML = 0.f; - } else if (x == 2 || x == bfw - 3) { + } else if (x == 0 || x == bfw - 1) { SUML = 0.f; } else { for (int i = -1; i < 2; i++) { @@ -265,8 +281,8 @@ static void SobelCannyLuma (LabImage *sobelL, LabImage *deltasobelL, LabImage *l SUML = CLIPLOC (SUML); - sobelL->L[y][x] = SUML; - deltasobelL->L[y][x] = SUML - tmL[y][x]; + sobelL[y][x] = SUML; + deltasobelL[y][x] = SUML - tmL[y][x]; } } @@ -332,6 +348,12 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str lp.blurmet = 2; } + if (locallab.Exclumethod == "norm") { + lp.excmet = 0; + } else if (locallab.Exclumethod == "exc") { + lp.excmet = 1; + } + float local_noiself = locallab.noiselumf; float local_noiselc = locallab.noiselumc; float local_noisecf = locallab.noisechrof; @@ -349,6 +371,8 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str int local_sensi = locallab.sensi; int local_sensibn = locallab.sensibn; int local_sensitm = locallab.sensitm; + int local_sensiexclu = locallab.sensiexclu; + int local_struc = locallab.struc; int local_sensih = locallab.sensih; int local_sensicb = locallab.sensicb; int local_contrast = locallab.contrast; @@ -396,6 +420,7 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str lp.rad = radius; lp.stren = strength; lp.sensbn = local_sensibn; + lp.sensexclu = local_sensiexclu; lp.inv = inverse; lp.curvact = curvacti; lp.invrad = inverserad; @@ -451,7 +476,7 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str lp.hlcompthr = locallab.hlcomprthresh; lp.expcomp = locallab.expcomp / 100.; lp.sensex = local_sensiex; - + lp.strucc = local_struc; } @@ -509,6 +534,7 @@ static void calcTransition (const float lox, const float loy, const float ach, c } } +/* static void calcTransitioninv (const float lox, const float loy, const float ach, const local_params& lp, int &zone, float &localFactor) { // returns the zone (0 = outside selection, 1 = zone between outside and inside selection, 2 = inside selection with transition) @@ -566,7 +592,7 @@ static void calcTransitioninv (const float lox, const float loy, const float ach } } - +*/ void ImProcFunctions::strcurv_data (std::string retistr, int *s_datc, int &siz) { @@ -4078,6 +4104,418 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa } } + +void ImProcFunctions::Exclude_Local (int sen, int call, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * rsv, int cx, int cy) +{ + +//local exposure + BENCHFUN { + const float ach = (float)lp.trans / 100.f; + float varsens = lp.sensexclu; + + if (sen == 1) + { + varsens = lp.sensexclu; + } + + if (sen == 2) + { + varsens = lp.sensv;//?? or other + } + + //chroma + constexpr float amplchsens = 2.5f; + constexpr float achsens = (amplchsens - 1.f) / (100.f - 20.f); //20. default locallab.sensih + constexpr float bchsens = 1.f - 20.f * achsens; + const float multchro = varsens * achsens + bchsens; + + //luma + + //skin + constexpr float amplchsensskin = 1.6f; + constexpr float achsensskin = (amplchsensskin - 1.f) / (100.f - 20.f); //20. default locallab.sensih + constexpr float bchsensskin = 1.f - 20.f * achsensskin; + const float multchroskin = varsens * achsensskin + bchsensskin; + + //transition = difficult to avoid artifact with scope on flat area (sky...) + + constexpr float delhu = 0.05f; //between 0.05 and 0.2 + + const float apl = (-1.f) / delhu; + const float bpl = - apl * hueplus; + const float amo = 1.f / delhu; + const float bmo = - amo * huemoins; + + + const float pb = 4.f; + const float pa = (1.f - pb) / 40.f; + + const float ahu = 1.f / (2.8f * varsens - 280.f); + const float bhu = 1.f - ahu * 2.8f * varsens; + + const float alum = 1.f / (varsens - 100.f); + const float blum = 1.f - alum * varsens; + //float maxc = -100000.f; + //float minc = 100000.f; + +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { +#ifdef __SSE2__ + float atan2Buffer[transformed->W] ALIGNED16; + float sqrtBuffer[transformed->W] ALIGNED16; + vfloat c327d68v = F2V (327.68f); +#endif + +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H; y++) + { + + const int loy = cy + y; + const bool isZone0 = loy > lp.yc + lp.ly || loy < lp.yc - lp.lyT; // whole line is zone 0 => we can skip a lot of processing + + if (isZone0) { // outside selection and outside transition zone => no effect, keep original values + for (int x = 0; x < transformed->W; x++) { + transformed->L[y][x] = original->L[y][x]; + } + + continue; + } + +#ifdef __SSE2__ + int i = 0; + + for (; i < transformed->W - 3; i += 4) { + vfloat av = LVFU (original->a[y][i]); + vfloat bv = LVFU (original->b[y][i]); + STVF (atan2Buffer[i], xatan2f (bv, av)); + STVF (sqrtBuffer[i], _mm_sqrt_ps (SQRV (bv) + SQRV (av)) / c327d68v); + } + + for (; i < transformed->W; i++) { + atan2Buffer[i] = xatan2f (original->b[y][i], original->a[y][i]); + sqrtBuffer[i] = sqrt (SQR (original->b[y][i]) + SQR (original->a[y][i])) / 327.68f; + } + +#endif + + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int begx = int (lp.xc - lp.lxL); + int begy = int (lp.yc - lp.lyT); + + int zone = 0; + float localFactor = 1.f; + calcTransition (lox, loy, ach, lp, zone, localFactor); + + if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values + transformed->L[y][x] = original->L[y][x]; + continue; + } + +#ifdef __SSE2__ + float rhue = atan2Buffer[x]; + float rchro = sqrtBuffer[x]; +#else + float rhue = xatan2f (original->b[y][x], original->a[y][x]); + float rchro = sqrt (SQR (original->b[y][x]) + SQR (original->a[y][x])) / 327.68f; +#endif + float rL = original->L[y][x] / 327.68f; + + float cli = 1.f; + float clc = 1.f; + + // if (lp.curvact == true) { + cli = (buflight[loy - begy][lox - begx]); + clc = (bufchro[loy - begy][lox - begx]); + //printf("cl=%f",clc); + + // } else { + // cli = lp.str; + // clc = params->locallab.chrrt; + // } + + float aplus = (1.f - cli) / delhu; + float bplus = 1.f - aplus * hueplus; + float amoins = (cli - 1.f) / delhu; + float bmoins = 1.f - amoins * huemoins; + + float aplusch = (1.f - clc) / delhu; + float bplusch = 1.f - aplusch * hueplus; + float amoinsch = (clc - 1.f) / delhu; + float bmoinsch = 1.f - amoinsch * huemoins; + + float realstr = 1.f; + float realstrch = 1.f; + //prepare shape detection + float deltachro = fabs (rchro - chromaref); + float deltahue = fabs (rhue - hueref); + + if (deltahue > rtengine::RT_PI) { + deltahue = - (deltahue - 2.f * rtengine::RT_PI); + } + + float deltaE = 20.f * deltahue + deltachro; //between 0 and 280 + float deltaL = fabs (lumaref - rL); //between 0 and 100 + + float kch = 1.f; + float khu = 0.f; + float fach = 1.f; + float falu = 1.f; + + if (deltachro < 160.f * SQR (varsens / 100.f)) { + kch = 1.f; + } else { + float ck = 160.f * SQR (varsens / 100.f); + float ak = 1.f / (ck - 160.f); + float bk = -160.f * ak; + kch = ak * deltachro + bk; + } + + if (varsens < 40.f ) { + kch = pow (kch, pa * varsens + pb); //increase under 40 + } + + bool kzon = false; + + //transition = difficult to avoid artifact with scope on flat area (sky...) + //hue detection + if ((hueref + dhue) < rtengine::RT_PI && rhue < hueplus && rhue > huemoins) { //transition are good + if (rhue >= hueplus - delhu) { + realstr = aplus * rhue + bplus; + realstrch = aplusch * rhue + bplusch; + khu = apl * rhue + bpl; + + } else if (rhue < huemoins + delhu) { + realstr = amoins * rhue + bmoins; + realstrch = amoinsch * rhue + bmoinsch; + khu = amo * rhue + bmo; + + } else { + realstr = cli; + khu = 1.f; + realstrch = clc; + + } + + kzon = true; + } else if ((hueref + dhue) >= rtengine::RT_PI && (rhue > huemoins || rhue < hueplus )) { + if (rhue >= hueplus - delhu && rhue < hueplus) { + realstr = aplus * rhue + bplus; + realstrch = aplusch * rhue + bplusch; + khu = apl * rhue + bpl; + + } else if (rhue >= huemoins && rhue < huemoins + delhu) { + realstr = amoins * rhue + bmoins; + realstrch = amoinsch * rhue + bmoinsch; + khu = amo * rhue + bmo; + + } else { + realstr = cli; + khu = 1.f; + realstrch = clc; + + } + + kzon = true; + } + + if ((hueref - dhue) > -rtengine::RT_PI && rhue < hueplus && rhue > huemoins) { + if (rhue >= hueplus - delhu && rhue < hueplus) { + realstr = aplus * rhue + bplus; + realstrch = aplusch * rhue + bplusch; + khu = apl * rhue + bpl; + + } else if (rhue >= huemoins && rhue < huemoins + delhu) { + realstr = amoins * rhue + bmoins; + realstrch = amoinsch * rhue + bmoinsch; + khu = amo * rhue + bmo; + + } else { + realstr = cli; + khu = 1.f; + realstrch = clc; + + } + + kzon = true; + } else if ((hueref - dhue) <= -rtengine::RT_PI && (rhue > huemoins || rhue < hueplus )) { + if (rhue >= hueplus - delhu && rhue < hueplus) { + realstr = aplus * rhue + bplus; + realstrch = aplusch * rhue + bplusch; + khu = apl * rhue + bpl; + + } else if (rhue >= huemoins && rhue < huemoins + delhu) { + realstr = amoins * rhue + bmoins; + realstrch = amoinsch * rhue + bmoinsch; + khu = amo * rhue + bmo; + + } else { + realstr = cli; + khu = 1.f; + realstrch = clc; + + } + + kzon = true; + } + + /* + //printf("re=%f", realstrch); + if (realstrch > maxc) { + maxc = realstrch; + } + + if (realstrch < minc) { + minc = realstrch; + } + */ + //shape detection for hue chroma and luma + if (varsens <= 20.f) { //to try... + + if (deltaE < 2.8f * varsens) { + fach = khu; + } else { + fach = khu * (ahu * deltaE + bhu); + } + + float kcr = 10.f; + + if (rchro < kcr) { + fach *= (1.f / (kcr * kcr)) * rchro * rchro; + } + + if (lp.qualmet >= 1) { + } else { + fach = 1.f; + } + + if (deltaL < varsens) { + falu = 1.f; + } else { + falu = alum * deltaL + blum; + } + + } + + // float kdiff = 0.f; + // I add these functions...perhaps not good + if (kzon) { + if (varsens < 60.f) { //arbitrary value + if (hueref < -1.1f && hueref > -2.8f) { // detect blue sky + if (chromaref > 0.f && chromaref < 35.f * multchro) { // detect blue sky + if ( (rhue > -2.79f && rhue < -1.11f) && (rchro < 35.f * multchro)) { + realstr *= 0.9f; + } else { + realstr = 1.f; + } + } + } else { + realstr = cli; + } + + if (varsens < 50.f) { //&& lp.chro > 0.f + if (hueref > -0.1f && hueref < 1.6f) { // detect skin + if (chromaref > 0.f && chromaref < 55.f * multchroskin) { // detect skin + if ( (rhue > -0.09f && rhue < 1.59f) && (rchro < 55.f * multchroskin)) { + realstr *= 0.7f; + } else { + realstr = 1.f; + } + } + } else { + realstr = cli; + } + } + } + + } + + float kcr = 100.f * lp.thr; + float falL = 1.f; + + if (rchro < kcr && chromaref > kcr) { // reduce artifacts in grey tones near hue spot and improve algorithm + falL *= pow (rchro / kcr, lp.iterat / 10.f); + } + + // int zone; + // float localFactor; + // calcTransition (lox, loy, ach, lp, zone, localFactor); + + if (rL > 0.1f) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9 + switch (zone) { + case 0: { // outside selection and outside transition zone => no effect, keep original values + transformed->L[y][x] = original->L[y][x]; + transformed->a[y][x] = original->a[y][x]; + transformed->b[y][x] = original->b[y][x]; + + break; + } + + case 1: { // inside transition zone + float factorx = localFactor; + + float difL; + difL = rsv->L[loy - begy][lox - begx] - original->L[y][x]; + difL *= factorx * (100.f + realstr * falL) / 100.f; + difL *= kch * fach; + + transformed->L[y][x] = original->L[y][x] + difL; + float difa, difb; + + difa = rsv->a[loy - begy][lox - begx] - original->a[y][x]; + difb = rsv->b[loy - begy][lox - begx] - original->b[y][x]; + difa *= factorx * (100.f + realstrch * falu * falL) / 100.f; + difb *= factorx * (100.f + realstrch * falu * falL) / 100.f; + difa *= kch * fach; + difb *= kch * fach; + transformed->a[y][x] = CLIPC (original->a[y][x] + difa); + transformed->b[y][x] = CLIPC (original->b[y][x] + difb); + + + break; + + } + + case 2: { // inside selection => full effect, no transition + float difL; + + difL = rsv->L[loy - begy][lox - begx] - original->L[y][x]; + difL *= (100.f + realstr * falL) / 100.f; + difL *= kch * fach; + transformed->L[y][x] = original->L[y][x] + difL; + float difa, difb; + + difa = rsv->a[loy - begy][lox - begx] - original->a[y][x]; + difb = rsv->b[loy - begy][lox - begx] - original->b[y][x]; + difa *= (100.f + realstrch * falu * falL) / 100.f; + difb *= (100.f + realstrch * falu * falL) / 100.f; + difa *= kch * fach; + difb *= kch * fach; + + transformed->a[y][x] = CLIPC (original->a[y][x] + difa); + transformed->b[y][x] = CLIPC (original->b[y][x] + difb); + + } + } + + } + } + } + + } + + } +} + + + + + void ImProcFunctions::Expose_Local (int sen, int call, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy) { @@ -4112,7 +4550,7 @@ void ImProcFunctions::Expose_Local (int sen, int call, float **buflight, float * //transition = difficult to avoid artifact with scope on flat area (sky...) - constexpr float delhu = 0.1f; //between 0.05 and 0.2 + constexpr float delhu = 0.05f; //between 0.05 and 0.2 const float apl = (-1.f) / delhu; const float bpl = - apl * hueplus; @@ -5361,7 +5799,7 @@ void ImProcFunctions::calc_ref (int call, int sp, float** shbuffer, LabImage * o } //ref for sobel - bool toto = false; + bool toto = true; if (toto) { for (int y = max (cy, (int) (lp.yc - spotSise2)); y < min (transformed->H + cy, (int) (lp.yc + spotSise2 + 1)); y++) { @@ -5377,13 +5815,15 @@ void ImProcFunctions::calc_ref (int call, int sp, float** shbuffer, LabImage * o } } + const float radius = 3.f / (sk * 1.4f); //0 to 70 ==> see skip + SobelCannyLuma (sobelL->L, deltasobelL->L, origsob->L, spotSi, spotSi, radius); - SobelCannyLuma (sobelL, deltasobelL, origsob, spotSi, spotSi ); + // SobelCannyLuma (sobelL, deltasobelL, origsob, spotSi, spotSi, radius ); int nbs = 0; for (int y = 0; y < spotSi ; y ++) for (int x = 0; x < spotSi ; x ++) { - avesobel += deltasobelL->L[y][x]; + avesobel += sobelL->L[y][x]; nbs++; } @@ -5500,7 +5940,7 @@ void ImProcFunctions::paste_ref (int call, int sp, LabImage * spotbuffer, LabIma } } -void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** shbuffer, LabImage * original, LabImage * transformed, int sx, int sy, int cx, int cy, int oW, int oH, int fw, int fh, bool locutili, int sk, +void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, int sx, int sy, int cx, int cy, int oW, int oH, int fw, int fh, bool locutili, int sk, const LocretigainCurve & locRETgainCcurve, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, double & hueref, double & chromaref, double & lumaref, double & sobelref) { @@ -5521,7 +5961,8 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** calcLocalParams (oW, oH, params->locallab, lp); const float radius = lp.rad / (sk * 1.4f); //0 to 70 ==> see skip - + // float radiussob = 3.f / (sk * 1.4f); //0 to 70 ==> see skip + //printf("radiussob=%f rad=%f sk=%i\n", radiussob, lp.rad, sk); double ave = 0.; int n = 0; float av = 0; @@ -5536,6 +5977,13 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** noiscfactiv = false; } + /* int HH=transformed->H; + int WW=transformed->W; + int OH=original->H; + int OW=original->W; + + printf("TH=%f OR=%f\n", transformed->L[HH/3][WW/3], original->L[HH/3][WW/3]); + */ if (lp.inv || lp.invret) { //exterior || lp.curvact ave = 0.f; n = 0; @@ -5581,7 +6029,7 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** float dhuev = ared * lp.sensv + bred; //delta hue vibr - float dhueex = ared * lp.sensex + bred; //delta hue vibr + float dhueex = ared * lp.sensex + bred; //delta hue exp float dhueret = ared * lp.sensh + bred; //delta hue retinex @@ -5593,6 +6041,8 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** float dhuecb = ared * lp.senscb + bred; //delta hue cbdl + float dhueexclu = ared * lp.sensexclu + bred; //delta hue exclude + constexpr float maxh = 3.5f; // 3.5 amplification contrast above mean constexpr float maxl = 2.5f; // 3 reductio contrast under mean @@ -5606,6 +6056,176 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** lco.dy = 1.f - 1.f / multh; + if (lp.excmet == 1 && call <= 3) { + LabImage *deltasobelL = nullptr; + LabImage *tmpsob = nullptr; + LabImage *bufsob = nullptr; + LabImage *bufreserv = nullptr; + LabImage *bufexclu = nullptr; + float *origBuffer = nullptr; + + int bfh = int (lp.ly + lp.lyT) + del; //bfw bfh real size of square zone + int bfw = int (lp.lx + lp.lxL) + del; + int begy = lp.yc - lp.lyT; + int begx = lp.xc - lp.lxL; + int yEn = lp.yc + lp.ly; + int xEn = lp.xc + lp.lx; + bufsob = new LabImage (bfw, bfh); + bufreserv = new LabImage (bfw, bfh); + float **buflight = nullptr; + float **bufchro = nullptr; + float *orig[bfh] ALIGNED16; + origBuffer = new float[bfh * bfw]; + + for (int i = 0; i < bfh; i++) { + orig[i] = &origBuffer[i * bfw]; + } + + bufexclu = new LabImage (bfw, bfh); + buflight = new float*[bfh]; + + for (int i = 0; i < bfh; i++) { + buflight[i] = new float[bfw]; + } + + bufchro = new float*[bfh];//for chroma reti + + for (int i = 0; i < bfh; i++) { + bufchro[i] = new float[bfw]; + } + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) //fill with 0 + for (int jr = 0; jr < bfw; jr++) { + bufsob->L[ir][jr] = 0.f; + bufexclu->L[ir][jr] = 0.f; + bufexclu->a[ir][jr] = 0.f; + bufexclu->b[ir][jr] = 0.f; + buflight[ir][jr] = 0.f; + bufchro[ir][jr] = 0.f; + bufreserv->L[ir][jr] = 0.f; + bufreserv->a[ir][jr] = 0.f; + bufreserv->b[ir][jr] = 0.f; + + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufsob->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas + + } + } + + tmpsob = new LabImage (bfw, bfh); + deltasobelL = new LabImage (bfw, bfh); + // SobelCannyLuma (tmpsob->L, deltasobelL->L, bufsob->L, bfw, bfh, radiussob); + //todo use of tmpsob and deltasobelL - shape detection + + //then restore non modified area +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufreserv->L[loy - begy][lox - begx] = reserved->L[y][x]; + bufreserv->a[loy - begy][lox - begx] = reserved->a[y][x]; + bufreserv->b[loy - begy][lox - begx] = reserved->b[y][x]; + bufexclu->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas + bufexclu->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas + bufexclu->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas + + } + } + + //TODO then use instead of others modifications Color and Light, Blur, etc. + float hueplus = hueref + dhueexclu; + float huemoins = hueref - dhueexclu; + + if (hueplus > rtengine::RT_PI) { + hueplus = hueref + dhueexclu - 2.f * rtengine::RT_PI; + } + + if (huemoins < -rtengine::RT_PI) { + huemoins = hueref - dhueexclu + 2.f * rtengine::RT_PI; + } + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + float rL; + rL = CLIPRET ((bufreserv->L[ir][jr] - bufexclu->L[ir][jr]) / 328.f); + buflight[ir][jr] = rL; + + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int ir = 0; ir < bfh; ir += 1) + for (int jr = 0; jr < bfw; jr += 1) { + orig[ir][jr] = sqrt (SQR (bufexclu->a[ir][jr]) + SQR (bufexclu->b[ir][jr])); + } + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + float rch; + rch = CLIPRET ((sqrt ((SQR (bufreserv->a[ir][jr]) + SQR (bufreserv->b[ir][jr]))) - orig[ir][jr]) / 328.f); + bufchro[ir][jr] = rch; + } + + Exclude_Local (1, call, buflight, bufchro, hueplus, huemoins, hueref, dhueex, chromaref, lumaref, lp, original, transformed, bufreserv, cx, cy); + + + delete deltasobelL; + delete tmpsob; + + for (int i = 0; i < bfh; i++) { + delete [] bufchro[i]; + } + + delete [] bufchro; + + for (int i = 0; i < bfh; i++) { + delete [] buflight[i]; + } + + delete [] buflight; + + delete bufexclu; + delete [] origBuffer; + + + + delete bufreserv; + delete bufsob; + + } + //Blur and noise if (((radius >= 1.5 * GAUSS_SKIP && lp.rad > 1.) || lp.stren > 0.1) && lp.blurena) { // radius < GAUSS_SKIP means no gauss, just copy of original image @@ -5615,6 +6235,7 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** float **buflight = nullptr; float **bufchro = nullptr; float *origBuffer = nullptr; + // LabImage *deltasobelL = nullptr; int GW = transformed->W; int GH = transformed->H; @@ -5681,6 +6302,11 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** tmp1 = new LabImage (bfw, bfh); + + // deltasobelL = new LabImage (bfw, bfh); + + + if (lp.blurmet == 2) { tmp2 = new LabImage (transformed->W, transformed->H); #ifdef _OPENMP @@ -5696,6 +6322,9 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** } + + // SobelCannyLuma (tmp1->L, deltasobelL->L, bufgb->L, bfw, bfh, radiussob); + #ifdef _OPENMP #pragma omp parallel #endif @@ -5703,7 +6332,6 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** gaussianBlur (bufgb->L, tmp1->L, bfw, bfh, radius); gaussianBlur (bufgb->a, tmp1->a, bfw, bfh, radius); gaussianBlur (bufgb->b, tmp1->b, bfw, bfh, radius); - } } else { @@ -5768,7 +6396,7 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float rch; - rch = CLIPRET ((sqrt ((SQR (tmp1->a[ir][jr]) + SQR (tmp1->a[ir][jr]))) - orig[ir][jr]) / 328.f); + rch = CLIPRET ((sqrt ((SQR (tmp1->a[ir][jr]) + SQR (tmp1->b[ir][jr]))) - orig[ir][jr]) / 328.f); bufchro[ir][jr] = rch; } @@ -5802,6 +6430,7 @@ void ImProcFunctions::Lab_Local (LocallabParams &loc, int call, int sp, float** } delete tmp1; +// delete deltasobelL; if (lp.blurmet == 2) { delete tmp2; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index bdf58f3f2..4ffd00cb7 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -610,6 +610,9 @@ enum ProcEvent { EvlocallabdustMethod = 580, Evlocallablastdust = 581, Evlocallabsobelref = 582, + Evlocallabexclumethod = 583, + Evlocallabsensiexclu = 584, + Evlocallabstruc = 585, NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 7d5f37183..c76a881cc 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1025,6 +1025,8 @@ void LocallabParams::setDefaults() sensih = 19; retrab = 500; sensicb = 19; + sensiexclu = 19; + struc = 0; sensibn = 40; sensitm = 19; sensisha = 19; @@ -1032,6 +1034,7 @@ void LocallabParams::setDefaults() chrrt = 0; avoid = false; Smethod = "IND"; + Exclumethod = "norm"; retinexMethod = "high"; blurMethod = "norm"; dustMethod = "mov"; @@ -3006,6 +3009,10 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_string ("Locallab", "Smethod", locallab.Smethod); } + if (!pedited || pedited->locallab.Exclumethod) { + keyFile.set_string ("Locallab", "Exclumethod", locallab.Exclumethod); + } + if (!pedited || pedited->locallab.retinexMethod) { keyFile.set_string ("Locallab", "retinexMethod", locallab.retinexMethod); } @@ -3204,6 +3211,13 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_integer ("Locallab", "Retrab", locallab.retrab); } + if (!pedited || pedited->locallab.sensiexclu) { + keyFile.set_integer ("Locallab", "Sensiexclu", locallab.sensiexclu); + } + + if (!pedited || pedited->locallab.struc) { + keyFile.set_integer ("Locallab", "Struc", locallab.struc); + } if (!pedited || pedited->locallab.sensicb) { keyFile.set_integer ("Locallab", "Sensicb", locallab.sensicb); @@ -4867,6 +4881,14 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Locallab", "Exclumethod")) { + locallab.Exclumethod = keyFile.get_string ("Locallab", "Exclumethod"); + + if (pedited) { + pedited->locallab.Exclumethod = true; + } + } + if (keyFile.has_key ("Locallab", "retinexMethod")) { locallab.retinexMethod = keyFile.get_string ("Locallab", "retinexMethod"); @@ -5167,6 +5189,21 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) //RAS + if (keyFile.has_key ("Locallab", "Sensiexclu")) { + locallab.sensiexclu = keyFile.get_integer ("Locallab", "Sensiexclu"); + + if (pedited) { + pedited->locallab.sensiexclu = true; + } + } + + if (keyFile.has_key ("Locallab", "Struc")) { + locallab.struc = keyFile.get_integer ("Locallab", "Struc"); + + if (pedited) { + pedited->locallab.struc = true; + } + } if (keyFile.has_key ("Locallab", "Sensicb")) { @@ -10020,6 +10057,7 @@ bool ProcParams::operator== (const ProcParams& other) && locallab.inverssha == other.locallab.inverssha && locallab.degree == other.locallab.degree && locallab.Smethod == other.locallab.Smethod + && locallab.Exclumethod == other.locallab.Exclumethod && locallab.retinexMethod == other.locallab.retinexMethod && locallab.blurMethod == other.locallab.blurMethod && locallab.dustMethod == other.locallab.dustMethod @@ -10069,6 +10107,8 @@ bool ProcParams::operator== (const ProcParams& other) && locallab.sensih == other.locallab.sensih && locallab.retrab == other.locallab.retrab && locallab.sensicb == other.locallab.sensicb + && locallab.sensiexclu == other.locallab.sensiexclu + && locallab.struc == other.locallab.struc && locallab.sensibn == other.locallab.sensibn && locallab.sensisha == other.locallab.sensisha && locallab.radius == other.locallab.radius diff --git a/rtengine/procparams.h b/rtengine/procparams.h index c42fe7f0a..c925c0211 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -984,6 +984,8 @@ public: int sensih; int retrab; int sensicb; + int sensiexclu; + int struc; int sensibn; int sensisha; int sensitm; @@ -997,6 +999,7 @@ public: int transit; bool avoid; Glib::ustring Smethod; + Glib::ustring Exclumethod; Glib::ustring retinexMethod; Glib::ustring blurMethod; Glib::ustring dustMethod; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 18137687b..cea4accee 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -609,7 +609,10 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvlocallabblurMethod LUMINANCECURVE, //EvlocallabdustMethod LUMINANCECURVE, //Evlocallablastdust - LUMINANCECURVE // Evlocallabsobelref + LUMINANCECURVE, // Evlocallabsobelref + LUMINANCECURVE, // Evlocallabexclumethod + LUMINANCECURVE, // Evlocallabsensiexclu + LUMINANCECURVE // Evlocallabstruc }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index c043d6d8c..660c07f7c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -911,6 +911,7 @@ private: } labView = new LabImage (fw, fh); + reservView = new LabImage (fw, fh); if (params.blackwhite.enabled) { CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); @@ -1025,6 +1026,7 @@ private: bool locutili = false; // bool locallutili = false; // bool localcutili = false; + reservView->CopyFrom (labView); if (params.locallab.enabled) { MyTime t1, t2; @@ -1102,7 +1104,7 @@ private: } ifstream fich (datalab, ios::in); - int maxdata = 82;//78;//73 10011 + int maxdata = 85; //82;//78;//73 10011 if (fich && versionmip != 0) { std::string inser; @@ -1327,6 +1329,16 @@ private: dataspots[77][0] = 2; } + + if (params.locallab.Exclumethod == "norm") { + dataspots[78][0] = 0; + } else if (params.locallab.Exclumethod == "exc") { + dataspots[78][0] = 1; + } + + dataspots[79][0] = params.locallab.sensiexclu; + dataspots[80][0] = params.locallab.struc; + dataspots[maxdata - 4][0] = 100.f * params.locallab.hueref; dataspots[maxdata - 3][0] = params.locallab.chromaref; dataspots[maxdata - 2][0] = params.locallab.lumaref; @@ -1785,6 +1797,16 @@ private: params.locallab.dustMethod = "pas" ; } + + if (dataspots[78][sp] == 0) { + params.locallab.Exclumethod = "norm" ; + } else if (dataspots[78][sp] == 1) { + params.locallab.Exclumethod = "exc" ; + } + + params.locallab.sensiexclu = dataspots[79][sp]; + params.locallab.struc = dataspots[80][sp]; + params.locallab.hueref = ((float) dataspots[maxdata - 4][sp]) / 100.f; params.locallab.chromaref = dataspots[maxdata - 3][sp]; params.locallab.lumaref = dataspots[maxdata - 2][sp]; @@ -1974,7 +1996,7 @@ private: params.locallab.lumaref = lumare; params.locallab.sobelref = sobelre; - ipf.Lab_Local (params.locallab, 2, sp, (float**)shbuffer, labView, labView, 0, 0, 0, 0, fw, fh, fw, fh, locutili, 1, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, + ipf.Lab_Local (params.locallab, 2, sp, (float**)shbuffer, labView, labView, reservView, 0, 0, 0, 0, fw, fh, fw, fh, locutili, 1, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve.clear(); cclocalcurve.clear(); @@ -2021,6 +2043,9 @@ private: } } + + delete reservView; + reservView = nullptr; ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); @@ -2278,6 +2303,8 @@ private: delete labView; labView = nullptr; + // delete reservView; + // reservView = nullptr; if (bwonly) { //force BW r=g=b @@ -2551,6 +2578,7 @@ private: ColorTemp currWB; Imagefloat *baseImg; LabImage* labView; + LabImage* reservView; LUTu hist16; diff --git a/rtgui/history.cc b/rtgui/history.cc index b1c2b8369..95b1c9f4f 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -29,12 +29,12 @@ History::History (bool bookmarkSupport) : historyVPaned (nullptr), blistener (nu { blistenerLock = false; // sets default that the Before preview will not be locked -/* - // fill history event message array - for (int i = 0; i < NUMOFEVENTS; i++) { - eventDescrArray[i] = M (Glib::ustring::compose ("HISTORY_MSG_%1", i + 1)); - } -*/ + /* + // fill history event message array + for (int i = 0; i < NUMOFEVENTS; i++) { + eventDescrArray[i] = M (Glib::ustring::compose ("HISTORY_MSG_%1", i + 1)); + } + */ // History List // ~~~~~~~~~~~~ Gtk::ScrolledWindow* hscrollw = Gtk::manage (new Gtk::ScrolledWindow ()); @@ -225,7 +225,7 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring { // to prevent recursion, we filter out the events triggered by the history and events that should not be registered - if (ev == EvHistoryBrowsed || ev == EvMonitorTransform) { + if (ev == EvHistoryBrowsed || ev == EvMonitorTransform || descr == "") { return; } @@ -237,7 +237,7 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring } // construct formatted list content - Glib::ustring text = M("HISTORY_MSG_" + std::to_string(ev + 1)); + Glib::ustring text = M ("HISTORY_MSG_" + std::to_string (ev + 1)); Glib::RefPtr selection = hTreeView->get_selection(); Gtk::TreeModel::iterator iter = selection->get_selected(); @@ -261,9 +261,9 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring // if there is no last item or its chev!=ev, create a new one if (size == 0 || !row || row[historyColumns.chev] != ev || ev == EvProfileChanged) { - // Gtk::TreeModel::Row newrow = * (historyModel->append()); - // newrow[historyColumns.realText] = eventDescrArray[ev]; - Gtk::TreeModel::Row newrow = *(historyModel->append()); +// Gtk::TreeModel::Row newrow = * (historyModel->append()); +// newrow[historyColumns.realText] = eventDescrArray[ev]; + Gtk::TreeModel::Row newrow = * (historyModel->append()); newrow[historyColumns.text] = text; newrow[historyColumns.value] = g_markup_escape_text (descr.c_str(), -1); newrow[historyColumns.chev] = ev; @@ -433,8 +433,8 @@ bool History::on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib: // iter->get_value (1, param); // iter->get_value (2, val); Glib::ustring text, val; - iter->get_value(0, text); - iter->get_value(1, val); + iter->get_value (0, text); + iter->get_value (1, val); /* * @@ -453,8 +453,8 @@ bool History::on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib: tooltip->set_custom(*hbox); */ - // tooltip->set_text (param + " : " + val); - tooltip->set_text(text + " : " + val); +// tooltip->set_text (param + " : " + val); + tooltip->set_text (text + " : " + val); displayTooltip = true; } } diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 0db1d3172..cc32328e3 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -3,6 +3,7 @@ * * Copyright (c) 2004-2010 Gabor Horvath * + * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -65,6 +66,8 @@ Locallab::Locallab (): centerX (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CENTER_X"), -1000, 1000, 1, 0))), centerY (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CENTER_Y"), -1000, 1000, 1, 0))), circrad (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CIRCRADIUS"), 2, 150, 1, 18))), + sensiexclu (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_SENSIEXCLU"), 0, 100, 1, 19))), + struc (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_STRUC"), 0, 100, 1, 0))), thres (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_THRES"), 1, 35, 1, 18))), proxi (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_PROXI"), 0, 60, 1, 0))), lightness (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_LIGHTNESS"), -100, 100, 1, 0))), @@ -114,12 +117,15 @@ Locallab::Locallab (): adjblur (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_ADJBLUR"), 0, 100, 1, 0))), Smethod (Gtk::manage (new MyComboBoxText ())), + Exclumethod (Gtk::manage (new MyComboBoxText ())), + retinexMethod (Gtk::manage (new MyComboBoxText ())), qualityMethod (Gtk::manage (new MyComboBoxText ())), qualitycurveMethod (Gtk::manage (new MyComboBoxText ())), blurMethod (Gtk::manage (new MyComboBoxText ())), dustMethod (Gtk::manage (new MyComboBoxText ())), + excluFrame (Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_EXCLUF")))), artifFrame (Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_ARTIF")))), shapeFrame (Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_SHFR")))), superFrame (Gtk::manage (new Gtk::Frame ())), @@ -141,8 +147,10 @@ Locallab::Locallab (): labqual (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_QUAL_METHOD") + ":"))), labqualcurv (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_QUALCURV_METHOD") + ":"))), labmS (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_STYPE") + ":"))), + labmEx (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_EXCLUTYPE") + ":"))), ctboxS (Gtk::manage (new Gtk::HBox ())), + ctboxEx (Gtk::manage (new Gtk::HBox ())), dhbox (Gtk::manage (new Gtk::HBox ())), qualbox (Gtk::manage (new Gtk::HBox ())), qualcurvbox (Gtk::manage (new Gtk::HBox ())), @@ -221,6 +229,19 @@ Locallab::Locallab (): expdenoi->signal_button_release_event().connect_notify ( sigc::bind ( sigc::mem_fun (this, &Locallab::foldAllButMe), expdenoi) ); enabledenoiConn = expdenoi->signal_enabled_toggled().connect ( sigc::bind ( sigc::mem_fun (this, &Locallab::enableToggled), expdenoi) ); + ctboxEx->pack_start (*labmEx, Gtk::PACK_SHRINK, 4); + ctboxEx->set_tooltip_markup (M ("TP_LOCALLAB_EXCLUTYPE_TOOLTIP")); + + Exclumethod->append (M ("TP_LOCALLAB_EXNORM")); + Exclumethod->append (M ("TP_LOCALLAB_EXECLU")); + Exclumethod->set_active (0); + Exclumethodconn = Exclumethod->signal_changed().connect ( sigc::mem_fun (*this, &Locallab::ExclumethodChanged) ); + + sensiexclu->set_tooltip_text (M ("TP_LOCALLAB_SENSIEXCLU_TOOLTIP")); + sensiexclu->setAdjusterListener (this); + + // struc->set_tooltip_text (M ("TP_LOCALLAB_STRUC_TOOLTIP")); + struc->setAdjusterListener (this); ctboxS->pack_start (*labmS, Gtk::PACK_SHRINK, 4); ctboxS->set_tooltip_markup (M ("TP_LOCALLAB_STYPE_TOOLTIP")); @@ -232,6 +253,7 @@ Locallab::Locallab (): Smethod->set_active (0); Smethodconn = Smethod->signal_changed().connect ( sigc::mem_fun (*this, &Locallab::SmethodChanged) ); + //locX->set_tooltip_text (M("TP_LOCAL_WIDTH_TOOLTIP")); locX->setAdjusterListener (this); @@ -497,9 +519,23 @@ Locallab::Locallab (): chromaref->hide(); lumaref->hide(); sobelref->hide(); + ctboxEx->pack_start (*Exclumethod); + shapeBox->pack_start (*ctboxEx); + + excluFrame->set_label_align (0.025, 0.5); + excluFrame->set_tooltip_text (M ("TP_LOCALLAB_EXCLUF_TOOLTIP")); + ToolParamBlock* const excluBox = Gtk::manage (new ToolParamBlock()); + + excluBox->pack_start (*sensiexclu); +// excluBox->pack_start (*struc); + excluFrame->add (*excluBox); + shapeBox->pack_start (*excluFrame); + + ctboxS->pack_start (*Smethod); shapeBox->pack_start (*ctboxS); + shapeBox->pack_start (*locX); shapeBox->pack_start (*locXL); //pack_start (*degree); @@ -632,7 +668,7 @@ Locallab::Locallab (): superFrame->set_label_widget (*curvactiv); ToolParamBlock* const colorBox = Gtk::manage (new ToolParamBlock()); - ToolParamBlock* const dustBox = Gtk::manage (new ToolParamBlock()); + // ToolParamBlock* const dustBox = Gtk::manage (new ToolParamBlock()); dustMethod->append (M ("TP_LOCALLAB_DSCOP")); dustMethod->append (M ("TP_LOCALLAB_DSMOV")); dustMethod->append (M ("TP_LOCALLAB_DSPAS")); @@ -649,15 +685,15 @@ Locallab::Locallab (): colorBox->pack_start (*sensi); dustFrame->set_label_align (0.025, 0.5); - dustBox->pack_start (*dustMethod); - dustBox->pack_start (*lastdust); +// dustBox->pack_start (*dustMethod); +// dustBox->pack_start (*lastdust); - dustBox->pack_start (*cutpast); - dustBox->pack_start (*centerXbuf); - dustBox->pack_start (*centerYbuf); - dustBox->pack_start (*adjblur); - dustFrame->add (*dustBox); -// colorBox->pack_start (*dustFrame); +// dustBox->pack_start (*cutpast); +// dustBox->pack_start (*centerXbuf); +// dustBox->pack_start (*centerYbuf); +// dustBox->pack_start (*adjblur); +// dustFrame->add (*dustBox); +// colorBox->pack_start (*dustFrame); centerXbuf->hide(); centerYbuf->hide(); @@ -1196,6 +1232,7 @@ void Locallab::updateToolState (std::vector &tpOpen) void Locallab::neutral_pressed () { Smethod->set_active (0); + Exclumethod->set_active (0); locX->resetValue (false); locXL->resetValue (false); locY->resetValue (false); @@ -1208,6 +1245,8 @@ void Locallab::neutral_pressed () adjblur->resetValue (false); blurMethod->set_active (0); dustMethod->set_active (1); + sensiexclu->resetValue (false); + struc->resetValue (false); qualityMethod->set_active (0); qualitycurveMethod->set_active (0); @@ -1755,11 +1794,20 @@ bool Locallab::localComputed_ () dustMethod->set_active (2); } - double intermed = 0.01 * (double) nextdatasp[78]; + if (nextdatasp[78] == 0) { + Exclumethod->set_active (0); + } else if (nextdatasp[78] == 1) { + Exclumethod->set_active (1); + } + + sensiexclu->setValue (nextdatasp[79]); + struc->setValue (nextdatasp[80]); + + double intermed = 0.01 * (double) nextdatasp[81]; hueref->setValue (intermed); - chromaref->setValue (nextdatasp[79]); - lumaref->setValue (nextdatasp[80]); - sobelref->setValue (nextdatasp[81]); + chromaref->setValue (nextdatasp[82]); + lumaref->setValue (nextdatasp[83]); + sobelref->setValue (nextdatasp[84]); int *s_datc; s_datc = new int[70]; @@ -1942,11 +1990,11 @@ bool Locallab::localComputed_ () } if (listener) {//for cutpast - listener->panelChanged (Evlocallabcutpast, M ("GENERAL_ENABLED")); + // listener->panelChanged (Evlocallabcutpast, M ("GENERAL_ENABLED")); } if (listener) {//for cutpast - listener->panelChanged (Evlocallablastdust, M ("GENERAL_ENABLED")); + // listener->panelChanged (Evlocallablastdust, M ("GENERAL_ENABLED")); } if (listener) {//for blur method @@ -1954,7 +2002,11 @@ bool Locallab::localComputed_ () } if (listener) {//for dust method - listener->panelChanged (EvlocallabdustMethod, dustMethod->get_active_text ()); + // listener->panelChanged (EvlocallabdustMethod, dustMethod->get_active_text ()); + } + + if (listener) {//for Exclude method + listener->panelChanged (Evlocallabexclumethod, Exclumethod->get_active_text ()); } if (listener) {//for curvactiv @@ -2039,7 +2091,7 @@ bool Locallab::localComputed_ () void Locallab::localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, std::string sk_str, std::string ps_str, std::string ex_str, int sp, int maxdat) { - for (int i = 2; i < 82; i++) { + for (int i = 2; i < 85; i++) { nextdatasp[i] = datasp[i][sp]; } @@ -2142,6 +2194,8 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) threshold->setEditedState (pedited->locallab.threshold ? Edited : UnEdited); chromacbdl->setEditedState (pedited->locallab.chromacbdl ? Edited : UnEdited); + sensiexclu->setEditedState (pedited->locallab.sensiexclu ? Edited : UnEdited); + struc->setEditedState (pedited->locallab.struc ? Edited : UnEdited); sensi->setEditedState (pedited->locallab.sensi ? Edited : UnEdited); sensih->setEditedState (pedited->locallab.sensih ? Edited : UnEdited); @@ -2199,6 +2253,10 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) Smethod->set_active_text (M ("GENERAL_UNCHANGED")); } + if (!pedited->locallab.Exclumethod) { + Exclumethod->set_active_text (M ("GENERAL_UNCHANGED")); + } + if (!pedited->locallab.retinexMethod) { retinexMethod->set_active_text (M ("GENERAL_UNCHANGED")); } @@ -2224,6 +2282,7 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) setEnabled (pp->locallab.enabled); Smethodconn.block (true); + Exclumethodconn.block (true); retinexMethodConn.block (true); qualityMethodConn.block (true); qualitycurveMethodConn.block (true); @@ -2281,6 +2340,8 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) black->setValue (pp->locallab.black); shcompr->setValue (pp->locallab.shcompr); shcompr->set_sensitive (! ((int)black->getValue () == 0)); //at black=0 shcompr value has no effect + sensiexclu->setValue (pp->locallab.sensiexclu); + struc->setValue (pp->locallab.struc); sharradius->setValue (pp->locallab.sharradius); sharamount->setValue (pp->locallab.sharamount); @@ -2410,6 +2471,15 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) SmethodChanged(); Smethodconn.block (false); + if (pp->locallab.Exclumethod == "norm") { + Exclumethod->set_active (0); + } else if (pp->locallab.Exclumethod == "exc") { + Exclumethod->set_active (1); + } + + ExclumethodChanged(); + Exclumethodconn.block (false); + if (pp->locallab.retinexMethod == "low") { retinexMethod->set_active (0); } else if (pp->locallab.retinexMethod == "uni") { @@ -2751,6 +2821,8 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) pp->locallab.sensih = sensih->getIntValue (); pp->locallab.retrab = retrab->getIntValue (); pp->locallab.sensicb = sensicb->getIntValue (); + pp->locallab.sensiexclu = sensiexclu->getIntValue (); + pp->locallab.struc = struc->getIntValue (); pp->locallab.sensibn = sensibn->getIntValue (); pp->locallab.sensitm = sensitm->getIntValue (); pp->locallab.radius = radius->getIntValue (); @@ -2818,6 +2890,7 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->locallab.degree = degree->getEditedState (); pedited->locallab.Smethod = Smethod->get_active_text() != M ("GENERAL_UNCHANGED"); + pedited->locallab.Exclumethod = Exclumethod->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->locallab.retinexMethod = retinexMethod->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->locallab.qualityMethod = qualityMethod->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->locallab.qualitycurveMethod = qualitycurveMethod->get_active_text() != M ("GENERAL_UNCHANGED"); @@ -2858,6 +2931,8 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) pedited->locallab.sensih = sensih->getEditedState (); pedited->locallab.retrab = retrab->getEditedState (); pedited->locallab.sensicb = sensicb->getEditedState (); + pedited->locallab.sensiexclu = sensiexclu->getEditedState (); + pedited->locallab.struc = struc->getEditedState (); pedited->locallab.sensibn = sensibn->getEditedState (); pedited->locallab.sensitm = sensitm->getEditedState (); pedited->locallab.radius = radius->getEditedState (); @@ -2963,6 +3038,11 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) pp->locallab.qualitycurveMethod = "enh"; } + if (Exclumethod->get_active_row_number() == 0) { + pp->locallab.Exclumethod = "norm"; + } else if (Exclumethod->get_active_row_number() == 1) { + pp->locallab.Exclumethod = "exc"; + } if (Smethod->get_active_row_number() == 0) { pp->locallab.Smethod = "IND"; @@ -3211,7 +3291,7 @@ void Locallab::dustMethodChanged() if (listener) { - listener->panelChanged (EvlocallabdustMethod, dustMethod->get_active_text ()); + // listener->panelChanged (EvlocallabdustMethod, dustMethod->get_active_text ()); } } @@ -3253,6 +3333,24 @@ void Locallab::qualitycurveMethodChanged() } } +void Locallab::ExclumethodChanged() +{ + if (!batchMode) { + if (Exclumethod->get_active_row_number() == 0) { + excluFrame->hide(); + } else if (Exclumethod->get_active_row_number() == 1) { + excluFrame->show(); + } + } + + + if (listener) { + listener->panelChanged (Evlocallabexclumethod, Exclumethod->get_active_text ()); + } + +} + + void Locallab::SmethodChanged () { if (!batchMode) { @@ -3379,9 +3477,9 @@ void Locallab::cutpastChanged () if (listener) { if (getEnabled()) { - listener->panelChanged (Evlocallabcutpast, M ("GENERAL_ENABLED")); + // listener->panelChanged (Evlocallabcutpast, M ("GENERAL_ENABLED")); } else { - listener->panelChanged (Evlocallabcutpast, M ("GENERAL_DISABLED")); + // listener->panelChanged (Evlocallabcutpast, M ("GENERAL_DISABLED")); } } } @@ -3405,9 +3503,9 @@ void Locallab::lastdustChanged () if (listener) { if (getEnabled()) { - listener->panelChanged (Evlocallablastdust, M ("GENERAL_ENABLED")); + // listener->panelChanged (Evlocallablastdust, M ("GENERAL_ENABLED")); } else { - listener->panelChanged (Evlocallablastdust, M ("GENERAL_DISABLED")); + // listener->panelChanged (Evlocallablastdust, M ("GENERAL_DISABLED")); } } } @@ -3600,6 +3698,8 @@ void Locallab::setDefaults (const ProcParams * defParams, const ParamsEdited * p sensiex->setDefault (defParams->locallab.sensiex); sensih->setDefault (defParams->locallab.sensih); retrab->setDefault (defParams->locallab.retrab); + sensiexclu->setDefault (defParams->locallab.sensiexclu); + struc->setDefault (defParams->locallab.struc); sensicb->setDefault (defParams->locallab.sensicb); sensibn->setDefault (defParams->locallab.sensibn); sensitm->setDefault (defParams->locallab.sensitm); @@ -3671,6 +3771,8 @@ void Locallab::setDefaults (const ProcParams * defParams, const ParamsEdited * p sensiex->setDefaultEditedState (pedited->locallab.sensiex ? Edited : UnEdited); sensih->setDefaultEditedState (pedited->locallab.sensih ? Edited : UnEdited); retrab->setDefaultEditedState (pedited->locallab.retrab ? Edited : UnEdited); + sensiexclu->setDefaultEditedState (pedited->locallab.sensiexclu ? Edited : UnEdited); + struc->setDefaultEditedState (pedited->locallab.struc ? Edited : UnEdited); sensicb->setDefaultEditedState (pedited->locallab.sensicb ? Edited : UnEdited); sensibn->setDefaultEditedState (pedited->locallab.sensibn ? Edited : UnEdited); sensitm->setDefaultEditedState (pedited->locallab.sensitm ? Edited : UnEdited); @@ -3742,7 +3844,9 @@ void Locallab::setDefaults (const ProcParams * defParams, const ParamsEdited * p sensih->setDefaultEditedState (Irrelevant); retrab->setDefaultEditedState (Irrelevant); sensicb->setDefaultEditedState (Irrelevant); - sensibn->setDefaultEditedState (Irrelevant); + sensiexclu->setDefaultEditedState (Irrelevant); + sensicb->setDefaultEditedState (Irrelevant); + struc->setDefaultEditedState (Irrelevant); sensitm->setDefaultEditedState (Irrelevant); radius->setDefaultEditedState (Irrelevant); strength->setDefaultEditedState (Irrelevant); @@ -3967,12 +4071,16 @@ void Locallab::adjusterChanged (Adjuster * a, double newval) listener->panelChanged (Evlocallabchromacbdl, chromacbdl->getTextValue()); } else if (a == sensicb) { listener->panelChanged (Evlocallabsensicb, sensicb->getTextValue()); + } else if (a == sensiexclu) { + listener->panelChanged (Evlocallabsensiexclu, sensiexclu->getTextValue()); + } else if (a == struc) { +// listener->panelChanged (Evlocallabstruc, struc->getTextValue()); } else if (a == sensibn) { listener->panelChanged (Evlocallabsensibn, sensibn->getTextValue()); } else if (a == proxi) { listener->panelChanged (Evlocallabproxi, proxi->getTextValue()); } else if (a == adjblur) { - listener->panelChanged (Evlocallabadjblur, adjblur->getTextValue()); + // listener->panelChanged (Evlocallabadjblur, adjblur->getTextValue()); } else if (a == centerX || a == centerY) { listener->panelChanged (EvlocallabCenter, Glib::ustring::compose ("X=%1\nY=%2", centerX->getTextValue(), centerY->getTextValue())); } else if (a == centerXbuf || a == centerYbuf) { @@ -4091,6 +4199,8 @@ void Locallab::trimValues (rtengine::procparams::ProcParams * pp) sensiex->trimValue (pp->locallab.sensiex); sensih->trimValue (pp->locallab.sensih); retrab->trimValue (pp->locallab.retrab); + sensiexclu->trimValue (pp->locallab.sensiexclu); + struc->trimValue (pp->locallab.struc); sensicb->trimValue (pp->locallab.sensicb); sensibn->trimValue (pp->locallab.sensibn); sensitm->trimValue (pp->locallab.sensitm); @@ -4172,6 +4282,8 @@ void Locallab::setBatchMode (bool batchMode) sensiex->showEditedCB (); sensih->showEditedCB (); retrab->showEditedCB (); + sensiexclu->showEditedCB (); + struc->showEditedCB (); sensicb->showEditedCB (); sensibn->showEditedCB (); sensitm->showEditedCB (); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 03a292e51..e4332114d 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -68,6 +68,9 @@ private: Adjuster* const centerX; Adjuster* const centerY; Adjuster* const circrad; + Adjuster* const sensiexclu; + Adjuster* const struc; + Adjuster* const thres; Adjuster* const proxi; Adjuster* const lightness; @@ -123,12 +126,14 @@ private: Adjuster* const adjblur; MyComboBoxText* const Smethod; + MyComboBoxText* const Exclumethod; MyComboBoxText* const retinexMethod; MyComboBoxText* const qualityMethod; MyComboBoxText* const qualitycurveMethod; MyComboBoxText* const blurMethod; MyComboBoxText* const dustMethod; + Gtk::Frame* const excluFrame; Gtk::Frame* const artifFrame; Gtk::Frame* const shapeFrame; @@ -139,8 +144,11 @@ private: Gtk::Label* const labqual; Gtk::Label* const labqualcurv; Gtk::Label* const labmS; + Gtk::Label* const labmEx; Gtk::HBox* const ctboxS; + Gtk::HBox* const ctboxEx; + Gtk::HBox* const dhbox; Gtk::HBox* const qualbox; Gtk::HBox* const qualcurvbox; @@ -212,7 +220,7 @@ private: sigc::connection enableretiConn, enablesharpConn, enablecbdlConn; sigc::connection enabledenoiConn; sigc::connection editConn, avoidConn, inversConn, cutpastConn, lastdustConn, curvactivConn, activlumConn, inversradConn, inversretConn, inversshaConn, neutralconn, neutralconn1; - sigc::connection Smethodconn; + sigc::connection Smethodconn, Exclumethodconn; sigc::connection retinexMethodConn; sigc::connection qualityMethodConn; sigc::connection qualitycurveMethodConn; @@ -221,7 +229,7 @@ private: - int nextdatasp[82]; + int nextdatasp[85]; int nextlength; std::string nextstr; std::string nextstr2; @@ -266,6 +274,7 @@ public: void updateGeometry (const int centerX_, const int centerY_, const int circrad_, const int locY_, const double degree_, const int locX_, const int locYT_, const int locXL_, const int fullWidth = -1, const int fullHeight = -1); void SmethodChanged (); + void ExclumethodChanged (); void writeOptions (std::vector &tpOpen); void updateToolState (std::vector &tpOpen); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 68dbc94a8..d06f45137 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -351,6 +351,8 @@ void ParamsEdited::set (bool v) locallab.sensiex = v; locallab.sensih = v; locallab.retrab = v; + locallab.sensiexclu = v; + locallab.struc = v; locallab.sensicb = v; locallab.sensibn = v; locallab.sensitm = v; @@ -366,6 +368,7 @@ void ParamsEdited::set (bool v) locallab.chrrt = v; locallab.avoid = v; locallab.Smethod = v; + locallab.Exclumethod = v; locallab.retinexMethod = v; locallab.blurMethod = v; locallab.dustMethod = v; @@ -966,6 +969,7 @@ void ParamsEdited::initFrom (const std::vector locallab.locYT = locallab.locYT && p.locallab.locYT == other.locallab.locYT; locallab.locXL = locallab.locXL && p.locallab.locXL == other.locallab.locXL; locallab.Smethod = locallab.Smethod && p.locallab.Smethod == other.locallab.Smethod; + locallab.Exclumethod = locallab.Exclumethod && p.locallab.Exclumethod == other.locallab.Exclumethod; locallab.retinexMethod = locallab.retinexMethod && p.locallab.retinexMethod == other.locallab.retinexMethod; locallab.blurMethod = locallab.blurMethod && p.locallab.blurMethod == other.locallab.blurMethod; locallab.dustMethod = locallab.dustMethod && p.locallab.dustMethod == other.locallab.dustMethod; @@ -1000,6 +1004,8 @@ void ParamsEdited::initFrom (const std::vector locallab.sensiex = locallab.sensiex && p.locallab.sensiex == other.locallab.sensiex; locallab.sensih = locallab.sensih && p.locallab.sensih == other.locallab.sensih; locallab.retrab = locallab.retrab && p.locallab.retrab == other.locallab.retrab; + locallab.sensiexclu = locallab.sensiexclu && p.locallab.sensiexclu == other.locallab.sensiexclu; + locallab.struc = locallab.struc && p.locallab.struc == other.locallab.struc; locallab.sensicb = locallab.sensicb && p.locallab.sensicb == other.locallab.sensicb; locallab.sensibn = locallab.sensibn && p.locallab.sensibn == other.locallab.sensibn; locallab.sensitm = locallab.sensitm && p.locallab.sensitm == other.locallab.sensitm; @@ -2437,6 +2443,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.locallab.Smethod = mods.locallab.Smethod; } + if (locallab.Exclumethod) { + toEdit.locallab.Exclumethod = mods.locallab.Exclumethod; + } + if (locallab.retinexMethod) { toEdit.locallab.retinexMethod = mods.locallab.retinexMethod; } @@ -2605,6 +2615,13 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.locallab.retrab = mods.locallab.retrab; } + if (locallab.sensiexclu) { + toEdit.locallab.sensiexclu = mods.locallab.sensiexclu; + } + + if (locallab.struc) { + toEdit.locallab.struc = mods.locallab.struc; + } if (locallab.sensicb) { toEdit.locallab.sensicb = mods.locallab.sensicb; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index b0f3cda6a..d18b37e39 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -478,6 +478,9 @@ public: bool transit; bool avoid; bool Smethod; + bool Exclumethod; + bool sensiexclu; + bool struc; bool retinexMethod; bool blurMethod; bool dustMethod;