diff --git a/rtengine/color.h b/rtengine/color.h index cf44c5fe1..8031e4683 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1728,7 +1728,6 @@ public: return (hr); } - }; } diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 60f8b14d2..f70f658ad 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -1244,6 +1244,51 @@ void LocretigainCurverab::Set (const std::vector &curvePoints) } } + +LocHHCurve::LocHHCurve() : sum (0.f) {}; + +void LocHHCurve::Reset() +{ + lutLocHHCurve.reset(); + sum = 0.f; +} +void LocHHCurve::Set (const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutLocHHCurve (501); // raise this value if the quality suffers from this number of samples + sum = 0.f; + + for (int i = 0; i < 501; i++) { + lutLocHHCurve[i] = pCurve.getVal (double (i) / 500.); + + if (lutLocHHCurve[i] < 0.02f) { + lutLocHHCurve[i] = 0.02f; //avoid 0.f for wavelet : under 0.01f quasi no action for each value + } + + sum += lutLocHHCurve[i]; + } + + //lutLocHHCurve.dump("wav"); +} + + + +void LocHHCurve::Set (const std::vector &curvePoints, bool &HHutili) +{ + if (HHutili && !curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve ttcurve (curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + ttcurve.setIdentityValue (0.); + Set (ttcurve); + } else { + Reset(); + } +} + + LocLHCurve::LocLHCurve() : sum (0.f) {}; void LocLHCurve::Reset() @@ -1275,10 +1320,13 @@ void LocLHCurve::Set (const Curve &pCurve) //lutLocCurve.dump("wav"); } -void LocLHCurve::Set (const std::vector &curvePoints) + + + +void LocLHCurve::Set (const std::vector &curvePoints, bool &LHutili) { - if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + if (LHutili && !curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { FlatCurve tcurve (curvePoints, false, CURVES_MIN_POLY_POINTS / 2); tcurve.setIdentityValue (0.); Set (tcurve); diff --git a/rtengine/curves.h b/rtengine/curves.h index e97842b80..a45a8f11d 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -549,7 +549,7 @@ public: virtual ~LocLHCurve() {}; LocLHCurve(); void Reset(); - void Set (const std::vector &curvePoints); + void Set (const std::vector &curvePoints, bool &LHutili); float getSum() const { return sum; @@ -565,6 +565,33 @@ public: } }; +class LocHHCurve +{ +private: + LUTf lutLocHHCurve; // 0xffff range + void Set (const Curve &pCurve); + +public: + float sum; + + virtual ~LocHHCurve() {}; + LocHHCurve(); + void Reset(); + void Set (const std::vector &curvePoints, bool &HHutili); + float getSum() const + { + return sum; + } + + float operator[] (float index) const + { + return lutLocHHCurve[index]; + } + operator bool (void) const + { + return lutLocHHCurve; + } +}; class LocretigainCurve { diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 9b3a03bc4..a90fdd642 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ - + #include "dcrop.h" #include "curves.h" #include "mytime.h" @@ -712,8 +712,9 @@ void Crop::update (int todo) parent->imgsrc->getMetaData()->getFocusDist(), parent->imgsrc->getMetaData()->getFNumber(), parent->imgsrc->getRotateDegree(), false); - else - baseCrop->copyData(transCrop); + else { + baseCrop->copyData (transCrop); + } if (transCrop) { baseCrop = transCrop; @@ -819,11 +820,14 @@ void Crop::update (int todo) LUTf lllocalcurve2 (65536, 0); bool localcutili = parent->locallutili; LUTf cclocalcurve2 (65536, 0); + bool LHutili = parent->LHutili; + bool HHutili = parent->HHutili; LUTu dummy; bool needslocal = params.locallab.enabled; LocretigainCurve locRETgainCurve; LocLHCurve loclhCurve; + LocHHCurve lochhCurve; LocretigainCurverab locRETgainCurverab; locallutili = false; @@ -1021,7 +1025,16 @@ void Crop::update (int todo) params.locallab.LHcurve.clear(); params.locallab.LHcurve = lhc; - params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve); + std::vector hhc; + + for (int j = 0; j < parent->sizehhcs[sp]; j++) { + hhc.push_back ((double) (parent->hhcurvs[sp * 500 + j]) / 1000.); + } + + params.locallab.HHcurve.clear(); + params.locallab.HHcurve = hhc; + + params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve, lochhCurve, LHutili, HHutili); locallutili = false; CurveFactory::curveLocal (locallutili, params.locallab.llcurve, lllocalcurve2, sca); localcutili = false; @@ -1033,7 +1046,7 @@ void Crop::update (int todo) // printf ("dcr1 sp=%i huer=%f \n", sp, parent->huerefs[sp] / 100.f ); - parent->ipf.Lab_Local (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, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); + parent->ipf.Lab_Local (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, LHutili, HHutili, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); lllocalcurve2.clear(); cclocalcurve2.clear(); @@ -1257,7 +1270,16 @@ void Crop::update (int todo) params.locallab.LHcurve.clear(); params.locallab.LHcurve = lhcL; - params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve); + std::vector hhcL; + + for (int j = 0; j < parent->sizehhcs[sp]; j++) { + hhcL.push_back ((double) (parent->hhcurvs[0 * 500 + j]) / 1000.); + parent->hhcurvs[sp * 500 + j] = parent->hhcurvs[0 * 500 + j] ; + } + + params.locallab.HHcurve.clear(); + params.locallab.HHcurve = hhcL; + params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve, lochhCurve, LHutili, HHutili); locallutili = false; localcutili = false; @@ -1269,7 +1291,7 @@ void Crop::update (int todo) params.locallab.chromaref = parent->chromarefs[sp]; params.locallab.lumaref = parent->lumarefs[sp]; // printf ("dcr2 sp=%i huer=%f \n", sp, parent->huerefs[sp] / 100.f); - parent->ipf.Lab_Local (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, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); + parent->ipf.Lab_Local (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, LHutili, HHutili, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); lllocalcurve2.clear(); cclocalcurve2.clear(); @@ -1631,7 +1653,7 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte parent->ipf.transCoord (parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh); - if (check_need_larger_crop_for_lcp_distortion(parent->fw, parent->fh, orx, ory, orw, orh, parent->params)) { + if (check_need_larger_crop_for_lcp_distortion (parent->fw, parent->fh, orx, ory, orw, orh, parent->params)) { // TODO - this is an estimate of the max distortion relative to the image size. ATM it is hardcoded to be 15%, which seems enough. If not, need to revise int dW = int (double (parent->fw) * 0.15 / (2 * skip)); int dH = int (double (parent->fh) * 0.15 / (2 * skip)); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 5303c22e2..9bd9800d9 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -93,7 +93,7 @@ ImProcCoordinator::ImProcCoordinator () plistener (nullptr), awbListener (nullptr), imageListener (nullptr), aeListener (nullptr), acListener (nullptr), abwListener (nullptr), aloListener (nullptr), actListener (nullptr), adnListener (nullptr), awavListener (nullptr), dehaListener (nullptr), frameCountListener (nullptr), imageTypeListener (nullptr), hListener (nullptr), resultValid (false), lastOutputProfile ("BADFOOD"), lastOutputIntent (RI__COUNT), lastOutputBPC (false), thread (nullptr), changeSinceLast (0), updaterRunning (false), destroying (false), utili (false), autili (false), butili (false), ccutili (false), cclutili (false), clcutili (false), opautili (false), wavcontlutili (false), - dataspot (nullptr), retistr (nullptr), llstr (nullptr), lhstr (nullptr), ccstr (nullptr), + dataspot (nullptr), retistr (nullptr), llstr (nullptr), lhstr (nullptr), ccstr (nullptr), hhstr (nullptr), circrads (500, -10000), centerx (500, -10000), centery (500, -10000), @@ -157,7 +157,9 @@ ImProcCoordinator::ImProcCoordinator () llcurvs (25000, -10000), //allow 500 values for each control point * 500 sizellcs (500, -10000), lhcurvs (25000, -10000), //allow 500 values for each control point * 500 + hhcurvs (25000, -10000), //allow 500 values for each control point * 500 sizelhcs (500, -10000), + sizehhcs (500, -10000), cccurvs (25000, -10000), //allow 500 values for each control point * 500 sizecccs (500, -10000), huerefs (500, -100000.f), @@ -480,8 +482,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if (needstransform) ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getMetaData()->getFNumber(), imgsrc->getRotateDegree(), false); - else - orig_prev->copyData(oprevi); + else { + orig_prev->copyData (oprevi); + } } if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { @@ -840,7 +843,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { for (int sp = 1; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10007;//new value for tone mapping + int t_mipversion = 10008;//new value for tone mapping int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -916,6 +919,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) //10007 int t_qualitycurveMethod = 0; + //versionmip = 10008 HHcurv + std::string t_curvhh = "1000A0B500C350D350E166F500G350H350I333J500K350L350M500N500O350P350Q666R500S350T350U833V500W350X350Y"; //all variables except locRETgainCurve 'coomon for all) fic << "Mipversion=" << t_mipversion << '@' << endl; @@ -983,6 +988,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fic << "curveLL=" << t_curvll << '@' << endl; fic << "curveLH=" << t_curvlh << '@' << endl; fic << "curveCC=" << t_curvcc << '@' << endl; + fic << "curveHH=" << t_curvhh << '@' << endl; fic << endl; } @@ -1011,6 +1017,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) llstr = new std::string[maxspot]; lhstr = new std::string[maxspot]; ccstr = new std::string[maxspot]; + hhstr = new std::string[maxspot]; { @@ -1229,6 +1236,30 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } lhstr[0] = lh_str + "@"; + + //HH curve + //curve local H f(H) + int sizhh = params.locallab.HHcurve.size(); + + if (sizhh > 69) { + sizhh = 69;//to avoid crash + } + + + int s_datcurhh[sizhh + 1]; + + for (int j = 0; j < sizhh; j++) { + s_datcurhh[j] = hhcurvs[0 + j] = (int) (1000. * params.locallab.HHcurve[j]); + } + + std::string hh_str = ""; + + for (int j = 0; j < sizhh; j++) { + hh_str = hh_str + std::to_string (s_datcurhh[j]) + delim[j]; + } + + hhstr[0] = hh_str + "@"; + //end local L = f(H) //spot references /* @@ -1241,7 +1272,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if (params.locallab.anbspot == 0) { //update GUI and MIP after current spot ==> params, shift with the other alolistener if (aloListener && params.locallab.anbspot == 0) { - aloListener->localretChanged (dataspot, retistr[0], llstr[0], lhstr[0], ccstr[0], 0, 1); + aloListener->localretChanged (dataspot, retistr[0], llstr[0], lhstr[0], ccstr[0], hhstr[0], 0, 1); } } @@ -1260,6 +1291,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) bool excurvll = true; bool excurvlh = true; bool excurvcc = true; + bool excurvhh = true; ifstream fich (datal, ios::in); @@ -1276,6 +1308,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) excurvret = false; excurvll = false; excurvlh = false; + excurvhh = false; } if (versionmip == 10001) { @@ -1283,6 +1316,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) excurvret = false; excurvll = false; excurvlh = false; + excurvhh = false; } @@ -1402,6 +1436,22 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) // sizecc = longec; } + if (excurvhh && spotline.substr (0, pos) == "curveHH") { + std::string cursthh; + // int longecurh; + std::string strendhh = spotline.substr (posend - 1, 1); + // std::size_t poszh = spotline.find (strendh); + // int longeh; + + for (int sh = 0; sh < 69; sh++) { + if (delim[sh] == strendhh) { + // longeh = sh + 1; + } + } + + hhstr[ns] = str3; + // sizelh = longeh; + } } @@ -1471,13 +1521,21 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } + if (versionmip == 10007) { + + for (int sp = 1; sp < maxspot; sp++) { // spots default + std::string hh_str = "1000A0B500C350D350E166F500G350H350I333J500K350L350M500N500O350P350Q666R500S350T350U833V500W350X350Y"; + hhstr[sp] = hh_str + "@"; + } + } + if (ns < (maxspot - 1)) { ofstream fic (datal, ios::out | ios::app); // ouverture en écriture avec effacement du fichier ouvert for (int sp = ns + 1 ; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10007; + int t_mipversion = 10008; int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -1547,7 +1605,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) std::string t_curvcc = "3000A0B0C1000D1000E"; //10007 int t_qualitycurveMethod = 0; - + std::string t_curvhh = "1000A0B500C350D350E166F500G350H350I333J500K350L350M500N500O350P350Q666R500S350T350U833V500W350X350Y"; + //10008 fic << "Mipversion=" << t_mipversion << '@' << endl; fic << "Spot=" << t_sp << '@' << endl; fic << "Circrad=" << t_circrad << '@' << endl; @@ -1612,6 +1671,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fic << "curveLL=" << t_curvll << '@' << endl; fic << "curveLH=" << t_curvlh << '@' << endl; fic << "curveCC=" << t_curvcc << '@' << endl; + fic << "curveHH=" << t_curvhh << '@' << endl; fic << endl; } @@ -1741,6 +1801,23 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } + if (spotline2.substr (0, pos2) == "curveHH") { + std::string curstr2hh; + // int longecur2h; + std::string strend2hh = spotline2.substr (posend2 - 1, 1); + // std::size_t posz2h = spotline2.find (strend2h); + // int longe2h; + + for (int sh = 0; sh < 69; sh++) { + if (delim[sh] == strend2hh) { + // longe2h = sh + 1; + } + } + + hhstr[ns] = str32; + // sizelh2 = longe2h; + + } } @@ -1979,6 +2056,24 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) delete [] s_datch; + + int *s_datchh; + s_datchh = new int[70]; + int sizhh; + + ipf.strcurv_data (hhstr[sp], s_datchh, sizhh); + + sizehhcs[sp] = sizhh; + + std::vector chhend; + + for (int j = 0; j < sizhh; j++) { + hhcurvs[sp * 500 + j] = s_datchh[j]; + chhend.push_back ((double) (s_datchh[j]) / 1000.); + } + + delete [] s_datchh; + params.locallab.localTgaincurve.clear(); params.locallab.localTgaincurve = cretiend; @@ -1993,10 +2088,25 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) params.locallab.cccurve.clear(); params.locallab.cccurve = cccend; + params.locallab.HHcurve.clear(); + params.locallab.HHcurve = chhend; + locallutili = false; localcutili = false; + LHutili = false; + HHutili = false; + std::string t_curvhhref = "1000A0B500C350D350E166F500G350H350I333J500K350L350M500N500O350P350Q666R500S350T350U833V500W350X350Y@"; - params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve); + if (lhstr[sp].c_str() != t_curvhhref) { + LHutili = true; + } + + if (hhstr[sp].c_str() != t_curvhhref) { + HHutili = true; + } + + // printf ("HHstr=%s\n", hhstr[sp].c_str()); + params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve, lochhCurve, LHutili, HHutili); CurveFactory::curveLocal (locallutili, params.locallab.llcurve, lllocalcurve, sca); //scale == 1 ? 1 : 16); CurveFactory::curveCCLocal (localcutili, params.locallab.cccurve, cclocalcurve, sca); //scale == 1 ? 1 : 16); double huere, chromare, lumare; @@ -2011,7 +2121,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) dataspot[59][sp] = chromarefs[sp] = params.locallab.chromaref; dataspot[60][sp] = lumarefs[sp] = params.locallab.lumaref; //printf("sp=%i huerefsp=%f\n", sp, huerefs[sp]); - ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); + ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); lllocalcurve.clear(); cclocalcurve.clear(); @@ -2027,7 +2137,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if (aloListener && realspot != dataspot[16][0]) { //update GUI and MIP - aloListener->localChanged (dataspot, retistr[sp], llstr[sp], lhstr[sp], ccstr[sp], sp, maxreal); + aloListener->localChanged (dataspot, retistr[sp], llstr[sp], lhstr[sp], ccstr[sp], hhstr[sp], sp, maxreal); } @@ -2303,7 +2413,40 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) delete [] s_datch; - params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve); + int *s_datchh; + s_datchh = new int[70]; + int sizhh; + + ipf.strcurv_data (hhstr[0], s_datchh, sizhh); + sizehhcs[sp] = sizhh; + std::vector chhend; + + hhstr[sp] = hhstr[0]; + + for (int j = 0; j < sizhh; j++) { + hhcurvs[sp * 500 + j] = s_datchh[j]; + chhend.push_back ((double) (s_datchh[j]) / 1000.); + + } + + params.locallab.HHcurve.clear(); + params.locallab.HHcurve = chhend; + + delete [] s_datchh; + LHutili = false; + HHutili = false; + + std::string t_curvhhref2 = "1000A0B500C350D350E166F500G350H350I333J500K350L350M500N500O350P350Q666R500S350T350U833V500W350X350Y@"; + + if (hhstr[sp].c_str() != t_curvhhref2) { + HHutili = true; + } + + if (lhstr[sp].c_str() != t_curvhhref2) { + LHutili = true; + } + + params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve, lochhCurve, LHutili, HHutili); locallutili = false; localcutili = false; @@ -2314,7 +2457,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) params.locallab.lumaref = lumarefs[sp]; // printf("sp=%i hueres=%i\n",sp, huerefs[sp]); - ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref ); + ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref ); lllocalcurve.clear(); cclocalcurve.clear(); @@ -2326,7 +2469,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) for (int spe = 1; spe < maxspot; spe++) { int t_sp = spe; - int t_mipversion = 10007; + int t_mipversion = 10008; int t_circrad = dataspot[2][spe]; int t_locX = dataspot[3][spe]; int t_locY = dataspot[4][spe]; @@ -2393,6 +2536,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) std::string t_curvll = llstr[spe]; std::string t_curvlh = lhstr[spe]; std::string t_curvcc = ccstr[spe]; + std::string t_curvhh = hhstr[spe]; fou << "Mipversion=" << t_mipversion << '@' << endl; fou << "Spot=" << t_sp << '@' << endl; @@ -2462,6 +2606,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fou << "curveLL=" << t_curvll << endl; fou << "curveLH=" << t_curvlh << endl; fou << "curveCC=" << t_curvcc << endl; + fou << "curveHH=" << t_curvhh << endl; fou << endl; } @@ -2481,6 +2626,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) delete [] llstr; delete [] lhstr; delete [] ccstr; + delete [] hhstr; // } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 344da2590..5b3023d95 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -147,6 +147,7 @@ protected: LocretigainCurve locRETgainCurve; LocretigainCurverab locRETgainCurverab; LocLHCurve loclhCurve; + LocHHCurve lochhCurve; ColorAppearance customColCurve1; ColorAppearance customColCurve2; @@ -223,12 +224,15 @@ protected: bool wavcontlutili; bool locallutili; bool localcutili; + bool LHutili; + bool HHutili; int **dataspot; std::string *retistr; std::string *llstr; std::string *lhstr; std::string *ccstr; + std::string *hhstr; LUTi circrads; LUTi centerx; @@ -294,7 +298,9 @@ protected: LUTi llcurvs; LUTi sizellcs; LUTi lhcurvs; + LUTi hhcurvs; LUTi sizelhcs; + LUTi sizehhcs; LUTi cccurvs; LUTi sizecccs; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index e54a22f8b..1517c7255 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5812,6 +5812,9 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu float l_r;//Luminance Lab in 0..1 l_r = Lprov1 / 100.f; { + //double hr = 0.5 * ((HH / rtengine::RT_PI) + 1.); + //float valparam = float ((lhCurve->getVal (hr - 0.5f)*2));//get l_r=f(H) + float valparam = float ((lhCurve->getVal (Color::huelab_to_huehsv2 (HH)) - 0.5f)); //get l_r=f(H) float valparamneg; valparamneg = valparam; @@ -5874,7 +5877,9 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu // calculate C=f(H) if (chutili) { - double hr = Color::huelab_to_huehsv2 (HH); + double hr = Color::huelab_to_huehsv2 (HH); + //double hr = 0.5 * ((HH / rtengine::RT_PI) + 1.); + float chparam = float ((chCurve->getVal (hr) - 0.5f) * 2.0f); //get C=f(H) float chromaChfactor = 1.0f + chparam; atmp *= chromaChfactor;//apply C=f(H) @@ -5883,9 +5888,19 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu if (hhutili) { // H=f(H) //hue Lab in -PI +PI - float valparam = float ((hhCurve->getVal (Color::huelab_to_huehsv2 (HH)) - 0.5f) * 1.7f) + HH; //get H=f(H) 1.7 optimisation ! - HH = valparam; - sincosval = xsincosf (HH); + double hr = 0.5 * ((HH / rtengine::RT_PI) + 1.); + + // float valparam = float ((hhCurve->getVal (Color::huelab_to_huehsv2 (HH)) - 0.5f) * 1.7f) + hr; //get H=f(H) 1.7 optimisation ! + float valparam = float ((hhCurve->getVal (hr - 0.5f)) * 2.) + hr; + + if (valparam > 1.0f) { + valparam -= 1.0f; + } else if ( valparam < 0.0f) { + valparam += 1.0f; + } + + float v = (2.f * valparam - 1.f) * rtengine::RT_PI; + sincosval = xsincosf (v); } if (!bwToning) { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index d8d6fa7f3..f1a2fb836 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -279,7 +279,7 @@ public: //locallab void MSRLocal (float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, const LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); 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, double &huere, double &chromare, double &lumare); - void Lab_Local (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, double &hueref, double &chromaref, double &lumaref); + void Lab_Local (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, double &hueref, double &chromaref, double &lumaref); 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); @@ -294,7 +294,7 @@ public: void DeNoise_Local (int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy); - void ColorLight_Local (int call, LabImage * bufcolorig, float **buflight, float **bufchro, float ** buflightslid, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy); + void ColorLight_Local (int call, LabImage * bufcolorig, float **buflight, float **bufchro, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy); void InverseColorLight_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy); void Sharp_Local (int call, int sp, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 625418848..991e11a6e 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2770,7 +2770,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa -void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float ** buflight, float ** bufchro, float ** buflightslid, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy) +void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float ** buflight, float ** bufchro, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy) { BENCHFUN // chroma and lightness @@ -2796,6 +2796,8 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * //transition = difficult to avoid artifact with scope on flat area (sky...) constexpr float delhu = 0.1f; //between 0.05 and 0.2 ==> minima for scope + constexpr float delhuhr = 0.1f; // same + //constexpr float delhu2 = 0.03f; //between 0.05 and 0.2 const float aplus = (1.f - lp.chro) / delhu; @@ -2842,6 +2844,9 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * ImProcFunctions::secondeg_end (reducac2, vinf2, aaaa, bbbb, cccc);//parabolic ImProcFunctions::secondeg_begin (reducac2, vi2, aO, bO);//parabolic + float hueplushr = Color::huelab_to_huehsv2 (hueplus); + float huemoinshr = Color::huelab_to_huehsv2 (huemoins); + if (call <= 3) { //Todo optimization in this first part with bufcolorig and bufcoltra @@ -2910,6 +2915,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * float rchro = sqrt (SQR (original->b[y][x]) + SQR (original->a[y][x])) / 327.68f; #endif + float rhuehr = Color::huelab_to_huehsv2 (rhue); float rL = original->L[y][x] / 327.68f; float rLL = original->L[y][x] / 327.68f; @@ -2938,6 +2944,14 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * float amoinscurv = (cchro - 1.f) / delhu; float bmoinscurv = 1.f - amoinscurv * huemoins; + //HH + + float hhro = (bufhh[loy - begy][lox - begx]); + float aplushh = (1.f - hhro) / delhuhr; + float bplushh = 1.f - aplushh * hueplushr; + float amoinshh = (hhro - 1.f) / delhuhr; + float bmoinshh = 1.f - amoinshh * huemoinshr; + float clisl = (buflightslid[loy - begy][lox - begx]); //parameters for linear interpolation in function of real hue float aplusclighsl = (1.f - clisl) / delhu; @@ -2953,7 +2967,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * float realcurv = 1.f; float realcligh = 1.f; float realclighsl = 1.f; - + float realhh = 0.f; //evaluate delta Hue and delta Chro float deltachro = fabs (rchro - chromaref); @@ -2988,6 +3002,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * bool kzon = false; + //transition = difficult to avoid artifact with scope on flat area (sky...) //hue detection //for each quart calculate realchro, realcligh,... in function of Hue pixel @@ -2997,6 +3012,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = apluscurv * rhue + bpluscurv; realcligh = apluscligh * rhue + bpluscligh; realclighsl = aplusclighsl * rhue + bplusclighsl; + realhh = aplushh * rhuehr + bplushh; khu = apl * rhue + bpl; } else if (rhue < huemoins + delhu) { @@ -3004,6 +3020,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = amoinscurv * rhue + bmoinscurv; realcligh = amoinscligh * rhue + bmoinscligh; realclighsl = amoinsclighsl * rhue + bmoinsclighsl; + realhh = amoinshh * rhuehr + bmoinshh; khu = amo * rhue + bmo; @@ -3012,7 +3029,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = cchro; realcligh = cli; realclighsl = clisl; - + realhh = hhro; khu = 1.f; } @@ -3024,6 +3041,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = apluscurv * rhue + bpluscurv; realcligh = apluscligh * rhue + bpluscligh; realclighsl = aplusclighsl * rhue + bplusclighsl; + realhh = aplushh * rhuehr + bplushh; khu = apl * rhue + bpl; @@ -3032,6 +3050,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = amoinscurv * rhue + bmoinscurv; realcligh = amoinscligh * rhue + bmoinscligh; realclighsl = amoinsclighsl * rhue + bmoinsclighsl; + realhh = amoinshh * rhuehr + bmoinshh; khu = amo * rhue + bmo; @@ -3041,7 +3060,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = cchro; realcligh = cli; realclighsl = clisl; - + realhh = hhro; khu = 1.f; } @@ -3055,6 +3074,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = apluscurv * rhue + bpluscurv; realcligh = apluscligh * rhue + bpluscligh; realclighsl = aplusclighsl * rhue + bplusclighsl; + realhh = aplushh * rhuehr + bplushh; khu = apl * rhue + bpl; @@ -3063,6 +3083,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = amoinscurv * rhue + bmoinscurv; realcligh = amoinscligh * rhue + bmoinscligh; realclighsl = amoinsclighsl * rhue + bmoinsclighsl; + realhh = amoinshh * rhuehr + bmoinshh; khu = amo * rhue + bmo; @@ -3072,7 +3093,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = cchro; realcligh = cli; realclighsl = clisl; - + realhh = hhro; khu = 1.f; } @@ -3084,6 +3105,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = apluscurv * rhue + bpluscurv; realcligh = apluscligh * rhue + bpluscligh; realclighsl = aplusclighsl * rhue + bplusclighsl; + realhh = aplushh * rhuehr + bplushh; khu = apl * rhue + bpl; @@ -3092,6 +3114,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = amoinscurv * rhue + bmoinscurv; realcligh = amoinscligh * rhue + bmoinscligh; realclighsl = amoinsclighsl * rhue + bmoinsclighsl; + // realhh = amoinshh * rhuehr + bmoinshh; khu = amo * rhue + bmo; @@ -3101,7 +3124,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * realcurv = cchro; realcligh = cli; realclighsl = clisl; - + realhh = hhro; khu = 1.f; } @@ -3109,6 +3132,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * kzon = true; } + // realhh = hhro; //detection of deltaE and deltaL if (lp.sens <= 20.f) { //to try... @@ -3246,6 +3270,10 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * // float localFactor; // calcTransition (lox, loy, ach, lp, zone, localFactor); float th_r = 0.01f; + float2 sincosval; + sincosval.y = 1.f; + sincosval.x = 0.0f; + float ddhue = 0.f; if (rL > th_r) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9 switch (zone) { @@ -3261,7 +3289,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * float lightcont; - if (lp.qualcurvemet == 1) { + if (lp.qualcurvemet >= 1) { if (lllocalcurve) { float lumprov = lllocalcurve[lumnew * 1.9f]; @@ -3270,7 +3298,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * } - if (loclhCurve) { + if (loclhCurve && LHutili) { float l_r;//Luminance Lab in 0..1 l_r = lumnew / 32768.f; { @@ -3328,15 +3356,45 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * diflc *= factorx; //transition lightness transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc)); + bool toty = false; - if (fabs (kab) > 1.f) { - transformed->a[y][x] = CLIPC (original->a[y][x] * fac) ; - transformed->b[y][x] = CLIPC (original->a[y][x] * fac) / kab; + + if (lochhCurve && lp.qualcurvemet >= 1 && HHutili) { + float addh = 0.f; + float chromhr = sqrt (SQR (original->a[y][x]) + SQR (original->b[y][x])); + + if (lp.qualcurvemet == 1) { + float valparam = float ((lochhCurve[500.f * Color::huelab_to_huehsv2 (rhue)] - 0.5f)); //get H=f(H) 1.7 optimisation ! + // float hh = 0.5 * ((rhue / rtengine::RT_PI) + 1.); + // float valparam = float ((lochhCurve[500.f * hh] - 0.5f)); //get H=f(H) 1.7 optimisation ! + ddhue = 2 * valparam; + + addh = ddhue * factorx; + // float dh = (0.02f*addh - 1.f) * rtengine::RT_PI; + } + + if (lp.qualcurvemet == 2) { + addh = 0.01f * realhh * factorx; + + } + + float newhr = rhue + addh; + + if (newhr > rtengine::RT_PI) { + newhr -= 2 * rtengine::RT_PI; + } else if ( newhr < -rtengine::RT_PI) { + newhr += 2 * rtengine::RT_PI; + } + + sincosval = xsincosf (newhr); + transformed->a[y][x] = CLIPC (chromhr * sincosval.y * fac) ; + transformed->b[y][x] = CLIPC (chromhr * sincosval.x * fac); + } else { - transformed->b[y][x] = CLIPC (original->b[y][x] * fac); - transformed->a[y][x] = CLIPC (original->b[y][x] * fac) * kab ; + transformed->a[y][x] = CLIPC (original->a[y][x] * fac) ; + transformed->b[y][x] = CLIPC (original->b[y][x] * fac); } break; @@ -3346,7 +3404,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * float lumnew = bufcolorig->L[loy - begy][lox - begx]; float lightcont; - if (lp.qualcurvemet == 1) { + if (lp.qualcurvemet >= 1) { if (lllocalcurve) { float lumprov = lllocalcurve[lumnew * 1.9f]; @@ -3354,7 +3412,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * lumnew = lumnew + (lumred - lumnew) / 4.f;//reduce sensibility } - if (loclhCurve) { + if (loclhCurve && LHutili) { float l_r;//Luminance Lab in 0..1 l_r = lumnew / 32768.f; { @@ -3412,15 +3470,49 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, float * kdiff *= fach * kch; diflc *= kdiff ; transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc)); + float ka = 0.f, kb = 0.f; + float newchro = sqrt (SQR (original->a[y][x]) + SQR (original->b[y][x])); + bool toty = false; + + if (lochhCurve && lp.qualcurvemet >= 1 && HHutili) { + float addh = 0.f; + float chromhr = sqrt (SQR (original->a[y][x]) + SQR (original->b[y][x])); + + if (lp.qualcurvemet == 1) { + float valparam = float ((lochhCurve[500.f * Color::huelab_to_huehsv2 (rhue)] - 0.5f)); //get H=f(H) 1.7 optimisation ! + //float hh = 0.5 * ((rhue / rtengine::RT_PI) + 1.); + //float valparam = float ((lochhCurve[500.f * hh] - 0.5f)); //get H=f(H) 1.7 optimisation ! + + ddhue = 2 * valparam; + + addh = ddhue; + } + + if (lp.qualcurvemet == 2) { + addh = 0.01f * realhh; + + } + + float newhr = rhue + addh; + + if (newhr > rtengine::RT_PI) { + newhr -= 2 * rtengine::RT_PI; + } else if ( newhr < -rtengine::RT_PI) { + newhr += 2 * rtengine::RT_PI; + } + + sincosval = xsincosf (newhr); + transformed->a[y][x] = CLIPC (chromhr * sincosval.y * fac) ; + transformed->b[y][x] = CLIPC (chromhr * sincosval.x * fac); - if (fabs (kab) > 1.f) { - transformed->a[y][x] = CLIPC (original->a[y][x] * fac) ; - transformed->b[y][x] = CLIPC (original->a[y][x] * fac) / kab; } else { + + + transformed->a[y][x] = CLIPC (original->a[y][x] * fac) ; transformed->b[y][x] = CLIPC (original->b[y][x] * fac); - transformed->a[y][x] = CLIPC (original->b[y][x] * fac) * kab; } + } } @@ -3546,7 +3638,7 @@ void ImProcFunctions::calc_ref (int call, int sp, float** shbuffer, LabImage * o } } -void ImProcFunctions::Lab_Local (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, double & hueref, double & chromaref, double & lumaref) +void ImProcFunctions::Lab_Local (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, double & hueref, double & chromaref, double & lumaref) { //general call of others functions : important return hueref, chromaref, lumaref if (params->locallab.enabled) { @@ -4124,6 +4216,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * if (!lp.inv && (lp.chro != 0 || lp.ligh != 0.f || lp.qualcurvemet != 0) && lp.colorena) { // || lllocalcurve)) { //interior ellipse renforced lightness and chroma //locallutili float hueplus = hueref + dhue; float huemoins = hueref - dhue; + float ddhue = 0.f; //printf("hueplus=%f huemoins=%f dhu=%f\n", hueplus, huemoins, dhue); if (hueplus > rtengine::RT_PI) { @@ -4138,11 +4231,13 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * float chprov = 1.f; float chpro = 1.f; float cligh = 1.f; + float hhpro = 1.f; float clighL = 1.f; float clighmax ; float **buflight = nullptr; float **bufchro = nullptr; float **buflightslid = nullptr; + float **bufhh = nullptr; int bfh = 0.f, bfw = 0.f; @@ -4186,6 +4281,12 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * bufchro[i] = new float[bfw]; } + bufhh = new float*[bfh];//for chroma curve + + for (int i = 0; i < bfh; i++) { + bufhh[i] = new float[bfw]; + } + buflightslid = new float*[bfh];//for chroma curve for (int i = 0; i < bfh; i++) { @@ -4205,6 +4306,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * bufchro[ir][jr] = 0.f; buflightslid[ir][jr] = 0.f; buflight[ir][jr] = 0.f; + bufhh[ir][jr] = 0.f; } clighmax = 0.f; @@ -4283,6 +4385,97 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * } + bool tyty = false; + + // if(HHutili) printf("HHutili true\n"); + + if (lochhCurve && lp.qualcurvemet == 2 && HHutili) { + // printf("a"); + // if (tyty) { + float hhforcurv = xatan2f (bufcolorig->b[loy - begy][lox - begx], bufcolorig->a[loy - begy][lox - begx]); + + float valparam = float ((lochhCurve[500.f * Color::huelab_to_huehsv2 (hhforcurv)] - 0.5f)); //get H=f(H) 1.7 optimisation ! + float ddhue = CLIPRET (200.f * valparam); + + // float aa = bufcolorig->a[loy - begy][lox - begx]; + // float bb = bufcolorig->b[loy - begy][lox - begx]; + // float ll = bufcolorig->L[loy - begy][lox - begx]; + /* + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.working); + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix (params->icm.working); + + float wip[3][3] = { + {static_cast (wiprof[0][0]), static_cast (wiprof[0][1]), static_cast (wiprof[0][2])}, + {static_cast (wiprof[1][0]), static_cast (wiprof[1][1]), static_cast (wiprof[1][2])}, + {static_cast (wiprof[2][0]), static_cast (wiprof[2][1]), static_cast (wiprof[2][2])} + }; + float wp[3][3] = { + {static_cast (wprof[0][0]), static_cast (wprof[0][1]), static_cast (wprof[0][2])}, + {static_cast (wprof[1][0]), static_cast (wprof[1][1]), static_cast (wprof[1][2])}, + {static_cast (wprof[2][0]), static_cast (wprof[2][1]), static_cast (wprof[2][2])} + }; + */ + /* + float X, Y, Z; + float r, g, b; + float hh, s, v; + Color::Lab2XYZ (ll, aa, bb, X, Y, Z); + Color::xyz2rgb (X, Y, Z, r, g, b, wip); + Color::rgb2hsv (r, g, b, hh, s, v); + */ + // float hr = 0.f; // = Color::huelab_to_huehsv2 (hhforcurv); + /* + if (hhforcurv >= 0.6f && hhforcurv < rtengine::RT_PI) { + hr = hhforcurv * 0.1652507f - 0.09915f;// hr 0 0.42 + } + + if (hhforcurv >= -rtengine::RT_PI && hhforcurv < 0.6f) { + hr = hhforcurv * 0.155014f + 0.90699f; + } + + + float valparam = float ((lochhCurve[500.f * (hr)] - 0.5f)); // + hr; //get H=f(H) + */ + ////////// float hh = 0.5 * ((hhforcurv / rtengine::RT_PI) + 1.); + // float hr = Color::huelab_to_huehsv2 (hhforcurv); + + // float valparam = float ((hhCurve->getVal (Color::huelab_to_huehsv2 (HH)) - 0.5f) * 1.7f) + hr; //get H=f(H) 1.7 optimisation ! + // float valparam = float ((hhCurve->getVal (hr - 0.5f))* 2.); //get H=f(H) 1.7 optimisation ! + /////////// float valparamdh = float ((lochhCurve[500.f * (hh)] - 0.5f) * 2); // + hr; //get H=f(H) + + //float hhhh = (2 * valparamdh - 1)* rtengine::RT_PI; + /* + if (valparamdh > 1.0f) { + valparamdh -= 1.0f; + } else if ( valparamdh < 0.0f) { + valparamdh += 1.0f; + } + */ + /* + float R, G, B; + float xx, yy, zz; + Color::hsv2rgb (valparamdh, s, v, R, G, B); + Color::rgbxyz (R, G, B, xx, yy, zz, wp); + float llf, aaf, bbf; + Color::XYZ2Lab (xx, yy, zz, llf, aaf, bbf); + float hhfin = xatan2f (bbf, aaf); + float hhresult = hhfin - hhforcurv; + */ + // float dh = valparam; + + /* + if (valparam < 0.42f) { + dh = 6.051411f * valparam + 0.6f; + } else { + dh = -4.38205629f * valparam + 4.98205629f; + } + + // float dh = Color::huehsv2_to_huelab (valparam); + */ + // float hhhh = (2 * valparamdh - 1)* rtengine::RT_PI; + bufhh[loy - begy][lox - begx] = ddhue;//valparamdh; // + + } //slider lightness clighL = 0.f; @@ -4330,7 +4523,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * } - ColorLight_Local (call, bufcolorig, buflight, bufchro, buflightslid, sp, moy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, locallutili, lllocalcurve, loclhCurve, cclocalcurve, chprov, clighmax, lp, original, transformed, cx, cy); + ColorLight_Local (call, bufcolorig, buflight, bufchro, bufhh, buflightslid, LHutili, HHutili, sp, moy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, locallutili, lllocalcurve, loclhCurve, lochhCurve, cclocalcurve, chprov, clighmax, lp, original, transformed, cx, cy); if (call <= 3) { @@ -4350,6 +4543,12 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * delete [] bufchro; + for (int i = 0; i < bfh; i++) { + delete [] bufhh[i]; + } + + delete [] bufhh; + for (int i = 0; i < bfh; i++) { delete [] buflightslid[i]; } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 7e8d82c8f..f815d14db 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -572,6 +572,7 @@ enum ProcEvent { Evlocallabhueref = 542, Evlocallabchromaref = 543, Evlocallablumaref = 544, + EvlocallabHHshape = 545, NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index d5fbe7cee..f3bc3bf97 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -31,11 +31,13 @@ using namespace std; extern Options options; -namespace { +namespace +{ -void avoidEmptyCurve(std::vector &curve) { - if(curve.empty()) { - curve.push_back(FCT_Linear); +void avoidEmptyCurve (std::vector &curve) +{ + if (curve.empty()) { + curve.push_back (FCT_Linear); } } @@ -594,10 +596,10 @@ void ColorToningParams::getCurves (ColorGradientCurve &colorCurveLUT, OpacityCur } } -SharpeningParams::SharpeningParams() : enabled(false), radius(0.5), amount(200), threshold(20, 80, 2000, 1200, false), edgesonly(false), edges_radius(1.9), edges_tolerance(1800), halocontrol(false), halocontrol_amount(85), deconvamount(75), deconvradius(0.75), deconviter(30), deconvdamping(20) {}; +SharpeningParams::SharpeningParams() : enabled (false), radius (0.5), amount (200), threshold (20, 80, 2000, 1200, false), edgesonly (false), edges_radius (1.9), edges_tolerance (1800), halocontrol (false), halocontrol_amount (85), deconvamount (75), deconvradius (0.75), deconviter (30), deconvdamping (20) {}; -VibranceParams::VibranceParams() : enabled(false), pastels(0), saturated(0), psthreshold(0, 75, false), protectskins(false), avoidcolorshift(true), pastsattog(true) {}; +VibranceParams::VibranceParams() : enabled (false), pastels (0), saturated (0), psthreshold (0, 75, false), protectskins (false), avoidcolorshift (true), pastsattog (true) {}; //WaveletParams::WaveletParams (): hueskin(-5, 25, 170, 120, false), hueskin2(-260, -250, -130, -140, false), hllev(50, 75, 100, 98, false), bllev(0, 2, 50, 25, false), pastlev(0, 2, 30, 20, false), satlev(30, 45, 130, 100, false), edgcont(0, 20, 100, 75, false){ @@ -784,6 +786,7 @@ void WaveletParams::setDefaults() for (int i = 0; i < 9; i ++) { ch[i] = 0; } + greenlow = greenmed = greenhigh = 0.0; bluelow = bluemed = bluehigh = 0.0; @@ -1017,6 +1020,7 @@ void LocallabParams::setDefaults() getDefaultLLCurve (llcurve); getDefaultLHCurve (LHcurve); getDefaultCCCurve (cccurve); + getDefaultHHCurve (HHcurve); } @@ -1065,6 +1069,32 @@ void LocallabParams::getDefaultLHCurve (std::vector &curve) } +void LocallabParams::getDefaultHHCurve (std::vector &curve) +{ + + /* + double v[12] = { 0.00, 0.12, 0.35, 0.35, + 0.70, 0.50, 0.35, 0.35, + 1.00, 0.12, 0.35, 0.35, + }; + */ + double v[24] = { 0.00, 0.50, 0.35, 0.35, + 0.166, 0.50, 0.35, 0.35, + 0.333, 0.50, 0.35, 0.35, + 0.50, 0.50, 0.35, 0.35, + 0.666, 0.50, 0.35, 0.35, + 0.833, 0.50, 0.35, 0.35, + }; + + curve.resize (25); + curve.at (0 ) = double (FCT_MinMaxCPoints); + + for (size_t i = 1; i < curve.size(); ++i) { + curve.at (i) = v[i - 1]; + } + +} + void LocallabParams::getDefaultLocalgainCurveTrab (std::vector &curve) { @@ -1114,11 +1144,13 @@ void LocallabParams::getDefaultCCCurve (std::vector &curve) } -void LocallabParams::getCurves (LocretigainCurve &cTgainCurve, LocretigainCurverab &cTgainCurverab, LocLHCurve &lhCurve) const +void LocallabParams::getCurves (LocretigainCurve &cTgainCurve, LocretigainCurverab &cTgainCurverab, LocLHCurve &lhCurve, LocHHCurve &hhCurve, bool &LHutili, bool &HHutili) const { cTgainCurve.Set (this->localTgaincurve); cTgainCurverab.Set (this->localTgaincurverab); - lhCurve.Set (this->LHcurve); + lhCurve.Set (this->LHcurve, LHutili); + hhCurve.Set (this->HHcurve, HHutili); + } void RAWParams::setDefaults() @@ -2770,6 +2802,11 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_double_list ("Locallab", "LHCurve", LHcurve); } + if (!pedited || pedited->locallab.HHcurve) { + Glib::ArrayHandle HHcurve = locallab.HHcurve; + keyFile.set_double_list ("Locallab", "HHCurve", HHcurve); + } + if (!pedited || pedited->locallab.localTgaincurverab) { Glib::ArrayHandle localTgaincurverab = locallab.localTgaincurverab; keyFile.set_double_list ("Locallab", "TgainCurverab", localTgaincurverab); @@ -4462,6 +4499,14 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Locallab", "HHCurve")) { + locallab.HHcurve = keyFile.get_double_list ("Locallab", "HHCurve"); + + if (pedited) { + pedited->locallab.HHcurve = true; + } + } + if (keyFile.has_key ("Locallab", "TgainCurverab")) { locallab.localTgaincurverab = keyFile.get_double_list ("Locallab", "TgainCurverab"); @@ -4920,8 +4965,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (pedited) { pedited->locallab.rewei = true; - } - } + } + } for (int i = 0; i < 5; i ++) { std::stringstream ss; @@ -4929,8 +4974,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Locallab", ss.str())) { locallab.mult[i] = keyFile.get_integer ("Locallab", ss.str()); - } - } + } + } if (keyFile.has_key ("Locallab", "Threshold")) { @@ -4949,10 +4994,11 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) const std::vector rmix = keyFile.get_integer_list ("Channel Mixer", "Red"); const std::vector gmix = keyFile.get_integer_list ("Channel Mixer", "Green"); const std::vector bmix = keyFile.get_integer_list ("Channel Mixer", "Blue"); - if(rmix.size() == 3 && gmix.size() == 3 && bmix.size() == 3) { - memcpy (chmixer.red, rmix.data(), 3 * sizeof(int)); - memcpy (chmixer.green, gmix.data(), 3 * sizeof(int)); - memcpy (chmixer.blue, bmix.data(), 3 * sizeof(int)); + + if (rmix.size() == 3 && gmix.size() == 3 && bmix.size() == 3) { + memcpy (chmixer.red, rmix.data(), 3 * sizeof (int)); + memcpy (chmixer.green, gmix.data(), 3 * sizeof (int)); + memcpy (chmixer.blue, bmix.data(), 3 * sizeof (int)); } if (pedited) { @@ -5103,7 +5149,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Black & White", "LuminanceCurve")) { blackwhite.luminanceCurve = keyFile.get_double_list ("Black & White", "LuminanceCurve"); - avoidEmptyCurve(blackwhite.luminanceCurve); + avoidEmptyCurve (blackwhite.luminanceCurve); + if (pedited) { pedited->blackwhite.luminanceCurve = true; } @@ -5111,7 +5158,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Black & White", "BeforeCurve")) { blackwhite.beforeCurve = keyFile.get_double_list ("Black & White", "BeforeCurve"); - avoidEmptyCurve(blackwhite.beforeCurve); + avoidEmptyCurve (blackwhite.beforeCurve); + if (pedited) { pedited->blackwhite.beforeCurve = true; } @@ -5145,7 +5193,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Black & White", "AfterCurve")) { blackwhite.afterCurve = keyFile.get_double_list ("Black & White", "AfterCurve"); - avoidEmptyCurve(blackwhite.afterCurve); + avoidEmptyCurve (blackwhite.afterCurve); + if (pedited) { pedited->blackwhite.afterCurve = true; } @@ -5348,7 +5397,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Retinex", "CDCurve")) { retinex.cdcurve = keyFile.get_double_list ("Retinex", "CDCurve"); - avoidEmptyCurve(retinex.cdcurve); + avoidEmptyCurve (retinex.cdcurve); + if (pedited) { pedited->retinex.cdcurve = true; } @@ -5356,7 +5406,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Retinex", "MAPCurve")) { retinex.mapcurve = keyFile.get_double_list ("Retinex", "MAPCurve"); - avoidEmptyCurve(retinex.mapcurve); + avoidEmptyCurve (retinex.mapcurve); + if (pedited) { pedited->retinex.mapcurve = true; } @@ -5364,7 +5415,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Retinex", "CDHCurve")) { retinex.cdHcurve = keyFile.get_double_list ("Retinex", "CDHCurve"); - avoidEmptyCurve(retinex.cdHcurve); + avoidEmptyCurve (retinex.cdHcurve); + if (pedited) { pedited->retinex.cdHcurve = true; } @@ -5372,7 +5424,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Retinex", "LHCurve")) { retinex.lhcurve = keyFile.get_double_list ("Retinex", "LHCurve"); - avoidEmptyCurve(retinex.lhcurve); + avoidEmptyCurve (retinex.lhcurve); + if (pedited) { pedited->retinex.lhcurve = true; } @@ -5422,7 +5475,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Retinex", "TransmissionCurve")) { retinex.transmissionCurve = keyFile.get_double_list ("Retinex", "TransmissionCurve"); - avoidEmptyCurve(retinex.transmissionCurve); + avoidEmptyCurve (retinex.transmissionCurve); + if (pedited) { pedited->retinex.transmissionCurve = true; } @@ -5431,7 +5485,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Retinex", "GainTransmissionCurve")) { retinex.gaintransmissionCurve = keyFile.get_double_list ("Retinex", "GainTransmissionCurve"); - avoidEmptyCurve(retinex.gaintransmissionCurve); + avoidEmptyCurve (retinex.gaintransmissionCurve); + if (pedited) { pedited->retinex.gaintransmissionCurve = true; } @@ -5531,7 +5586,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "LCurve")) { labCurve.lcurve = keyFile.get_double_list ("Luminance Curve", "LCurve"); - avoidEmptyCurve(labCurve.lcurve); + avoidEmptyCurve (labCurve.lcurve); + if (pedited) { pedited->labCurve.lcurve = true; } @@ -5539,7 +5595,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "aCurve")) { labCurve.acurve = keyFile.get_double_list ("Luminance Curve", "aCurve"); - avoidEmptyCurve(labCurve.acurve); + avoidEmptyCurve (labCurve.acurve); + if (pedited) { pedited->labCurve.acurve = true; } @@ -5547,7 +5604,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "bCurve")) { labCurve.bcurve = keyFile.get_double_list ("Luminance Curve", "bCurve"); - avoidEmptyCurve(labCurve.bcurve); + avoidEmptyCurve (labCurve.bcurve); + if (pedited) { pedited->labCurve.bcurve = true; } @@ -5555,7 +5613,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "ccCurve")) { labCurve.cccurve = keyFile.get_double_list ("Luminance Curve", "ccCurve"); - avoidEmptyCurve(labCurve.cccurve); + avoidEmptyCurve (labCurve.cccurve); + if (pedited) { pedited->labCurve.cccurve = true; } @@ -5563,7 +5622,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "chCurve")) { labCurve.chcurve = keyFile.get_double_list ("Luminance Curve", "chCurve"); - avoidEmptyCurve(labCurve.chcurve); + avoidEmptyCurve (labCurve.chcurve); + if (pedited) { pedited->labCurve.chcurve = true; } @@ -5571,7 +5631,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "lhCurve")) { labCurve.lhcurve = keyFile.get_double_list ("Luminance Curve", "lhCurve"); - avoidEmptyCurve(labCurve.lhcurve); + avoidEmptyCurve (labCurve.lhcurve); + if (pedited) { pedited->labCurve.lhcurve = true; } @@ -5579,7 +5640,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "hhCurve")) { labCurve.hhcurve = keyFile.get_double_list ("Luminance Curve", "hhCurve"); - avoidEmptyCurve(labCurve.hhcurve); + avoidEmptyCurve (labCurve.hhcurve); + if (pedited) { pedited->labCurve.hhcurve = true; } @@ -5587,7 +5649,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "LcCurve")) { labCurve.lccurve = keyFile.get_double_list ("Luminance Curve", "LcCurve"); - avoidEmptyCurve(labCurve.lccurve); + avoidEmptyCurve (labCurve.lccurve); + if (pedited) { pedited->labCurve.lccurve = true; } @@ -5595,7 +5658,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Luminance Curve", "ClCurve")) { labCurve.clcurve = keyFile.get_double_list ("Luminance Curve", "ClCurve"); - avoidEmptyCurve(labCurve.clcurve); + avoidEmptyCurve (labCurve.clcurve); + if (pedited) { pedited->labCurve.clcurve = true; } @@ -5635,8 +5699,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) sharpening.threshold.setValues (thresh, thresh, 2000, 2000); // TODO: 2000 is the maximum value and is taken of rtgui/sharpening.cc ; should be changed by the tool modularization } else { const std::vector thresh = keyFile.get_integer_list ("Sharpening", "Threshold"); - if(thresh.size() >= 4) { - sharpening.threshold.setValues(thresh[0], thresh[1], min(thresh[2], 2000), min(thresh[3], 2000)); + + if (thresh.size() >= 4) { + sharpening.threshold.setValues (thresh[0], thresh[1], min (thresh[2], 2000), min (thresh[3], 2000)); } } @@ -5828,8 +5893,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) vibrance.psthreshold.setValues (thresh, thresh); } else { const std::vector thresh = keyFile.get_integer_list ("Vibrance", "PSThreshold"); - if(thresh.size() >= 2 ) { - vibrance.psthreshold.setValues(thresh[0], thresh[1]); + + if (thresh.size() >= 2 ) { + vibrance.psthreshold.setValues (thresh[0], thresh[1]); } } @@ -5864,7 +5930,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Vibrance", "SkinTonesCurve")) { vibrance.skintonescurve = keyFile.get_double_list ("Vibrance", "SkinTonesCurve"); - avoidEmptyCurve(vibrance.skintonescurve); + avoidEmptyCurve (vibrance.skintonescurve); + if (pedited) { pedited->vibrance.skintonescurve = true; } @@ -5967,7 +6034,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Defringing", "HueCurve")) { defringe.huecurve = keyFile.get_double_list ("Defringing", "HueCurve"); - avoidEmptyCurve(defringe.huecurve); + avoidEmptyCurve (defringe.huecurve); + if (pedited) { pedited->defringe.huecurve = true; } @@ -6210,7 +6278,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (ppVersion > 200) { if (keyFile.has_key ("Color appearance", "Curve")) { colorappearance.curve = keyFile.get_double_list ("Color appearance", "Curve"); - avoidEmptyCurve(colorappearance.curve); + avoidEmptyCurve (colorappearance.curve); + if (pedited) { pedited->colorappearance.curve = true; } @@ -6218,7 +6287,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Color appearance", "Curve2")) { colorappearance.curve2 = keyFile.get_double_list ("Color appearance", "Curve2"); - avoidEmptyCurve(colorappearance.curve2); + avoidEmptyCurve (colorappearance.curve2); + if (pedited) { pedited->colorappearance.curve2 = true; } @@ -6226,7 +6296,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Color appearance", "Curve3")) { colorappearance.curve3 = keyFile.get_double_list ("Color appearance", "Curve3"); - avoidEmptyCurve(colorappearance.curve3); + avoidEmptyCurve (colorappearance.curve3); + if (pedited) { pedited->colorappearance.curve3 = true; } @@ -6380,7 +6451,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Directional Pyramid Denoising", "LCurve")) { dirpyrDenoise.lcurve = keyFile.get_double_list ("Directional Pyramid Denoising", "LCurve"); - avoidEmptyCurve(dirpyrDenoise.lcurve); + avoidEmptyCurve (dirpyrDenoise.lcurve); + if (pedited) { pedited->dirpyrDenoise.lcurve = true; } @@ -6388,7 +6460,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Directional Pyramid Denoising", "CCCurve")) { dirpyrDenoise.cccurve = keyFile.get_double_list ("Directional Pyramid Denoising", "CCCurve"); - avoidEmptyCurve(dirpyrDenoise.cccurve); + avoidEmptyCurve (dirpyrDenoise.cccurve); + if (pedited) { pedited->dirpyrDenoise.cccurve = true; } @@ -7000,8 +7073,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) prsharpening.threshold.setValues (thresh, thresh, 2000, 2000); // TODO: 2000 is the maximum value and is taken of rtgui/sharpening.cc ; should be changed by the tool modularization } else { const std::vector thresh = keyFile.get_integer_list ("PostResizeSharpening", "Threshold"); - if(thresh.size() >= 4) { - prsharpening.threshold.setValues(thresh[0], thresh[1], min(thresh[2], 2000), min(thresh[3], 2000)); + + if (thresh.size() >= 4) { + prsharpening.threshold.setValues (thresh[0], thresh[1], min (thresh[2], 2000), min (thresh[3], 2000)); } } @@ -7655,7 +7729,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "ContrastCurve")) { wavelet.ccwcurve = keyFile.get_double_list ("Wavelet", "ContrastCurve"); - avoidEmptyCurve(wavelet.ccwcurve); + avoidEmptyCurve (wavelet.ccwcurve); + if (pedited) { pedited->wavelet.ccwcurve = true; } @@ -7663,7 +7738,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "OpacityCurveRG")) { wavelet.opacityCurveRG = keyFile.get_double_list ("Wavelet", "OpacityCurveRG"); - avoidEmptyCurve(wavelet.opacityCurveRG); + avoidEmptyCurve (wavelet.opacityCurveRG); + if (pedited) { pedited->wavelet.opacityCurveRG = true; } @@ -7671,7 +7747,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "OpacityCurveBY")) { wavelet.opacityCurveBY = keyFile.get_double_list ("Wavelet", "OpacityCurveBY"); - avoidEmptyCurve(wavelet.opacityCurveBY); + avoidEmptyCurve (wavelet.opacityCurveBY); + if (pedited) { pedited->wavelet.opacityCurveBY = true; } @@ -7679,7 +7756,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "OpacityCurveW")) { wavelet.opacityCurveW = keyFile.get_double_list ("Wavelet", "OpacityCurveW"); - avoidEmptyCurve(wavelet.opacityCurveW); + avoidEmptyCurve (wavelet.opacityCurveW); + if (pedited) { pedited->wavelet.opacityCurveW = true; } @@ -7687,7 +7765,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "OpacityCurveWL")) { wavelet.opacityCurveWL = keyFile.get_double_list ("Wavelet", "OpacityCurveWL"); - avoidEmptyCurve(wavelet.opacityCurveWL); + avoidEmptyCurve (wavelet.opacityCurveWL); + if (pedited) { pedited->wavelet.opacityCurveWL = true; } @@ -7695,7 +7774,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "HHcurve")) { wavelet.hhcurve = keyFile.get_double_list ("Wavelet", "HHcurve"); - avoidEmptyCurve(wavelet.hhcurve); + avoidEmptyCurve (wavelet.hhcurve); + if (pedited) { pedited->wavelet.hhcurve = true; } @@ -7703,7 +7783,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "CHcurve")) { wavelet.Chcurve = keyFile.get_double_list ("Wavelet", "CHcurve"); - avoidEmptyCurve(wavelet.Chcurve); + avoidEmptyCurve (wavelet.Chcurve); + if (pedited) { pedited->wavelet.Chcurve = true; } @@ -7711,7 +7792,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "WavclCurve")) { wavelet.wavclCurve = keyFile.get_double_list ("Wavelet", "WavclCurve"); - avoidEmptyCurve(wavelet.wavclCurve); + avoidEmptyCurve (wavelet.wavclCurve); + if (pedited) { pedited->wavelet.wavclCurve = true; } @@ -7719,8 +7801,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Hueskin")) { const std::vector thresh = keyFile.get_integer_list ("Wavelet", "Hueskin"); - if(thresh.size() >= 4) { - wavelet.hueskin.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + wavelet.hueskin.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -7730,8 +7813,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "HueRange")) { const std::vector thresh = keyFile.get_integer_list ("Wavelet", "HueRange"); - if(thresh.size() >= 4) { - wavelet.hueskin2.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + wavelet.hueskin2.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -7741,8 +7825,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "HLRange")) { const std::vector thresh = keyFile.get_integer_list ("Wavelet", "HLRange"); - if(thresh.size() >= 4) { - wavelet.hllev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + wavelet.hllev.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -7752,8 +7837,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "SHRange")) { const std::vector thresh = keyFile.get_integer_list ("Wavelet", "SHRange"); - if(thresh.size() >= 4) { - wavelet.bllev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + wavelet.bllev.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -7763,8 +7849,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Edgcont")) { const std::vector thresh = keyFile.get_integer_list ("Wavelet", "Edgcont"); - if(thresh.size() >= 4) { - wavelet.edgcont.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + wavelet.edgcont.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -7774,8 +7861,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Level0noise")) { const std::vector thresh = keyFile.get_double_list ("Wavelet", "Level0noise"); - if(thresh.size() >= 2) { - wavelet.level0noise.setValues(thresh[0], thresh[1]); + + if (thresh.size() >= 2) { + wavelet.level0noise.setValues (thresh[0], thresh[1]); } if (pedited) { @@ -7785,8 +7873,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Level1noise")) { const std::vector thresh = keyFile.get_double_list ("Wavelet", "Level1noise"); - if(thresh.size() >= 2) { - wavelet.level1noise.setValues(thresh[0], thresh[1]); + + if (thresh.size() >= 2) { + wavelet.level1noise.setValues (thresh[0], thresh[1]); } if (pedited) { @@ -7796,8 +7885,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Level2noise")) { const std::vector thresh = keyFile.get_double_list ("Wavelet", "Level2noise"); - if(thresh.size() >= 2) { - wavelet.level2noise.setValues(thresh[0], thresh[1]); + + if (thresh.size() >= 2) { + wavelet.level2noise.setValues (thresh[0], thresh[1]); } if (pedited) { @@ -7807,8 +7897,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Level3noise")) { const std::vector thresh = keyFile.get_double_list ("Wavelet", "Level3noise"); - if(thresh.size() >= 2) { - wavelet.level3noise.setValues(thresh[0], thresh[1]); + + if (thresh.size() >= 2) { + wavelet.level3noise.setValues (thresh[0], thresh[1]); } if (pedited) { @@ -7819,8 +7910,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Pastlev")) { const std::vector thresh = keyFile.get_integer_list ("Wavelet", "Pastlev"); - if(thresh.size() >= 4) { - wavelet.pastlev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + wavelet.pastlev.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -7830,8 +7922,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("Wavelet", "Satlev")) { const std::vector thresh = keyFile.get_integer_list ("Wavelet", "Satlev"); - if(thresh.size() >= 4) { - wavelet.satlev.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + wavelet.satlev.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -7964,8 +8057,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) // if (keyFile.has_key ("Directional Pyramid Equalizer", "Algorithm")) { dirpyrequalizer.algo = keyFile.get_string ("Directional Pyramid Equalizer", "Algorithm"); if (pedited) pedited->dirpyrequalizer.algo = true; } if (keyFile.has_key ("Directional Pyramid Equalizer", "Hueskin")) { const std::vector thresh = keyFile.get_integer_list ("Directional Pyramid Equalizer", "Hueskin"); - if(thresh.size() >= 4) { - dirpyrequalizer.hueskin.setValues(thresh[0], thresh[1], min(thresh[2], 300), min(thresh[3], 300)); + + if (thresh.size() >= 4) { + dirpyrequalizer.hueskin.setValues (thresh[0], thresh[1], min (thresh[2], 300), min (thresh[3], 300)); } if (pedited) { @@ -8065,7 +8159,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (ppVersion >= 300) { if (keyFile.has_key ("HSV Equalizer", "HCurve")) { hsvequalizer.hcurve = keyFile.get_double_list ("HSV Equalizer", "HCurve"); - avoidEmptyCurve(hsvequalizer.hcurve); + avoidEmptyCurve (hsvequalizer.hcurve); + if (pedited) { pedited->hsvequalizer.hcurve = true; } @@ -8073,7 +8168,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("HSV Equalizer", "SCurve")) { hsvequalizer.scurve = keyFile.get_double_list ("HSV Equalizer", "SCurve"); - avoidEmptyCurve(hsvequalizer.scurve); + avoidEmptyCurve (hsvequalizer.scurve); + if (pedited) { pedited->hsvequalizer.scurve = true; } @@ -8081,7 +8177,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("HSV Equalizer", "VCurve")) { hsvequalizer.vcurve = keyFile.get_double_list ("HSV Equalizer", "VCurve"); - avoidEmptyCurve(hsvequalizer.vcurve); + avoidEmptyCurve (hsvequalizer.vcurve); + if (pedited) { pedited->hsvequalizer.vcurve = true; } @@ -8101,7 +8198,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("RGB Curves", "rCurve")) { rgbCurves.rcurve = keyFile.get_double_list ("RGB Curves", "rCurve"); - avoidEmptyCurve(rgbCurves.rcurve); + avoidEmptyCurve (rgbCurves.rcurve); + if (pedited) { pedited->rgbCurves.rcurve = true; } @@ -8109,7 +8207,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("RGB Curves", "gCurve")) { rgbCurves.gcurve = keyFile.get_double_list ("RGB Curves", "gCurve"); - avoidEmptyCurve(rgbCurves.gcurve); + avoidEmptyCurve (rgbCurves.gcurve); + if (pedited) { pedited->rgbCurves.gcurve = true; } @@ -8117,7 +8216,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("RGB Curves", "bCurve")) { rgbCurves.bcurve = keyFile.get_double_list ("RGB Curves", "bCurve"); - avoidEmptyCurve(rgbCurves.bcurve); + avoidEmptyCurve (rgbCurves.bcurve); + if (pedited) { pedited->rgbCurves.bcurve = true; } @@ -8160,7 +8260,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("ColorToning", "OpacityCurve")) { colorToning.opacityCurve = keyFile.get_double_list ("ColorToning", "OpacityCurve"); - avoidEmptyCurve(colorToning.opacityCurve); + avoidEmptyCurve (colorToning.opacityCurve); + if (pedited) { pedited->colorToning.opacityCurve = true; } @@ -8168,7 +8269,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("ColorToning", "ColorCurve")) { colorToning.colorCurve = keyFile.get_double_list ("ColorToning", "ColorCurve"); - avoidEmptyCurve(colorToning.colorCurve); + avoidEmptyCurve (colorToning.colorCurve); + if (pedited) { pedited->colorToning.colorCurve = true; } @@ -8208,8 +8310,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("ColorToning", "HighlightsColorSaturation")) { const std::vector thresh = keyFile.get_integer_list ("ColorToning", "HighlightsColorSaturation"); - if(thresh.size() >= 2) { - colorToning.hlColSat.setValues(thresh[0], thresh[1]); + + if (thresh.size() >= 2) { + colorToning.hlColSat.setValues (thresh[0], thresh[1]); } if (pedited) { @@ -8219,8 +8322,9 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("ColorToning", "ShadowsColorSaturation")) { const std::vector thresh = keyFile.get_integer_list ("ColorToning", "ShadowsColorSaturation"); - if(thresh.size() >= 2) { - colorToning.shadowsColSat.setValues(thresh[0], thresh[1]); + + if (thresh.size() >= 2) { + colorToning.shadowsColSat.setValues (thresh[0], thresh[1]); } if (pedited) { @@ -8230,7 +8334,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("ColorToning", "ClCurve")) { colorToning.clcurve = keyFile.get_double_list ("ColorToning", "ClCurve"); - avoidEmptyCurve(colorToning.clcurve); + avoidEmptyCurve (colorToning.clcurve); + if (pedited) { pedited->colorToning.clcurve = true; } @@ -8238,7 +8343,8 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) if (keyFile.has_key ("ColorToning", "Cl2Curve")) { colorToning.cl2curve = keyFile.get_double_list ("ColorToning", "Cl2Curve"); - avoidEmptyCurve(colorToning.cl2curve); + avoidEmptyCurve (colorToning.cl2curve); + if (pedited) { pedited->colorToning.cl2curve = true; } @@ -9405,6 +9511,7 @@ bool ProcParams::operator== (const ProcParams& other) && locallab.llcurve == other.locallab.llcurve && locallab.cccurve == other.locallab.cccurve && locallab.LHcurve == other.locallab.LHcurve + && locallab.HHcurve == other.locallab.HHcurve && pcvignette.enabled == other.pcvignette.enabled && pcvignette.strength == other.pcvignette.strength && pcvignette.feather == other.pcvignette.feather @@ -9667,13 +9774,13 @@ PartialProfile::PartialProfile (bool createInstance, bool paramsEditedValue) PartialProfile::PartialProfile (ProcParams* pp, ParamsEdited* pe, bool fullCopy) { if (fullCopy && pp) { - pparams = new ProcParams(*pp); + pparams = new ProcParams (*pp); } else { pparams = pp; } if (fullCopy && pe) { - pedited = new ParamsEdited(*pe); + pedited = new ParamsEdited (*pe); } else { pedited = pe; } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index a007fc6ca..12696f5f0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -48,6 +48,7 @@ class RetinexgaintransmissionCurve; class LocretigainCurve; class LocretigainCurverab; class LocLHCurve; +class LocHHCurve; enum RenderingIntent { @@ -937,6 +938,7 @@ public: std::vector llcurve; std::vector cccurve; std::vector LHcurve; + std::vector HHcurve; double mult[5]; double threshold; @@ -946,12 +948,13 @@ public: setDefaults(); } void setDefaults(); - void getCurves (LocretigainCurve &cTgainCurve, LocretigainCurverab &cTgainCurverab, LocLHCurve & lhCurve) const; + void getCurves (LocretigainCurve &cTgainCurve, LocretigainCurverab &cTgainCurverab, LocLHCurve & lhCurve, LocHHCurve & hhCurve, bool &LHutili, bool &HHutili) const; static void getDefaultLocalgainCurveT (std::vector &curve); static void getDefaultLocalgainCurveTrab (std::vector &curve); static void getDefaultLLCurve (std::vector &curve); static void getDefaultLHCurve (std::vector &curve); static void getDefaultCCCurve (std::vector &curve); + static void getDefaultHHCurve (std::vector &curve); }; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index d593e3125..b047a9b8e 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -571,6 +571,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvlocallabqualitycurveMethod LUMINANCECURVE, // Evlocallabhueref LUMINANCECURVE, // Evlocallabchromaref - LUMINANCECURVE // Evlocallablumaref + LUMINANCECURVE, // Evlocallablumaref + LUMINANCECURVE // EvlocallabHHshape + }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 0874ea482..d56bfe6f8 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -315,8 +315,8 @@ class localListener { public : virtual ~localListener() {} - virtual void localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat) {} - virtual void localretChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat) {} + virtual void localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, int sp, int maxdat) {} + virtual void localretChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, int sp, int maxdat) {} }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1c380fab0..4350b6592 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -744,7 +744,7 @@ private: { procparams::ProcParams& params = job->pparams; //ImProcFunctions ipf (¶ms, true); - ImProcFunctions &ipf = *(ipf_p.get()); + ImProcFunctions &ipf = * (ipf_p.get()); // perform luma/chroma denoise // CieImage *cieView; @@ -809,7 +809,7 @@ private: { procparams::ProcParams& params = job->pparams; //ImProcFunctions ipf (¶ms, true); - ImProcFunctions &ipf = *(ipf_p.get()); + ImProcFunctions &ipf = * (ipf_p.get()); imgsrc->convertColorSpace (baseImg, params.icm, currWB); @@ -834,7 +834,7 @@ private: { procparams::ProcParams& params = job->pparams; //ImProcFunctions ipf (¶ms, true); - ImProcFunctions &ipf = *(ipf_p.get()); + ImProcFunctions &ipf = * (ipf_p.get()); if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = baseImg->getWidth(); @@ -1040,6 +1040,7 @@ private: LocretigainCurve locRETgainCurve; LocLHCurve loclhCurve; + LocHHCurve lochhCurve; LocretigainCurverab locRETgainCurverab; LUTf lllocalcurve (65536, 0); @@ -1114,6 +1115,9 @@ private: std::string *ccstrs; ccstrs = new std::string[maxspot]; + std::string *hhstrs; + hhstrs = new std::string[maxspot]; + { dataspots[2][0] = params.locallab.circrad; dataspots[3][0] = params.locallab.locX; @@ -1325,12 +1329,33 @@ private: std::string lh_str = ""; - for (int j = 0; j < sizl; j++) { + for (int j = 0; j < sizh; j++) { lh_str = lh_str + std::to_string (s_datcurh[j]) + delim[j]; } lhstrs[0] = lh_str + "@"; + int sizhh = params.locallab.HHcurve.size(); + + if (sizhh > 69) { + sizhh = 69; + } + + // int s_curh[sizh + 1]; + int s_datcurhh[sizhh + 1]; + + for (int j = 0; j < sizhh; j++) { + s_datcurhh[j] = (int) (1000. * params.locallab.HHcurve[j]); + } + + std::string hh_str = ""; + + for (int j = 0; j < sizhh; j++) { + hh_str = hh_str + std::to_string (s_datcurhh[j]) + delim[j]; + } + + hhstrs[0] = hh_str + "@"; + } // locallutili = false; @@ -1436,6 +1461,23 @@ private: // sizelh = longeh; } + if (spotline.substr (0, pos) == "curveHH") { + std::string cursthh; + // int longecurh; + std::string strendhh = spotline.substr (posend - 1, 1); + // std::size_t poszh = spotline.find (strendh); + // int longeh; + + for (int sh = 0; sh < 69; sh++) { + if (delim[sh] == strendhh) { + // longeh = sh + 1; + } + } + + hhstrs[ns] = str3; + // sizelh = longeh; + } + if (spotline.substr (0, pos) == "curveCC") { std::string curstrc; // int longecurc; @@ -1648,20 +1690,45 @@ private: clhend.push_back ((double) (s_datch[j]) / 1000.); } + int *s_datchh; + s_datchh = new int[70]; + int sizhh; + + ipf.strcurv_data (hhstrs[sp], s_datchh, sizhh); + + + std::vector chhend; + + for (int j = 0; j < sizhh; j++) { + chhend.push_back ((double) (s_datchh[j]) / 1000.); + } params.locallab.localTgaincurve.clear(); params.locallab.llcurve.clear(); params.locallab.LHcurve.clear(); params.locallab.cccurve.clear(); + params.locallab.HHcurve.clear(); params.locallab.localTgaincurve = cretiend; params.locallab.llcurve = cllend; params.locallab.LHcurve = clhend; params.locallab.cccurve = cccend; + params.locallab.HHcurve = chhend; + + bool LHutili = false; + bool HHutili = false; + std::string t_curvhhref = "1000A0B500C350D350E166F500G350H350I333J500K350L350M500N500O350P350Q666R500S350T350U833V500W350X350Y@"; + + if (lhstrs[sp].c_str() != t_curvhhref) { + LHutili = true; + } + + if (hhstrs[sp].c_str() != t_curvhhref) { + HHutili = true; + } - - params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve); + params.locallab.getCurves (locRETgainCurve, locRETgainCurverab, loclhCurve, lochhCurve, LHutili, HHutili); bool locallutili = false; bool localcutili = false; @@ -1674,7 +1741,7 @@ private: params.locallab.chromaref = chromare; params.locallab.lumaref = lumare; - ipf.Lab_Local (2, sp, (float**)shbuffer, labView, labView, 0, 0, 0, 0, fw, fh, fw, fh, locutili, 1, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); + ipf.Lab_Local (2, sp, (float**)shbuffer, labView, labView, 0, 0, 0, 0, fw, fh, fw, fh, locutili, 1, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); lllocalcurve.clear(); cclocalcurve.clear(); @@ -1695,6 +1762,7 @@ private: delete [] llstrs; delete [] lhstrs; delete [] ccstrs; + delete [] hhstrs; if (params.locallab.inverssha) { @@ -2062,7 +2130,7 @@ private: { procparams::ProcParams& params = job->pparams; //ImProcFunctions ipf (¶ms, true); - ImProcFunctions &ipf = *(ipf_p.get()); + ImProcFunctions &ipf = * (ipf_p.get()); int imw, imh; double scale_factor = ipf.resizeScale (¶ms, fw, fh, imw, imh); @@ -2098,7 +2166,7 @@ private: tmplab = std::move (resized); } - adjust_procparams(scale_factor); + adjust_procparams (scale_factor); fw = imw; fh = imh; @@ -2133,21 +2201,27 @@ private: params.dirpyrDenoise.luma *= scale_factor; //params.dirpyrDenoise.Ldetail += (100 - params.dirpyrDenoise.Ldetail) * scale_factor; auto &lcurve = params.dirpyrDenoise.lcurve; + for (size_t i = 2; i < lcurve.size(); i += 4) { - lcurve[i] *= min(scale_factor * 2, 1.0); + lcurve[i] *= min (scale_factor * 2, 1.0); } - noiseLCurve.Set(lcurve); + + noiseLCurve.Set (lcurve); const char *medmethods[] = { "soft", "33", "55soft", "55", "77", "99" }; + if (params.dirpyrDenoise.median) { auto &key = params.dirpyrDenoise.methodmed == "RGB" ? params.dirpyrDenoise.rgbmethod : params.dirpyrDenoise.medmethod; - for (int i = 1; i < int(sizeof(medmethods)/sizeof(const char *)); ++i) { + + for (int i = 1; i < int (sizeof (medmethods) / sizeof (const char *)); ++i) { if (key == medmethods[i]) { - int j = i - int(1.0 / scale_factor); + int j = i - int (1.0 / scale_factor); + if (j < 0) { params.dirpyrDenoise.median = false; } else { key = medmethods[j]; } + break; } } @@ -2162,6 +2236,7 @@ private: adjust_radius (defaultparams.dirpyrequalizer.mult[i], dirpyreq_scale, params.dirpyrequalizer.mult[i]); } + params.dirpyrequalizer.threshold *= scale_factor; adjust_radius (defaultparams.defringe.radius, scale_factor, @@ -2175,6 +2250,7 @@ private: procparams::RAWParams::XTransSensor::methodstring[ procparams::RAWParams::XTransSensor::onePass]; } + if (params.raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::pixelshift]) { params.raw.bayersensor.method = procparams::RAWParams::BayerSensor::methodstring[params.raw.bayersensor.pixelShiftLmmse ? procparams::RAWParams::BayerSensor::lmmse : procparams::RAWParams::BayerSensor::amaze]; } @@ -2290,8 +2366,9 @@ void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bo void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) { - if (bpl) - Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl, tunnelMetaData), 0, true, true, Glib::THREAD_PRIORITY_LOW); + if (bpl) { + Glib::Thread::create (sigc::bind (sigc::ptr_fun (batchProcessingThread), job, bpl, tunnelMetaData), 0, true, true, Glib::THREAD_PRIORITY_LOW); + } } diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 6e863b2e7..3973001af 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -249,6 +249,7 @@ Locallab::Locallab (): std::vector defaultCurve2rab; std::vector defaultCurve3; std::vector defaultCurve4; + std::vector defaultCurve5; irg = Gtk::manage (new RTImage ("Chanmixer-RG.png")); @@ -300,6 +301,26 @@ Locallab::Locallab (): LHshape->setBottomBarBgGradient (milestones); + rtengine::LocallabParams::getDefaultHHCurve (defaultCurve5); + + HHshape = static_cast (llCurveEditorG->addCurve (CT_Flat, "H(H)", nullptr, false, true)); + + HHshape->setIdentityValue (0.); + HHshape->setResetCurve (FlatCurveType (defaultCurve5.at (0)), defaultCurve5); + HHshape->setTooltip (M ("TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP")); + HHshape->setCurveColorProvider (this, 1); + milestones.clear(); + + for (int i = 0; i < 7; i++) { + float R, G, B; + float x = float (i) * (1.0f / 6.0); + + Color::hsv2rgb01 (x, 0.5f, 0.5f, R, G, B); + milestones.push_back ( GradientMilestone (double (x), double (R), double (G), double (B)) ); + } + + HHshape->setBottomBarBgGradient (milestones); + llCurveEditorG->curveListComplete(); @@ -1180,6 +1201,20 @@ bool Locallab::localretComputed_ () LHshape->setCurve (clh); + int *s_datchh; + s_datchh = new int[70]; + int sizhh; + ImProcFunctions::strcurv_data (nexthh_str2, s_datchh, sizhh); + std::vector chh; + + for (int j = 0; j < sizhh; j++) { + chh.push_back ((double) (s_datchh[j]) / 1000.); + } + + delete [] s_datchh; + + HHshape->setCurve (chh); + enableListener (); //update all sliders by this strange process! @@ -1250,6 +1285,10 @@ bool Locallab::localretComputed_ () listener->panelChanged (EvlocallabLHshape, M ("")); } + if (listener) {//for curve + listener->panelChanged (EvlocallabHHshape, M ("")); + } + return false; } @@ -1472,6 +1511,22 @@ bool Locallab::localComputed_ () delete [] s_datch; LHshape->setCurve (clh); + //HHcurv + int *s_datchh; + s_datchh = new int[70]; + int sizhh; + ImProcFunctions::strcurv_data (nexthh_str, s_datchh, sizhh); + + + std::vector chh; + + for (int j = 0; j < sizhh; j++) { + chh.push_back ((double) (s_datchh[j]) / 1000.); + } + + delete [] s_datchh; + HHshape->setCurve (chh); + // usleep(10000); @@ -1586,10 +1641,14 @@ bool Locallab::localComputed_ () listener->panelChanged (Evlocallabccshape, M ("")); } + if (listener) {//for curve LH + listener->panelChanged (EvlocallabHHshape, M ("")); + } + return false; } -void Locallab::localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat) +void Locallab::localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, int sp, int maxdat) { for (int i = 2; i < 61; i++) { nextdatasp[i] = datasp[i][sp]; @@ -1599,18 +1658,20 @@ void Locallab::localChanged (int **datasp, std::string datastr, std::string ll_ nextll_str = ll_str; nextlh_str = lh_str; nextcc_str = cc_str; + nexthh_str = hh_str; nextlength = maxdat; g_idle_add (localChangedUI, this); } -void Locallab::localretChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat) +void Locallab::localretChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, int sp, int maxdat) { nextlength = maxdat; nextstr2 = datastr; nextll_str2 = ll_str; nextlh_str2 = lh_str; nextcc_str2 = cc_str; + nexthh_str2 = hh_str; g_idle_add (localretChangedUI, this); } @@ -1698,6 +1759,7 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) llshape->setUnChanged (!pedited->locallab.llcurve); ccshape->setUnChanged (!pedited->locallab.cccurve); LHshape->setUnChanged (!pedited->locallab.LHcurve); + HHshape->setUnChanged (!pedited->locallab.HHcurve); inversret->set_inconsistent (multiImage && !pedited->locallab.inversret); cTgainshaperab->setUnChanged (!pedited->locallab.localTgaincurverab); expcolor->set_inconsistent (!pedited->locallab.expcolor); @@ -1801,6 +1863,7 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) llshape->setCurve (pp->locallab.llcurve); ccshape->setCurve (pp->locallab.cccurve); LHshape->setCurve (pp->locallab.LHcurve); + HHshape->setCurve (pp->locallab.HHcurve); lastactivlum = pp->locallab.activlum; lastanbspot = pp->locallab.anbspot; noiselumf->setValue (pp->locallab.noiselumf); @@ -2187,6 +2250,7 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) pp->locallab.llcurve = llshape->getCurve (); pp->locallab.cccurve = ccshape->getCurve (); pp->locallab.LHcurve = LHshape->getCurve (); + pp->locallab.HHcurve = HHshape->getCurve (); pp->locallab.expcolor = expcolor->getEnabled(); pp->locallab.expblur = expblur->getEnabled(); pp->locallab.exptonemap = exptonemap->getEnabled(); @@ -2265,6 +2329,7 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) pedited->locallab.llcurve = !llshape->isUnChanged (); pedited->locallab.cccurve = !ccshape->isUnChanged (); pedited->locallab.LHcurve = !LHshape->isUnChanged (); + pedited->locallab.HHcurve = !HHshape->isUnChanged (); pedited->locallab.expcolor = !expcolor->get_inconsistent(); pedited->locallab.expblur = !expblur->get_inconsistent(); pedited->locallab.exptonemap = !exptonemap->get_inconsistent(); @@ -2366,6 +2431,14 @@ void Locallab::curveChanged (CurveEditor* ce) retrab->setValue (strval); adjusterChanged (retrab, strval); + } else if (ce == HHshape) { + listener->panelChanged (EvlocallabHHshape, M ("")); + int strval = retrab->getValue(); + //update MIP + retrab->setValue (strval + 1); + adjusterChanged (retrab, strval + 1); + usleep (10000); //to test + retrab->setValue (strval); } else if (ce == llshape) { diff --git a/rtgui/locallab.h b/rtgui/locallab.h index af8523839..35fcff114 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -151,6 +151,7 @@ private: DiagonalCurveEditor* ccshape; Gtk::Image* irg; FlatCurveEditor* LHshape; + FlatCurveEditor* HHshape; @@ -179,6 +180,8 @@ private: std::string nextlh_str2; std::string nextcc_str; std::string nextcc_str2; + std::string nexthh_str; + std::string nexthh_str2; double draggedPointOldAngle; double draggedPointAdjusterAngle; @@ -222,8 +225,8 @@ public: void inversshaChanged (); void curveChanged (CurveEditor* ce); void autoOpenCurve (); - void localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat); - void localretChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat); + void localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, int sp, int maxdat); + void localretChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, int sp, int maxdat); bool localComputed_ (); bool localretComputed_ (); void setEditProvider (EditDataProvider* provider); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index b55665c91..8d1d6d18a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -360,6 +360,7 @@ void ParamsEdited::set (bool v) locallab.llcurve = v; locallab.cccurve = v; locallab.LHcurve = v; + locallab.HHcurve = v; for (int i = 0; i < 5; i++) { locallab.mult[i] = v; @@ -955,6 +956,7 @@ void ParamsEdited::initFrom (const std::vector locallab.llcurve = locallab.llcurve && p.locallab.llcurve == other.locallab.llcurve; locallab.cccurve = locallab.cccurve && p.locallab.cccurve == other.locallab.cccurve; locallab.LHcurve = locallab.LHcurve && p.locallab.LHcurve == other.locallab.LHcurve; + locallab.HHcurve = locallab.HHcurve && p.locallab.HHcurve == other.locallab.HHcurve; locallab.expcolor = locallab.expcolor && p.locallab.expcolor == other.locallab.expcolor; locallab.expblur = locallab.expblur && p.locallab.expblur == other.locallab.expblur; locallab.exptonemap = locallab.exptonemap && p.locallab.exptonemap == other.locallab.exptonemap; @@ -2478,6 +2480,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.locallab.LHcurve = mods.locallab.LHcurve; } + if (locallab.HHcurve) { + toEdit.locallab.HHcurve = mods.locallab.HHcurve; + } + if (locallab.localTgaincurverab) { toEdit.locallab.localTgaincurverab = mods.locallab.localTgaincurverab; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index b8926c30e..cbc36a431 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -478,6 +478,7 @@ public: bool llcurve; bool cccurve; bool LHcurve; + bool HHcurve; bool chrrt; bool mult[5]; bool threshold;