diff --git a/rtdata/languages/default b/rtdata/languages/default index d23148c48..b91e112d5 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -531,63 +531,73 @@ HISTORY_MSG_300;- HISTORY_MSG_301;NR - Luma control HISTORY_MSG_302;NR - Chroma method HISTORY_MSG_303;NR - Chroma method -HISTORY_MSG_304;Wavelet Level -HISTORY_MSG_305;Wavelet Level -HISTORY_MSG_306;Wavelet N° level -HISTORY_MSG_307;Wavelet Ch level -HISTORY_MSG_308;Wavelet Direction -HISTORY_MSG_309;Wavelet Edge threshold -HISTORY_MSG_310;Wavelet Hue-tones sky -HISTORY_MSG_311;Wavelet Max Levels -HISTORY_MSG_312;Wavelet Shadow Threshold -HISTORY_MSG_313;Wavelet Pastel Saturated -HISTORY_MSG_314;Wavelet Artifacts blue sky -HISTORY_MSG_315;Wavelet Contrast Residual -HISTORY_MSG_316;Wavelet Skin tones -HISTORY_MSG_317;Wavelet Skin hue -HISTORY_MSG_318;Wavelet Highlight levels -HISTORY_MSG_319;Wavelet Highlight range -HISTORY_MSG_320;Wavelet Shadow range -HISTORY_MSG_321;Wavelet Shadow levels -HISTORY_MSG_322;Wavelet Avoid color shift -HISTORY_MSG_323;Wavelet Contrast curve -HISTORY_MSG_324;Wavelet Chroma pastel -HISTORY_MSG_325;Wavelet Chroma saturated -HISTORY_MSG_326;Wavelet Chroma method -HISTORY_MSG_327;Wavelet Contrast method -HISTORY_MSG_328;Wavelet Chroma link -HISTORY_MSG_329;Wavelet Opacity RG -HISTORY_MSG_330;Wavelet Opacity BY -HISTORY_MSG_331;Wavelet Extra -HISTORY_MSG_332;Wavelet Tiles Method -HISTORY_MSG_333;Wavelet Shadow Residual -HISTORY_MSG_334;Wavelet Chroma -HISTORY_MSG_335;Wavelet Highlight Residual -HISTORY_MSG_336;Wavelet Highlight threshold -HISTORY_MSG_337;Wavelet Hue range -HISTORY_MSG_338;Wavelet Edge Radius -HISTORY_MSG_339;Wavelet Edge Value -HISTORY_MSG_340;Wavelet Strength -HISTORY_MSG_341;Wavelet Daubechies -HISTORY_MSG_342;Wavelet Reinforce first level -HISTORY_MSG_343;Wavelet level chroma -HISTORY_MSG_344;Wavelet Meth chroma sl/cur -HISTORY_MSG_345;Wavelet Local contrast -HISTORY_MSG_346;Wavelet Local contrast Meth -HISTORY_MSG_347;Wavelet Level0 + denoise -HISTORY_MSG_348;Wavelet Level1 + denoise -HISTORY_MSG_349;Wavelet Level2 + denoise -HISTORY_MSG_350;Wavelet edgedetect -HISTORY_MSG_351;Wavelet Curve Hue -HISTORY_MSG_352;Wavelet Background -HISTORY_MSG_353;Wavelet edgedetect value -HISTORY_MSG_354;Wavelet edgedetect enhance -HISTORY_MSG_355;Wavelet edgedetect thresholdLow -HISTORY_MSG_356;Wavelet edgedetect thresholdHi -HISTORY_MSG_357;Wavelet Denoise link -HISTORY_MSG_358;Wavelet Contrast Hue curve +HISTORY_MSG_304;W - Contrast levels +HISTORY_MSG_305;Wavelet Levels +HISTORY_MSG_306;W - Preview +HISTORY_MSG_307;W - Preview +HISTORY_MSG_308;W - Preview direction +HISTORY_MSG_309;W - Edge sharpness - Detail +HISTORY_MSG_310;W - Residual - Hue tar/prot +HISTORY_MSG_311;W - Wavelet levels +HISTORY_MSG_312;W - Residual - Shadows threshold +HISTORY_MSG_313;W - Chroma - Sat/past +HISTORY_MSG_314;W - Gamut - Reduce artifacts +HISTORY_MSG_315;W - Residual - Contrast +HISTORY_MSG_316;W - Gamut - Hue tar/prot +HISTORY_MSG_317;W - Gamut - Hue +HISTORY_MSG_318;W - Contrast - Highlight levels +HISTORY_MSG_319;W - Contrast - Highlight range +HISTORY_MSG_320;W - Contrast - Shadow range +HISTORY_MSG_321;W - Contrast - Shadow levels +HISTORY_MSG_322;W - Gamut - Avoid color shift +HISTORY_MSG_323;W - Edge sharpness - Local contrast curve +HISTORY_MSG_324;W - Chroma - Pastel +HISTORY_MSG_325;W - Chroma - Saturated +HISTORY_MSG_326;W - Chroma - Method +HISTORY_MSG_327;W - Contrast - Apply to +HISTORY_MSG_328;W - Chroma - Link strength +HISTORY_MSG_329;W - Toning - Opacity RG +HISTORY_MSG_330;W - Toning - Opacity BY +HISTORY_MSG_331;W - Contrast levels - Extra +HISTORY_MSG_332;W - Tiling method +HISTORY_MSG_333;W - Residual - Shadows +HISTORY_MSG_334;W - Residual - Chroma +HISTORY_MSG_335;W - Residual - Highlights +HISTORY_MSG_336;W - Residual - Highlights threshold +HISTORY_MSG_337;W - Residual - Hue +HISTORY_MSG_338;W - Edge sharpness - Radius +HISTORY_MSG_339;W - Edge - Strength +HISTORY_MSG_340;W - Strength +HISTORY_MSG_341;W - Edge performance +HISTORY_MSG_342;W - Edge Sharpness - First level +HISTORY_MSG_343;W - Chroma levels +HISTORY_MSG_344;W - Meth chroma sl/cur +HISTORY_MSG_345;W - Edge sharpness - Local contrast +HISTORY_MSG_346;W - Edge sharpness - Local contrast method +HISTORY_MSG_347;W - Denoise and refine - Level 0 +HISTORY_MSG_348;W - Denoise and refine - Level 1 +HISTORY_MSG_349;W - Denoise and refine - Level 2 +HISTORY_MSG_350;W - Edge sharpness - Edge detection +HISTORY_MSG_351;W - Residual - HH curve +HISTORY_MSG_352;W - Background +HISTORY_MSG_353;W - Edge sharpness - Gradient sensitivity +HISTORY_MSG_354;W - Edge sharpness - Enhance +HISTORY_MSG_355;W - Edge sharpness - Threshold low +HISTORY_MSG_356;W - Edge sharpness - Threshold high +HISTORY_MSG_357;W - Denoise and refine - Link with edge sharpness +HISTORY_MSG_358;W - Gamut - CH HISTORY_MSG_359;Hot/Dead - Threshold HISTORY_MSG_360;TM Gamma +HISTORY_MSG_361;W - Final - Chroma balance +HISTORY_MSG_362;W - Residual - Compression method +HISTORY_MSG_363;W - Residual - Compression strength +HISTORY_MSG_364;W - Final - Contrast balance +HISTORY_MSG_365;W - Finals - Delta balance +HISTORY_MSG_366;W - Residual - Compression gamma +HISTORY_MSG_367;W - Edge sharpness - Local contrast curve +HISTORY_MSG_368;W - Final - Balance curve +HISTORY_MSG_369;W - Final - Balance method +HISTORY_MSG_370;W - Final - Local contrast curve HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1344,7 +1354,7 @@ TP_EPD_LABEL;Tone Mapping TP_EPD_REWEIGHTINGITERATES;Reweighting iterates TP_EPD_SCALE;Scale TP_EPD_STRENGTH;Strength -TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" TP_EXPOSURE_AUTOLEVELS;Auto Levels TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. TP_EXPOSURE_BLACKLEVEL;Black @@ -1562,13 +1572,13 @@ TP_ROTATE_LABEL;Rotate TP_ROTATE_SELECTLINE;Select Straight Line TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter TP_SHADOWSHLIGHTS_HIGHLIGHTS;Highlights -TP_SHADOWSHLIGHTS_HLTONALW;Tonal width for highlights +TP_SHADOWSHLIGHTS_HLTONALW;Highlights tonal width TP_SHADOWSHLIGHTS_LABEL;Shadows/highlights TP_SHADOWSHLIGHTS_LOCALCONTR;Local contrast TP_SHADOWSHLIGHTS_RADIUS;Radius TP_SHADOWSHLIGHTS_SHADOWS;Shadows TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask -TP_SHADOWSHLIGHTS_SHTONALW;Tonal width for shadows +TP_SHADOWSHLIGHTS_SHTONALW;Shadows tonal width TP_SHARPENEDGE_AMOUNT;Quantity TP_SHARPENEDGE_LABEL;Edges TP_SHARPENEDGE_PASSES;Iterations @@ -1633,60 +1643,71 @@ TP_WAVELET_B0;Black TP_WAVELET_B1;Grey TP_WAVELET_B2;Residual TP_WAVELET_CCURVE;Local contrast -TP_WAVELET_CH1;All chroma -TP_WAVELET_CH2;Pastel - Saturated +TP_WAVELET_CH1;Whole chromaticity range +TP_WAVELET_CH2;Saturated/pastel TP_WAVELET_CH3;Link contrast levels TP_WAVELET_CHCU;Curve -TP_WAVELET_CHRO;Saturated - Pastel -TP_WAVELET_CHRO_TOOLTIP;Limit between pastel and saturated\n 1-x level saturated \n x-9 level pastel -TP_WAVELET_CHR;Chroma link -TP_WAVELET_CHR_TOOLTIP;Adjust chroma in function of:\na-levels contrasts\nb-Chroma link slider strength +TP_WAVELET_CHRO;Saturated/pastel threshold +TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +TP_WAVELET_CHR;Chroma-contrast link strength +TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" TP_WAVELET_CHSL;Sliders -TP_WAVELET_CHTYPE;Chrominance type -TP_WAVELET_COLORT;Opacity Red-Green Levels +TP_WAVELET_CHTYPE;Chrominance method +TP_WAVELET_COLORT;Opacity Red-Green +TP_WAVELET_COMBOTH;Both +TP_WAVELET_COMPCONT;Contrast +TP_WAVELET_COMPGAMMA;Compression gamma +TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +TP_WAVELET_COMPTM;Tone mapping +TP_WAVELET_CONTEDIT;'After' contrast curve TP_WAVELET_CONTRAST_MINUS;Contrast - TP_WAVELET_CONTRAST_PLUS;Contrast + TP_WAVELET_CONTRA;Contrast -TP_WAVELET_CONTRA_TOOLTIP;Change contrast residual image\nFunction of Max Levels -TP_WAVELET_CONTR;Gamut - controls TP_WAVELET_CTYPE;Chrominance control -TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modify local contral in fonction of original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) -TP_WAVELET_CURVEEDITOR_CH;Contrast levels /Hue -TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modify each level contrast in function oh hue\nCareful not to overwrite changes made with skin-tone hue (red)\nOnly active for contrast levels +TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +TP_WAVELET_CONTR;Gamut +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +TP_WAVELET_CONTEDIT;'After' Contrast curve +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment TP_WAVELET_CURVEEDITOR_HH;HH -TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modify Hue in function of Hue, only for residual image +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. TP_WAVELET_DALL;All directions -TP_WAVELET_DAUB;Edge Quality -TP_WAVELET_DAUB_TOOLTIP;Change Daubechies coefficients\nD4=standard quality\nD14=best quality, more discriminant, increase slightly time treatment about 10%\nThese factors affect the detection of edges, but also general quality for firsts levels +TP_WAVELET_DAUB;Edge performance +TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels.\nHowever the quality is not strictly related to this coefficient and can vary with images and uses TP_WAVELET_DISP;Preview Settings TP_WAVELET_DONE;Vertical TP_WAVELET_DTHR;Diagonal TP_WAVELET_DTWO;Horizontal TP_WAVELET_EDCU;Curve TP_WAVELET_EDGCONT;Local contrast -TP_WAVELET_EDGCONT_TOOLTIP;If you move sliders to the left contrast decrease...and to the right..increase -TP_WAVELET_EDGEDETECTTHR2;Threshold High (detection) -TP_WAVELET_EDGEDETECTTHR;Threshold Low (noise) -TP_WAVELET_EDGEDETECTTHR_TOOLTIP;You can adjust threshold to avoid apply edge sharpness to thin details (noise in sky...) +TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. TP_WAVELET_EDGEDETECT;Gradient sensitivity -TP_WAVELET_EDGEDETECT_TOOLTIP;Algorithm detect edge\nMore the slider is moved to the right, more edge gradient with high level are take into account\nThis has an incidence on local contrast, on edge settings and also on noise -TP_WAVELET_EDGE;Edge Sharpness (Luminance) -TP_WAVELET_EDGREINF_TOOLTIP;For low radius value, increase/decrease the action of the first level, and decrease/increase the action of second level then the others +TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +TP_WAVELET_EDGE;Edge Sharpness +TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. TP_WAVELET_EDGTHRESH;Detail -TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others\nThe more threshold is high, the more the action is centred on the first levels\nBe carefull to negatives values, they increase the action of high levels and can bring artifacts +TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. TP_WAVELET_EDRAD;Radius -TP_WAVELET_EDRAD_TOOLTIP;Radius is very different from others sharpening tools\nIts value is compared to each level, through a complex function\nIn this sense, a zero radius value produce an effect +TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. TP_WAVELET_EDSL;Threshold Sliders -TP_WAVELET_EDTYPE;Local contrast control +TP_WAVELET_EDTYPE;Local contrast method TP_WAVELET_EDVAL;Strength TP_WAVELET_FINEST;Finest TP_WAVELET_HIGHLIGHT;Highlight luminance range TP_WAVELET_HS1;Whole luminance range TP_WAVELET_HS2;Shadows/Highlights -TP_WAVELET_HUESKIN;Hue Range (skin) -TP_WAVELET_HUESKIN_TOOLTIP;This pyramid is for the upper part, so far as the algorithm at its maximum efficiency.\nTo the lower part, the transition zones.\nIf you need to move the area significantly to the left or right - or if there are artifacts: the white balance is incorrect\nYou can slightly reduce the zone to prevent the rest of the image is affected. -TP_WAVELET_HUESKY;Hue Range (sky) -TP_WAVELET_HUESKY_TOOLTIP;This pyramid is for the upper part, so far as the algorithm at its maximum efficiency.\nTo the lower part, the transition zones.\nIf you need to move the area significantly to the left or right - or if there are artifacts: the white balance is incorrect\nYou can slightly reduce the zone to prevent the rest of the image is affected. +TP_WAVELET_HUESKIN;Hue range (skin) +TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +TP_WAVELET_HUESKY;Hue range (sky) +TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. TP_WAVELET_INF;Below or equal the level TP_WAVELET_LABEL;Wavelet levels TP_WAVELET_LARGEST;Coarsest @@ -1694,23 +1715,26 @@ TP_WAVELET_LEVCH;Chromaticity TP_WAVELET_LEVELS;Wavelet levels TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. TP_WAVELET_LEVF;Contrast -TP_WAVELET_LEVLABEL;Preview maximum possible levels=%1 +TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 TP_WAVELET_LEVONE;Level 2 TP_WAVELET_LEVTWO;Level 3 TP_WAVELET_LEVZERO;Level 1 -TP_WAVELET_LINKEDG;Link with Edge-sharpness (strength) +TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength TP_WAVELET_LIPST;Enhanced algorithm -TP_WAVELET_LIPST_TOOLTIP;This algorithme use Lipschitz regularity\nIt increases the processing time and memory requirements, but it is better at detecting edges. +TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. TP_WAVELET_LOWLIGHT;Shadow luminance range TP_WAVELET_MEDGREINF;First level TP_WAVELET_MEDILEV;Edge detection TP_WAVELET_MEDI;Reduce artifacts in blue sky TP_WAVELET_NEUTRAL;Neutral -TP_WAVELET_NOISE;Denoise and refine +TP_WAVELET_NOISE;Denoise and Refine TP_WAVELET_NOIS;Denoise TP_WAVELET_ONE;One level -TP_WAVELET_OPACITY;Opacity Blue-Yellow Levels -TP_WAVELET_PASTEL;Pastel chromacity +TP_WAVELET_OPACITYWL;Final local contrast +TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +TP_WAVELET_OPACITY;Opacity Blue-Yellow +TP_WAVELET_PASTEL;Pastel chromaticity TP_WAVELET_PREVIEWBACK;Background TP_WAVELET_PREVIEWLEVELS;Preview TP_WAVELET_RE1;Reinforced @@ -1720,27 +1744,59 @@ TP_WAVELET_RESCHRO;Chromaticity TP_WAVELET_RESCONH;Highlights TP_WAVELET_RESCON;Shadows TP_WAVELET_RESID;Residual image -TP_WAVELET_SAT;Saturated chromacity +TP_WAVELET_TMTYPE;Compression method +TP_WAVELET_COMPCONT;Contrast +TP_WAVELET_COMPTM;Tone mapping +TP_WAVELET_COMBOTH;Both +TP_WAVELET_BATYPE;Balance method +TP_WAVELET_BANONE;None +TP_WAVELET_BASLI;Slider +TP_WAVELET_BACUR;Curve +TP_WAVELET_BALANCE;Contrast balance diagonal / vertical-horizontal +TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +TP_WAVELET_BALCHRO;Chroma balance +TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +TP_WAVELET_BANONE;None +TP_WAVELET_BASLI;Slider +TP_WAVELET_BATYPE;Balance method +TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +TP_WAVELET_ITER;Delta balance levels +TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +TP_WAVELET_OPACITYWL;Final local contrast +TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +TP_WAVELET_COMPGAMMA;Gamma +TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +TP_WAVELET_TMHIGH;High +TP_WAVELET_TMLOWHIGH;Low+High +TP_WAVELET_SAT;Saturated chromaticity TP_WAVELET_SETTINGS;Wavelet Settings +TP_WAVELET_FINAL;Final Touchup TP_WAVELET_SKIN;Hue-tones (skin) targetting/protection TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. TP_WAVELET_SKY;Hue-tones (sky) targetting/protection -TP_WAVELET_SKY_TOOLTIP;Increase/reduce chrominance in/out hue range\nAvoid artifacts in blue sky - due to micro-contrast, micro-chroma,... +TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. TP_WAVELET_STRENGTH;Strength TP_WAVELET_STREN;Strength TP_WAVELET_SUPE;Extra TP_WAVELET_SUP;Above the level -TP_WAVELET_THRESHOLD2;Shadow Levels -TP_WAVELET_THRESHOLD2_TOOLTIP;If you change this value, only level between 9 and 9 minus value, will be treated with shadow luminance levels\nOthers level will be full treated\nMax level shadow is limited by value of highlight level (9-highlight level) +TP_WAVELET_THRESHOLD2;Shadow levels +TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). TP_WAVELET_THRESHOLD;Highlight levels -TP_WAVELET_THRESHOLD_TOOLTIP;If you change this value, only level beyond will be treated with highlight luminance levels\nOthers level will be full treated -TP_WAVELET_THRH;Threshold highlights -TP_WAVELET_THR;Threshold shadows +TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +TP_WAVELET_THRH;Highlights threshold +TP_WAVELET_THR;Shadows threshold TP_WAVELET_TILESBIG;Big tiles TP_WAVELET_TILESFULL;Full image -TP_WAVELET_TILESIZE;Tile size +TP_WAVELET_TILESIZE;Tiling method TP_WAVELET_TILESLIT;Little tiles TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +TP_WAVELET_TMHIGH;High +TP_WAVELET_TMLOWHIGH;Low+High +TP_WAVELET_TMNONE;None +TP_WAVELET_TMSTD;Standard +TP_WAVELET_TMSTRENGTH;Compression strength +TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +TP_WAVELET_TMTYPE;Compression method TP_WAVELET_TON;Toning TP_WAVELET_daub2;D2 - low TP_WAVELET_daub4;D4 - standard diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 27fd67738..17f5d0fd5 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -425,6 +425,39 @@ void CurveFactory::curveCL ( bool & clcutili,const std::vector& clcurveP dCurve = NULL; } } +// add curve Lab wavelet : Cont=f(L) +void CurveFactory::curveWavContL ( bool & wavcontlutili,const std::vector& wavclcurvePoints, LUTf & wavclCurve, /*LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip){ + bool needed; + DiagonalCurve* dCurve = NULL; + + // if (outBeforeWavCLurveHistogram) + // outBeforeWavCLurveHistogram.clear(); + bool histNeededCL = false; + + needed = false; + if (!wavclcurvePoints.empty() && wavclcurvePoints[0]!=0) { + dCurve = new DiagonalCurve (wavclcurvePoints, CURVES_MIN_POLY_POINTS/skip); + // if (outBeforeWavCLurveHistogram) + // histNeededCL = true; + + if (dCurve && !dCurve->isIdentity()) + {needed = true;wavcontlutili=true;} + } + // if(histNeededCL) + for (int i=0; i<32768; i++) {//32768*1.414 + ... + int hi = (int)(255.0*CLIPD((float)i / 32767.0)); // + // outBeforeWavCLurveHistogram[hi] += histogramwavcl[i] ; + } + + + fillCurveArray(dCurve, wavclCurve, skip, needed); + // wavclCurve.dump("WL"); + + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} // add curve Colortoning : C=f(L) void CurveFactory::curveToningCL ( bool & clctoningutili,const std::vector& clcurvePoints, LUTf & clToningCurve,int skip){ @@ -1254,6 +1287,57 @@ void WavOpacityCurveBY::Set(const std::vector &curvePoints) { } } +WavOpacityCurveW::WavOpacityCurveW(){}; + +void WavOpacityCurveW::Reset() { + lutOpacityCurveW.reset(); +} + +void WavOpacityCurveW::Set(const Curve &pCurve) { + if (pCurve.isIdentity()) { + lutOpacityCurveW.reset(); // raise this value if the quality suffers from this number of samples + return; + } + lutOpacityCurveW(501); // raise this value if the quality suffers from this number of samples + + for (int i=0; i<501; i++) lutOpacityCurveW[i] = pCurve.getVal(double(i)/500.); +} + +void WavOpacityCurveW::Set(const std::vector &curvePoints) { + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0] &curvePoints) { + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0]& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip); + + static void curveWavContL ( bool & wavcontlutili,const std::vector& wavclcurvePoints, LUTf & wavclCurve,/* LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip); + static void curveToningCL ( bool & clctoningutili, const std::vector& clcurvePoints, LUTf & clToningCurve, int skip); static void curveToningLL ( bool & llctoningutili, const std::vector& llcurvePoints, LUTf & llToningCurve, int skip); static void denoiseCC ( bool & ccdenoiseutili, const std::vector& cccurvePoints, LUTf & NoiseCCcurve,int skip); @@ -422,6 +425,39 @@ class WavOpacityCurveBY { operator bool (void) const { return lutOpacityCurveBY; } }; +class WavOpacityCurveW { + private: + LUTf lutOpacityCurveW; // 0xffff range + void Set(const Curve &pCurve); + + public: + virtual ~WavOpacityCurveW() {}; + WavOpacityCurveW(); + + void Reset(); + void Set(const Curve *pCurve); + void Set(const std::vector &curvePoints); + float operator[](float index) const { return lutOpacityCurveW[index]; } + + operator bool (void) const { return lutOpacityCurveW; } +}; + +class WavOpacityCurveWL { + private: + LUTf lutOpacityCurveWL; // 0xffff range + void Set(const Curve &pCurve); + + public: + virtual ~WavOpacityCurveWL() {}; + WavOpacityCurveWL(); + + void Reset(); + void Set(const Curve *pCurve); + void Set(const std::vector &curvePoints); + float operator[](float index) const { return lutOpacityCurveWL[index]; } + + operator bool (void) const { return lutOpacityCurveWL; } +}; class NoiseCurve { private: diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 7a8dc715c..13fef46f5 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -632,6 +632,7 @@ void Crop::update (int todo) { bool ccutili=parent->ccutili; bool clcutili=parent->clcutili; bool cclutili=parent->cclutili; + bool wavcontlutili=parent->wavcontlutili; LUTu dummy; parent->ipf.chromiLuminanceCurve (this, 1,labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy); @@ -713,10 +714,14 @@ void Crop::update (int todo) { WavCurve wavCLVCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; - - params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY); + WavOpacityCurveW waOpacityCurveW; + WavOpacityCurveWL waOpacityCurveWL; + LUTf wavclCurve; + LUTu dummy; - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, skip); + params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, wavcontlutili, skip); } // } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 9313b91a3..a0d643205 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -45,6 +45,7 @@ ImProcCoordinator::ImProcCoordinator () satcurve(65536,0), lhskcurve(65536,0), clcurve(65536,0), + wavclCurve(65536,0), clToningcurve(65536,0), cl2Toningcurve(65536,0), Noisecurve(65536,0), @@ -84,7 +85,7 @@ ImProcCoordinator::ImProcCoordinator () fullw(1),fullh(1), pW(-1), pH(-1), plistener(NULL), imageListener(NULL), aeListener(NULL), acListener(NULL),abwListener(NULL),actListener(NULL),adnListener(NULL), awavListener(NULL), hListener(NULL), - resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false),utili(false),autili(false), + resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false),utili(false),autili(false),wavcontlutili(false), butili(false),ccutili(false),cclutili(false),clcutili(false),opautili(false) {} @@ -549,14 +550,22 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { } //} + wavcontlutili = false; + //CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve , /*lhist16CLlad, histCLurve,*/ scale==1 ? 1 : 16); + + if((params.wavelet.enabled)) { WaveletParams WaveParams = params.wavelet; - WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY); + // WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY); + WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); int kall=0; progress ("Wavelet...",100*readyphase/numofphases); - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, scale); - } + // ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, scale); + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, wavcontlutili, scale); + + } if(params.colorappearance.enabled){ diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index d3ed9da0e..6040b9977 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -92,6 +92,7 @@ class ImProcCoordinator : public StagedImageProcessor { LUTf satcurve; LUTf lhskcurve; LUTf clcurve; + LUTf wavclCurve; LUTf clToningcurve; LUTf cl2Toningcurve; LUTf Noisecurve; @@ -123,6 +124,8 @@ class ImProcCoordinator : public StagedImageProcessor { WavCurve wavCLVCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; + WavOpacityCurveW waOpacityCurveW; + WavOpacityCurveWL waOpacityCurveWL; ColorAppearance customColCurve1; ColorAppearance customColCurve2; @@ -181,7 +184,7 @@ class ImProcCoordinator : public StagedImageProcessor { bool cclutili; bool clcutili; bool opautili; - + bool wavcontlutili; void startProcessing (); void process (); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 865fb822b..32c16790d 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5099,6 +5099,8 @@ void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) { void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates, int skip){ if(!params->epd.enabled) return; +if(params->wavelet.enabled && params->wavelet.tmrs!=0) return; + float stren=params->epd.strength; float edgest=params->epd.edgeStopping; float sca=params->epd.scale; @@ -5188,6 +5190,8 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) //Enabled? Leave now if not. // if(!p->enabled) return; if(!params->epd.enabled) return; +if(params->wavelet.enabled && params->wavelet.tmrs!=0) return; + float stren=params->epd.strength; float edgest=params->epd.edgeStopping; float sca=params->epd.scale; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f05ab3237..e2e958fcb 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -270,6 +270,11 @@ class ImProcFunctions { void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise void dirpyrequalizer (LabImage* lab, int scale);//Emil's wavelet + void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params cp, int W_L, int H_L, float max0, float min0); + float *CompressDR(float *Source, int skip, struct cont_params cp, int W_L, int H_L, float Compression,float DetailBoost,float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed); + void ContrastResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx); + float *ContrastDR(float *Source, int skip, struct cont_params cp, int W_L, int H_L, float Compression,float DetailBoost,float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Contrast=NULL); + void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); void EPDToneMapCIE(CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates=0, int skip =1); // void CAT02 (Imagefloat* baseImg, const ProcParams* params); @@ -287,16 +292,21 @@ class ImProcFunctions { //void RGB_OutputTransf(LabImage * src, Imagefloat * dst, const procparams::DirPyrDenoiseParams & dnparams); //void output_tile_row (float *Lbloxrow, float ** Lhipassdn, float ** tilemask, int height, int width, int top, int blkrad ); void Tile_calc (int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); - void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, int skip); + void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, LUTf &wavclCurve, bool wavcontlutili, int skip); + void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, - struct cont_params cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, FlatCurve* ChCurve, bool Chutili); - void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, + struct cont_params cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili); + void WaveletcontAllLfinal(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, + struct cont_params cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili); + void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a,const WavOpacityCurveW & waOpacityCurveW, struct cont_params cp, const bool useChannelA); void WaveletAandBAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, - struct cont_params cp, FlatCurve* hhcurve, bool hhutili); + struct cont_params cp, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* hhcurve, bool hhutili); void ContAllL (float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params cp, - int W_L, int H_L, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, FlatCurve* ChCurve, bool Chutili); - void ContAllAB (LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, struct cont_params cp, + int W_L, int H_L, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); + void finalContAllL (int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params cp, + int W_L, int H_L, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili); + void ContAllAB (LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params cp, int W_ab, int H_ab, const bool useChannelA); void Evaluate2(wavelet_decomposition &WaveletCoeffs_L, struct cont_params cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float madL[8][3]); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index cf7a48c9a..d52c9ea3b 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -38,6 +38,7 @@ #include "sleef.c" #include "opthelper.h" #include "StopWatch.h" +#include "EdgePreservingDecomposition.h" #ifdef _OPENMP #include @@ -78,59 +79,72 @@ namespace rtengine { extern const Settings* settings; struct cont_params { - float mul[10]; - int chrom; - int chro; - int contrast; - float th; - float thH; - float conres; - float conresH; - float chrores; - float hueres; - float sky; - float b_l,t_l,b_r,t_r; - float b_ly,t_ly,b_ry,t_ry; - float b_lsl,t_lsl,b_rsl,t_rsl; - float b_lhl,t_lhl,b_rhl,t_rhl; - float edg_low, edg_mean, edg_sd, edg_max; - float lev0s, lev0n, lev1s, lev1n, lev2s, lev2n; - float b_lpast,t_lpast,b_rpast,t_rpast; - float b_lsat,t_lsat,b_rsat,t_rsat; - int rad; - int val; - int til; - int numlevH, numlevS; - float mulC[9]; - float mulopaRG[9]; - float mulopaBY[9]; - bool curv; - bool opaBY; - bool opaRG; - bool edgcurv; - int CHmet; - int CHSLmet; - int EDmet; - bool HSmet; - bool avoi; - float strength; - int reinforce; - bool detectedge; - int backm; - float eddet; - float eddetthr; - bool lips; - float eddetthrHi; - bool link; - bool lip3; - + float mul[10]; + int chrom; + int chro; + int contrast; + float th; + float thH; + float conres; + float conresH; + float chrores; + float hueres; + float sky; + float b_l,t_l,b_r,t_r; + float b_ly,t_ly,b_ry,t_ry; + float b_lsl,t_lsl,b_rsl,t_rsl; + float b_lhl,t_lhl,b_rhl,t_rhl; + float edg_low, edg_mean, edg_sd, edg_max; + float lev0s, lev0n, lev1s, lev1n, lev2s, lev2n; + float b_lpast,t_lpast,b_rpast,t_rpast; + float b_lsat,t_lsat,b_rsat,t_rsat; + int rad; + int val; + int til; + int numlevH, numlevS; + float mulC[9]; + float mulopaRG[9]; + float mulopaBY[9]; + bool curv; + bool opaBY; + bool opaRG; + bool edgcurv; + bool diagcurv; + int CHmet; + int CHSLmet; + int EDmet; + bool HSmet; + bool avoi; + float strength; + int reinforce; + bool detectedge; + int backm; + float eddet; + float eddetthr; + bool lips; + float eddetthrHi; + bool link; + bool lip3; + bool tonemap; + bool diag; + int TMmeth; + float tmstrength; + float balan; + int ite; + int contmet; + bool opaW; + int BAmet; + bool bam; }; int wavNestedLevels = 1; -SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, int skip) + +SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, LUTf &wavclCurve, bool wavcontlutili, int skip) + + { - MyTime t1e,t2e; + MyTime t1e,t2e ; t1e.set(); #ifdef _DEBUG @@ -150,6 +164,27 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int if(params->wavelet.Medgreinf=="none") cp.reinforce = 2; if(params->wavelet.Medgreinf=="less") cp.reinforce = 3; cp.lip3 = params->wavelet.lipst; + cp.diag = params->wavelet.tmr; + cp.balan = (float)params->wavelet.balance; + cp.ite = params->wavelet.iter; + cp.tonemap=false; + cp.bam=false; + if(params->wavelet.tmrs==0) cp.tonemap=false; + else cp.tonemap=true; + /*else if(params->wavelet.TMmethod=="std") {cp.TMmeth=1;cp.tonemap=true;} + else if(params->wavelet.TMmethod=="high") {cp.TMmeth=2;cp.tonemap=true;} + else if(params->wavelet.TMmethod=="lowhigh") {cp.TMmeth=3;cp.tonemap=true;} + */ + if(params->wavelet.TMmethod=="cont") cp.contmet=1; + else if(params->wavelet.TMmethod=="tm") cp.contmet=2; + + if(params->wavelet.BAmethod!="none") cp.bam=true; + if(params->wavelet.BAmethod=="sli") cp.BAmet=1; + if(params->wavelet.BAmethod=="cur") cp.BAmet=2; + + cp.tmstrength=params->wavelet.tmrs; + //cp.tonemap = params->wavelet.tmr; + if(params->wavelet.Backmethod=="black") cp.backm= 0; if(params->wavelet.Backmethod=="grey") cp.backm = 1; if(params->wavelet.Backmethod=="resid") cp.backm = 2; @@ -183,8 +218,10 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int cp.curv=false; cp.edgcurv=false; + cp.diagcurv=false; cp.opaRG=false; cp.opaBY=false; + cp.opaW=false; cp.CHmet=0; cp.HSmet=false; if(params->wavelet.CHmethod=="with") cp.CHmet=1; @@ -193,29 +230,8 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int cp.strength = min(1.f,max(0.f,((float)params->wavelet.strength / 100.f))); -// if(wavCLVCcurve) cp.curv=true; - /* if(cp.CHSLmet==2) {//curve - if(cp.curv) {//convert curve in discret values - cp.mulC[0]=200.f*(wavCLVCcurve[0]-0.5f); - cp.mulC[1]=200.f*(wavCLVCcurve[62]-0.5f); - cp.mulC[2]=200.f*(wavCLVCcurve[125]-0.5f); - cp.mulC[3]=200.f*(wavCLVCcurve[187]-0.5f); - cp.mulC[4]=200.f*(wavCLVCcurve[250]-0.5f); - cp.mulC[5]=200.f*(wavCLVCcurve[312]-0.5f); - cp.mulC[6]=200.f*(wavCLVCcurve[375]-0.5f); - cp.mulC[7]=200.f*(wavCLVCcurve[438]-0.5f); - cp.mulC[8]=200.f*(wavCLVCcurve[500]-0.5f); - } - else { - for(int level=0;level<9;level++) - cp.mulC[level] = 0.f; - } - } - */ -// else if(cp.CHSLmet==1) {//slider for(int m=0;mverbose) printf("Wav mul 0=%f 1=%f 2=%f 3=%f 4=%f 5=%f 6=%f 7=%f 8=%f 9=%f\n",cp.mul[0],cp.mul[1],cp.mul[2],cp.mul[3],cp.mul[4],cp.mul[5],cp.mul[6],cp.mul[7],cp.mul[8],cp.mul[9]); +// if(settings->verbose) printf("Wav mul 0=%f 1=%f 2=%f 3=%f 4=%f 5=%f 6=%f 7=%f 8=%f 9=%f\n",cp.mul[0],cp.mul[1],cp.mul[2],cp.mul[3],cp.mul[4],cp.mul[5],cp.mul[6],cp.mul[7],cp.mul[8],cp.mul[9]); for(int sc=0;sc<9;sc++) {//reduce strength if zoom < 100% for chroma and tuning if(sc==0) {if(scaleskip[sc] < 1.f) {cp.mulC[sc]*=(atten0*scaleskip[sc]);cp.mulopaRG[sc]*=(atten0*scaleskip[sc]);cp.mulopaBY[sc]*=(atten0*scaleskip[sc]);}} else {if(scaleskip[sc] < 1.f) {cp.mulC[sc]*=(atten123*scaleskip[sc]);cp.mulopaRG[sc]*=(atten123*scaleskip[sc]);cp.mulopaBY[sc]*=(atten123*scaleskip[sc]);}} @@ -588,12 +605,12 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int bool ref0=false; if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) ref0=true; - printf("LevwavL before: %d\n",levwavL); - if(cp.contrast == 0.f && cp.conres == 0.f && cp.conresH == 0.f && cp.val ==0 && !ref0 && params->wavelet.CLmethod=="all") { // no processing of residual L or edge=> we probably can reduce the number of levels + // printf("LevwavL before: %d\n",levwavL); + if(cp.contrast == 0.f && cp.tonemap==false && cp.conres == 0.f && cp.conresH == 0.f && cp.val ==0 && !ref0 && params->wavelet.CLmethod=="all") { // no processing of residual L or edge=> we probably can reduce the number of levels while(levwavL > 0 && cp.mul[levwavL-1] == 0.f) // cp.mul[level] == 0.f means no changes to level levwavL--; } - printf("LevwavL after: %d\n",levwavL); + // printf("LevwavL after: %d\n",levwavL); if(levwavL < 3) levwavL=3;//to allow edge => I always allocate 3 levels..because if user select wavelet it is to do something !! if(levwavL > 0) { wavelet_decomposition* Ldecomp = new wavelet_decomposition (labco->data, labco->W, labco->H, levwavL, 1, skip, max(1,wavNestedLevels), DaubLen ); @@ -653,10 +670,12 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int Chutili = true; - WaveletcontAllL(labco, varhue, varchro, *Ldecomp, cp, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, ChCurve, Chutili); - if(cp.val > 0 || ref || contr) {//edge + WaveletcontAllL(labco, varhue, varchro, *Ldecomp, cp, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveWL, ChCurve, Chutili); + if(cp.val > 0 || ref || contr || cp.diagcurv) {//edge Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); } + WaveletcontAllLfinal(labco, varhue, varchro, *Ldecomp, cp, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, waOpacityCurveWL, ChCurve, Chutili); + //Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); Ldecomp->reconstruct(labco->data, cp.strength); } @@ -679,7 +698,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int int levwava = levwav; // printf("Levwava before: %d\n",levwava); if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels - while(levwava > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwava-1] == 0.f )) || (cp.CHmet!=2 && (levwava == 10 || (!cp.curv || (cp.curv && cp.mulC[levwava-1] == 0.f)))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava-1] == 0.f)) && ((levwava == 10 ||(cp.CHSLmet==1 && cp.mulC[levwava-1] == 0.f)))) { + while(levwava > 0 && !cp.diag &&(((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwava-1] == 0.f )) || (cp.CHmet!=2 && (levwava == 10 || (!cp.curv || (cp.curv && cp.mulC[levwava-1] == 0.f)))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava-1] == 0.f)) && ((levwava == 10 ||(cp.CHSLmet==1 && cp.mulC[levwava-1] == 0.f)))) { levwava--; } } @@ -687,7 +706,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int if(levwava > 0) { wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data+datalen, labco->W, labco->H,levwava, 1, skip, max(1,wavNestedLevels), DaubLen ); if(!adecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp, cp, true); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); adecomp->reconstruct(labco->data+datalen, cp.strength); } delete adecomp; @@ -695,7 +714,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int int levwavb = levwav; //printf("Levwavb before: %d\n",levwavb); if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels - while(levwavb > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavb-1] == 0.f )) || (cp.CHmet!=2 && (levwavb == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavb-1] == 0.f)))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb-1] == 0.f)) && ((levwavb == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavb-1] == 0.f)))) { + while(levwavb > 0 && !cp.diag && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavb-1] == 0.f )) || (cp.CHmet!=2 && (levwavb == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavb-1] == 0.f)))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb-1] == 0.f)) && ((levwavb == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavb-1] == 0.f)))) { levwavb--; } } @@ -703,27 +722,27 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int if(levwavb > 0) { wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data+2*datalen, labco->W, labco->H, levwavb, 1, skip, max(1,wavNestedLevels), DaubLen ); if(!bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, cp, false); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); bdecomp->reconstruct(labco->data+2*datalen, cp.strength); } delete bdecomp; } } else {// a and b int levwavab = levwav; - printf("Levwavab before: %d\n",levwavab); + // printf("Levwavab before: %d\n",levwavab); if(cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels while(levwavab > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavab-1] == 0.f )) || (cp.CHmet!=2 && (levwavab == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavab-1] == 0.f)))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab-1] == 0.f)) && ((levwavab == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavab-1] == 0.f)))) { levwavab--; } } - printf("Levwavab after: %d\n",levwavab); + // printf("Levwavab after: %d\n",levwavab); if(levwavab > 0) { wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data+datalen, labco->W, labco->H,levwavab, 1, skip, max(1,wavNestedLevels), DaubLen ); wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data+2*datalen, labco->W, labco->H, levwavab, 1, skip, max(1,wavNestedLevels), DaubLen ); if(!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp, cp, true); - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, cp, false); - WaveletAandBAllAB(labco, varhue, varchro, *adecomp, *bdecomp, cp, hhCurve, hhutili ); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); + WaveletAandBAllAB(labco, varhue, varchro, *adecomp, *bdecomp, cp, waOpacityCurveW, hhCurve, hhutili ); adecomp->reconstruct(labco->data+datalen, cp.strength); bdecomp->reconstruct(labco->data+2*datalen, cp.strength); @@ -736,7 +755,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int if (hhCurve) delete hhCurve; - if(numtiles > 1 || (numtiles == 1 && cp.avoi)) { + if(numtiles > 1 || (numtiles == 1 /*&& cp.avoi*/)) {//in all case since I add contrast curve //calculate mask for feathering output tile overlaps float Vmask[height+overlap] ALIGNED16; float Hmask[width+overlap] ALIGNED16; @@ -826,6 +845,11 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int Chprov1 /= 327.68f; #endif L = labco->L[i1][j1]; + const float Lin=labco->L[i1][j1]; + + if(wavclCurve) {labco->L[i1][j1] =(0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve + L = labco->L[i1][j1]; + float Lprov1=L/327.68f; float Lprov2 = Lold[i][j]/327.68f; float memChprov=varchro[i1][j1]; @@ -859,7 +883,11 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int a=327.68f*Chprov*sincosv.y;// apply Munsell b=327.68f*Chprov*sincosv.x;//aply Munsell - } else { + } else {//general case + L = labco->L[i1][j1]; + const float Lin=labco->L[i1][j1]; + + if(wavclCurve) {labco->L[i1][j1] = (0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve L = labco->L[i1][j1]; a = labco->a[i1][j1]; b = labco->b[i1][j1]; @@ -995,7 +1023,7 @@ omp_set_nested(oldNested); void ImProcFunctions::Evaluate2(wavelet_decomposition &WaveletCoeffs_L, struct cont_params cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float madL[8][3]){ -StopWatch Stop1("Evaluate2"); +//StopWatch Stop1("Evaluate2"); int maxlvl = WaveletCoeffs_L.maxlevel(); for (int lvl=0; lvl ave) { + float kh = ah*(Source[i]*100.f)+bh; + prov=32768.f*Source[i]; + Contrast[i]=ave+kh*(Source[i]*32768.f-ave); + } else { + float kl = al*(Source[i]*100.f)+bl; + prov=32768.f*Source[i]; + Contrast[i]=ave-kl*(ave-Source[i]*32768.f); + } + float diflc=Contrast[i]-prov; + diflc*=factorx; + Contrast[i] = (prov + diflc)/32768.f; + //contrast between 0 and 1 + } +*/ + Contrast[i] = Source[i] ; + + } + return Contrast; +} + +SSEFUNCTION float *ImProcFunctions::CompressDR(float *Source, int skip, struct cont_params cp, int W_L, int H_L, float Compression,float DetailBoost,float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed){ + + const float eps = 0.000001f; + int n=W_L*H_L; + +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + __m128 epsv = _mm_set1_ps( eps ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int ii = 0; ii < n-3; ii+=4) + _mm_storeu_ps( &Source[ii], xlogf(LVFU(Source[ii]) + epsv)); +} + for(int ii = n-(n%4); ii < n; ii++) + Source[ii] = xlogf(Source[ii] + eps); + +#else +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int ii = 0; ii < n; ii++) + Source[ii] = xlogf(Source[ii] + eps); +#endif + + float *ucr =ContrastDR(Source, skip, cp, W_L, H_L, Compression,DetailBoost,max0, min0, ave, ah, bh, al, bl, factorx); + if(Compressed == NULL) Compressed = ucr; + float temp; + if(DetailBoost>0.f && DetailBoost < 0.05f ) { + float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2) + temp = 1.2f*xlogf( -betemp); + temp /= 20.f; + } + else if(DetailBoost>=0.05f && DetailBoost < 0.25f ) { + float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2) + temp = 1.2f*xlogf( -betemp); + temp /= (-75.f*DetailBoost+23.75f); + } + else if(DetailBoost>=0.25f) { + float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2) + temp = 1.2f*xlogf( -betemp); + temp /= (-2.f*DetailBoost + 5.5f); + } + + else temp= (Compression - 1.0f)/20.f; +// printf("temp=%f \n", temp); + + +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + __m128 cev, uev, sourcev; + __m128 epsv = _mm_set1_ps( eps ); + __m128 DetailBoostv = _mm_set1_ps( DetailBoost ); + __m128 tempv = _mm_set1_ps( temp ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < n-3; i+=4){ + cev = xexpf(LVFU(Source[i]) + LVFU(ucr[i])*(tempv)) - epsv; + uev = xexpf(LVFU(ucr[i])) - epsv; + sourcev = xexpf(LVFU(Source[i])) - epsv; + _mm_storeu_ps( &Source[i], sourcev); + _mm_storeu_ps( &Compressed[i], cev + DetailBoostv * (sourcev - uev) ); + } +} + for(int i=n-(n%4); i < n; i++){ + float ce = xexpf(Source[i] + ucr[i]*(temp)) - eps; + float ue = xexpf(ucr[i]) - eps; + Source[i] = xexpf(Source[i]) - eps; + Compressed[i] = ce + DetailBoost*(Source[i] - ue); + } + +#else +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < n; i++){ + float ce = xexpf(Source[i] + ucr[i]*(temp)) - eps; + float ue = xexpf(ucr[i]) - eps; + Source[i] = xexpf(Source[i]) - eps; + Compressed[i] = ce + DetailBoost*(Source[i] - ue); + } +#endif + + if(Compressed != ucr) delete[] ucr; + return Compressed; + + +} + +void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx) { + float stren=cp.tmstrength; + float gamm=params->wavelet.gamma; + cp.TMmeth=2;//default after testing + if(cp.TMmeth ==1) {min0 = 0.0f;max0=32768.f;} + else if (cp.TMmeth ==2) {min0 = 0.0f;} +#pragma omp parallel for + for(int i = 0; i < W_L*H_L; i++) + { WavCoeffs_L0[i]= (WavCoeffs_L0[i] - min0)/max0; + WavCoeffs_L0[i]*=gamm; + } + + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost = stren; + if(stren < 0.0f) DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. + + + CompressDR(WavCoeffs_L0, skip, cp, W_L, H_L, Compression,DetailBoost,max0, min0, ave, ah, bh, al, bl, factorx, WavCoeffs_L0); + + + #ifdef _OPENMP + #pragma omp parallel for // removed schedule(dynamic,10) + #endif + for(int ii = 0; ii < W_L*H_L; ii++) + WavCoeffs_L0[ii] = WavCoeffs_L0[ii]*max0*(1.f/gamm) + min0; + } + + + + + void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params cp, int W_L, int H_L, float max0, float min0) { + + + float stren=cp.tmstrength; + float edgest=params->epd.edgeStopping; + float sca=params->epd.scale; + float gamm=params->wavelet.gamma; + float rew=params->epd.reweightingIterates; + EdgePreservingDecomposition epd = EdgePreservingDecomposition(W_L, H_L); + cp.TMmeth=2;//default after testing + if(cp.TMmeth ==1) {min0 = 0.0f;max0=32768.f;} + else if (cp.TMmeth ==2) {min0 = 0.0f;} + // max0=32768.f; +#pragma omp parallel for + for(int i = 0; i < W_L*H_L; i++) + { WavCoeffs_L0[i]= (WavCoeffs_L0[i] - min0)/max0; + WavCoeffs_L0[i]*=gamm; + } + + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost = stren; + if(stren < 0.0f) DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. + + //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. + if(Iterates == 0) Iterates = (unsigned int)(edgest*15.0f); + + + epd.CompressDynamicRange(WavCoeffs_L0, sca/float(skip), edgest, Compression, DetailBoost, Iterates, rew, WavCoeffs_L0); + + //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. + #ifdef _OPENMP + #pragma omp parallel for // removed schedule(dynamic,10) + #endif + for(int ii = 0; ii < W_L*H_L; ii++) + WavCoeffs_L0[ii] = WavCoeffs_L0[ii]*max0*(1.f/gamm) + min0; + } + +void ImProcFunctions::WaveletcontAllLfinal(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, + struct cont_params cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili){ + + int maxlvl = WaveletCoeffs_L.maxlevel(); + int W_L = WaveletCoeffs_L.level_W(0); + int H_L = WaveletCoeffs_L.level_H(0); + float * WavCoeffs_L0 = WaveletCoeffs_L.coeff0; + + +#ifdef _OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int dir=1; dir<4; dir++) { + for (int lvl=0; lvl1) #endif @@ -1099,17 +1352,17 @@ StopWatch Stop1("Evaluate2"); } + // printf("MAXmax0=%f MINmin0=%f\n",max0,min0); + +//tone mapping +if(cp.tonemap && cp.contmet==2) { + //iterate = 5 + EPDToneMapResid(WavCoeffs_L0, 5, skip, cp, W_L, H_L, max0, min0); + +} +//end tonemapping -#ifdef _OPENMP -//#pragma omp parallel for num_threads(wavNestedLevels) if(wavNestedLevels>1) -#endif - /* for (int i=0; i max0) max0=WavCoeffs_L0[i]; - if(WavCoeffs_L0[i] < min0) min0=WavCoeffs_L0[i]; - - } - */ max0/=327.68f; min0/=327.68f; float ave = avedbl / (double)(W_L*H_L); @@ -1119,12 +1372,10 @@ StopWatch Stop1("Evaluate2"); float al=(multL-1.f)/(av-min0); float bl=1.f-min0*al; float factorx=1.f; - float *koeLi[9]; float maxkoeLi[9]; float *koeLibuffer = NULL; bool lipschitz =false; - //if(cp.lips)lipschitz=true;//I suppress "logical" normal algorithm, low quality, same time lipschitz=true; if(lipschitz==true) { @@ -1143,6 +1394,7 @@ StopWatch Stop1("Evaluate2"); #endif { if(contrast != 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step + { #ifdef _OPENMP #pragma omp for #endif @@ -1164,14 +1416,22 @@ StopWatch Stop1("Evaluate2"); } } } + } + +if(cp.tonemap && cp.contmet==1) { + float maxp=max0*256.f; + float minp=min0*256.f; + #pragma omp single + ContrastResid(WavCoeffs_L0, 5, skip, cp, W_L, H_L, maxp, minp, ave, ah, bh, al, bl, factorx ); +} +#pragma omp barrier + + if(cp.conres != 0.f || cp.conresH != 0.f) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _OPENMP #pragma omp for nowait #endif for (int i=0; iL[ii*2][jj*2]; float LL=WavCoeffs_L0[i]; float LL100 = LL/327.68f; float tran = 5.f;//transition @@ -1312,11 +1572,11 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - ContAllL (koeLi, maxkoeLi, lipschitz, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, ChCurve, Chutili); + ContAllL (koeLi, maxkoeLi, lipschitz, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); + + } } - - } //delete edge detection if(koeLibuffer) { @@ -1325,8 +1585,8 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory } void ImProcFunctions::WaveletAandBAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, - struct cont_params cp, FlatCurve* hhCurve, bool hhutili){ - StopWatch Stop1("WaveletAandBAllAB"); + struct cont_params cp, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* hhCurve, bool hhutili){ + // StopWatch Stop1("WaveletAandBAllAB"); if (hhutili) { // H=f(H) int W_L = WaveletCoeffs_a.level_W(0); int H_L = WaveletCoeffs_a.level_H(0); @@ -1386,7 +1646,7 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory } - void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_ab, + void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_ab,const WavOpacityCurveW & waOpacityCurveW, struct cont_params cp, const bool useChannelA){ int maxlvl = WaveletCoeffs_ab.maxlevel(); @@ -1460,9 +1720,11 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory int skip_ab = WaveletCoeffs_ab.level_stride(lvl); //printf("lev=%d skipL=%d skipab=%d\n",lvl, skip_L,skip_ab); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - ContAllAB (labco, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, cp, Wlvl_ab, Hlvl_ab, useChannelA); + ContAllAB (labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA); } } + + } } @@ -1471,6 +1733,7 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, float *koeLi[9], int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC){ int borderL = 2; +// printf("cpedth=%f\n",cp.eddetthr); if(cp.eddetthr < 30.f) { borderL = 1; // I calculate coefficients with r size matrix 3x3 r=1 ; 5x5 r=2; 7x7 r=3 @@ -1520,8 +1783,11 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa +1.323f*WavCoeffs_LL[dir][(i-1)*W_L + j+1]+1.323f*WavCoeffs_LL[dir][(i+1)*W_L + j-1]+1.323f*WavCoeffs_LL[dir][(i+1)*W_L + j+1]) * 0.06127f; } } - } + } + else if(cp.eddetthr >= 75.f) { + borderL = 2; + for (int i=2; i lees good results==> probably because structure data different and also I compare to original value which have + and - for(int i = borderL; i < H_L-borderL; i++ ) {//[-1 0 1] x==>j @@ -1583,6 +1853,11 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa float thr2=1.5f*edd;//edd can be modified in option ed_detect thr2+=cp.eddet/30.f;//to test float diffFactor = (cp.eddet/100.f); + for(int i = 0; i < H_L; i++ ) { + for(int j = 0; j < W_L; j++) { + koeLi[level*3 + dir-1][i*W_L + j]=1.f; + } + } for(int i = borderL; i < H_L-borderL; i++ ) { for(int j = borderL; j < W_L-borderL; j++) { // my own algo : probably a little false, but simpler as Lipschitz ! @@ -1603,10 +1878,133 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa } + void ImProcFunctions::finalContAllL (int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params cp, + int W_L, int H_L, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili) + { + bool lipschitz=true; + float edge=1.f; + bool curvdiag=true; + if(curvdiag) {//curve + float insigma=0.666f;//SD + float logmax=log(MaxP[level]);//log Max + float rapX=(mean[level]+sigma[level])/MaxP[level];//rapport between sD / max + float inx=log(insigma); + float iny=log(rapX); + float rap=inx/iny;//koef + float asig=0.166f/sigma[level]; + float bsig=0.5f-asig*mean[level]; + float amean=0.5f/mean[level]; + float absciss; + float kinterm; + float kmul; + for (int i=0; i= (mean[level]+sigma[level])){//for max + float valcour=log(fabs(WavCoeffs_L[dir][i])); + float valc=valcour-logmax; + float vald=valc*rap; + absciss=exp(vald); + + } + else if(fabs(WavCoeffs_L[dir][i])>=mean[level] && fabs(WavCoeffs_L[dir][i]) < (mean[level]+sigma[level])){ + absciss=asig*fabs(WavCoeffs_L[dir][i])+bsig; + } + else if(fabs(WavCoeffs_L[dir][i]) < mean[level]){ + absciss=amean*fabs(WavCoeffs_L[dir][i]); + } + kinterm=1.f; + kmul=1.f; + + float kc = kmul*(waOpacityCurveWL[absciss*500.f]-0.5f); + float reduceeffect=1.5f; + if(kc <=0.f) reduceeffect=1.f; + kinterm = 1.f + reduceeffect*kmul*(waOpacityCurveWL[absciss*500.f]-0.5f); + + if(kinterm<0.f) kinterm=0.01f; + } + + WavCoeffs_L[dir][i] *= kinterm; + } + } + int choicelevel = atoi(params->wavelet.Lmethod.data())-1; + choicelevel = choicelevel == -1 ? 4 : choicelevel; + int choiceClevel=0; + if(params->wavelet.CLmethod=="one") choiceClevel=0; + else if(params->wavelet.CLmethod=="inf") choiceClevel=1; + else if(params->wavelet.CLmethod=="sup") choiceClevel=2; + else if(params->wavelet.CLmethod=="all") choiceClevel=3; + int choiceDir=0; + if(params->wavelet.Dirmethod=="one") choiceDir=1; + else if(params->wavelet.Dirmethod=="two") choiceDir=2; + else if(params->wavelet.Dirmethod=="thr") choiceDir=3; + else if(params->wavelet.Dirmethod=="all") choiceDir=0; + + int dir1 = (choiceDir == 2) ? 1 : 2; + int dir2 = (choiceDir == 3) ? 1 : 3; + if(choiceClevel<3) { // not all levels visible, paint residual + if(level == 0) { + if(cp.backm!=2) { // nothing to change when residual is used as background + float backGroundColor = (cp.backm==1) ? 12000.f : 0.f; + for (int i=0; i= choicelevel) { + for (int dir=1; dir<4; dir++) { + for (int i=0; i= choicelevel + if(level >= choicelevel) { + for (int i=0; i= choicelevel + if(level <= choicelevel) { + for (int i=0; i med) it=itplus; + + for(int j=0; j < it; j++) { + //float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + k1=600.f; + k2=300.f; + k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + k2=k1*2.f; + if(dir <3) kba= 1.f + k1; + if(dir==3) kba = 1.f - k2; + + WavCoeffs_L[dir][i] *=(kba); + } + } +} +if(cp.BAmet==1){ + int iteration = cp.ite; + int itplus=7+iteration; + int itmoins= 7-iteration; + int med = maxlvl/2; + int it; + if(level < med) {it=itmoins; } + else if(level == med) it=7; + else if(level > med) it=itplus; + + for(int j=0; j < it; j++) { + float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + float aa=4970.f; + float bb=-397000.f; + float b0=100000.f; + float a0=-4970.f; + if(LL100> 80.f) {k1=aa*LL100 + bb;k2=0.5f*k1;} + if(LL100< 20.f) {k1=a0*LL100 + b0;k2=0.5f*k1;} + //k1=600.f; + //k2=300.f; + //k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + //k2=k1*2.f; + if(dir <3) kba= 1.f + bal/k1; + if(dir==3) kba = 1.f - bal/k2; + + WavCoeffs_L[dir][i] *=(kba); + } + } +} + +} + // to see each level of wavelet ...level from 0 to 8 int choicelevel = atoi(params->wavelet.Lmethod.data())-1; choicelevel = choicelevel == -1 ? 4 : choicelevel; -/* - int choicelevel=0; - if(params->wavelet.Lmethod=="1_") choicelevel=0; - else if(params->wavelet.Lmethod=="2_") choicelevel=1; - else if(params->wavelet.Lmethod=="3_") choicelevel=2; - else if(params->wavelet.Lmethod=="4_") choicelevel=3; - else if(params->wavelet.Lmethod=="5_") choicelevel=4; - else if(params->wavelet.Lmethod=="6_") choicelevel=5; - else if(params->wavelet.Lmethod=="7_") choicelevel=6; - else if(params->wavelet.Lmethod=="8_") choicelevel=7; - else if(params->wavelet.Lmethod=="9_") choicelevel=8; -*/ - int choiceClevel=0; - if(params->wavelet.CLmethod=="one") choiceClevel=0; - else if(params->wavelet.CLmethod=="inf") choiceClevel=1; - else if(params->wavelet.CLmethod=="sup") choiceClevel=2; - else if(params->wavelet.CLmethod=="all") choiceClevel=3; - int choiceDir=0; - if(params->wavelet.Dirmethod=="one") choiceDir=1; - else if(params->wavelet.Dirmethod=="two") choiceDir=2; - else if(params->wavelet.Dirmethod=="thr") choiceDir=3; - else if(params->wavelet.Dirmethod=="all") choiceDir=0; - - int dir1 = (choiceDir == 2) ? 1 : 2; - int dir2 = (choiceDir == 3) ? 1 : 3; - if(choiceClevel<3) { // not all levels visible, paint residual - if(level == 0) { - if(cp.backm!=2) { // nothing to change when residual is used as background - float backGroundColor = (cp.backm==1) ? 12000.f : 0.f; - for (int i=0; i= choicelevel) { - for (int dir=1; dir<4; dir++) { - for (int i=0; i= choicelevel - if(level >= choicelevel) { - for (int i=0; i= choicelevel - if(level <= choicelevel) { - for (int i=0; i med) it=itplus; + + for(int j=0; j < it; j++) { + //float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + k1=600.f; + k2=300.f; + k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + k2=k1*2.f; + if(dir <3) kba= 1.f + k1; + if(dir==3) kba = 1.f - k2; + + WavCoeffs_ab[dir][i] *=(kba); + } + } +} +if(cp.BAmet==1){ + int iteration = cp.ite; + int itplus=7+iteration; + int itmoins= 7-iteration; + int med = maxlvl/2; + int it; + if(level < med) {it=itmoins; } + else if(level == med) it=7; + else if(level > med) it=itplus; + + for(int j=0; j < it; j++) { + float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + float aa=4970.f; + float bb=-397000.f; + float b0=100000.f; + float a0=-4970.f; + if(LL100> 80.f) {k1=aa*LL100 + bb;k2=0.5f*k1;} + if(LL100< 20.f) {k1=a0*LL100 + b0;k2=0.5f*k1;} + //k1=600.f; + //k2=300.f; + //k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + //k2=k1*2.f; + if(dir <3) kba= 1.f + bal/k1; + if(dir==3) kba = 1.f - bal/k2; + + WavCoeffs_ab[dir][i] *=(kba); + } + } +} + +} // to see each level of wavelet ...level from 0 to 8 int choicelevel = atoi(params->wavelet.Lmethod.data())-1; choicelevel = choicelevel == -1 ? 4 : choicelevel; -/* - int choicelevel=0; - if(params->wavelet.Lmethod=="1_") choicelevel=0; - else if(params->wavelet.Lmethod=="2_") choicelevel=1; - else if(params->wavelet.Lmethod=="3_") choicelevel=2; - else if(params->wavelet.Lmethod=="4_") choicelevel=3; - else if(params->wavelet.Lmethod=="5_") choicelevel=4; - else if(params->wavelet.Lmethod=="6_") choicelevel=5; - else if(params->wavelet.Lmethod=="7_") choicelevel=6; - else if(params->wavelet.Lmethod=="8_") choicelevel=7; - else if(params->wavelet.Lmethod=="9_") choicelevel=8; -*/ int choiceClevel=0; if(params->wavelet.CLmethod=="one") choiceClevel=0; else if(params->wavelet.CLmethod=="inf") choiceClevel=1; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index ec45a0130..9c3052dd4 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -385,6 +385,16 @@ enum ProcEvent { EvWavCHCurve=357, EvPreProcessHotDeadThresh=358, EvEPDgamma=359, + EvWavtmr=360, + EvWavTMmet=361, + EvWavtmrs=362, + EvWavbalance=363, + EvWaviter=364, + EvWavgamma=365, + EvWavCLCurve=366, + EvWavopacity=367, + EvWavBAmet=368, + EvWavopacityWL=369, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2aedab246..4ee2762a9 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -42,10 +42,10 @@ extern Options options; namespace rtengine { namespace procparams { - int tr=(int) options.rtSettings.top_right; - int br=(int) options.rtSettings.bot_right; - int tl=(int) options.rtSettings.top_left; - int bl=(int) options.rtSettings.bot_left; + const int tr=(int) options.rtSettings.top_right; + const int br=(int) options.rtSettings.bot_right; + const int tl=(int) options.rtSettings.top_left; + const int bl=(int) options.rtSettings.bot_left; const char *RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::numMethods]={"amaze","igv","lmmse","eahd", "hphd", "vng4", "dcb", "ahd", "fast", "mono", "none" }; const char *RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::numMethods]={"3-pass (best)", "1-pass (medium)", "fast", "mono", "none" }; @@ -421,7 +421,7 @@ void ColorToningParams::getCurves(ColorGradientCurve &colorCurveLUT, OpacityCurv //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){ 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(bl, tl, br, tr, false), level0noise(0, 0, false),level1noise(0, 0, false), level2noise(0, 0, false){ + pastlev(0, 2, 30, 20, false), satlev(30, 45, 130, 100, false), edgcont(bl, tl, br, tr, false), /* edgcont(0, 10, 75, 40, false),*/level0noise(0, 0, false),level1noise(0, 0, false), level2noise(0, 0, false){ setDefaults (); } @@ -445,6 +445,32 @@ void WaveletParams::getDefaultOpacityCurveBY(std::vector &curve) { } +void WaveletParams::getDefaultOpacityCurveW(std::vector &curve) { + double v[16]={ 0.00, 0.35, 0.35, 0.00, + 0.35, 0.75, 0.35, 0.35, + 0.60, 0.75, 0.35, 0.35, + 1.00, 0.35, 0.00, 0.00 }; + curve.resize(17); + curve.at(0) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + double v[8]= { 0.0, 0.50,0.35,0.35, + 1.00, 0.50,0.35,0.35}; + + /*double v[12]={ 0.00, 0.53, 0.35, 0.00, + 0.42, 0.53, 0.35, 0.35, + 1.00, 0.15, 0.00, 0.00 }; + */ + curve.resize(9); + curve.at(0) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { double v[12]= { 0.0, 0.25, 0.35, 0.35, 0.50, 0.75, 0.35, 0.35, 0.90, 0.0, 0.35, 0.35}; @@ -456,16 +482,21 @@ void WaveletParams::getDefaultCCWCurve(std::vector &curve) { } -void WaveletParams::getCurves(WavCurve &cCurve, WavOpacityCurveRG &opacityCurveLUTRG, WavOpacityCurveBY &opacityCurveLUTBY) const { +void WaveletParams::getCurves(WavCurve &cCurve, WavOpacityCurveRG &opacityCurveLUTRG, WavOpacityCurveBY &opacityCurveLUTBY, WavOpacityCurveW &opacityCurveLUTW, WavOpacityCurveWL &opacityCurveLUTWL) const { cCurve.Set(this->ccwcurve); opacityCurveLUTRG.Set(this->opacityCurveRG); - opacityCurveLUTBY.Set(this->opacityCurveBY); + opacityCurveLUTBY.Set(this->opacityCurveBY); + opacityCurveLUTW.Set(this->opacityCurveW); + opacityCurveLUTWL.Set(this->opacityCurveWL); + } void WaveletParams::setDefaults() { getDefaultCCWCurve(ccwcurve); getDefaultOpacityCurveRG(opacityCurveRG); getDefaultOpacityCurveBY(opacityCurveBY); + getDefaultOpacityCurveW(opacityCurveW); + getDefaultOpacityCurveWL(opacityCurveWL); enabled = false; median = false; medianlev = false; @@ -473,11 +504,19 @@ void WaveletParams::setDefaults() { lipst = false; Medgreinf = "none"; avoid = false; + tmr = false; strength = 100; + balance = 0; + iter = 0; + wavclCurve.clear (); + wavclCurve.push_back(DCT_Linear); + Lmethod = "4_"; CHmethod = "without"; CHSLmethod = "SL"; EDmethod = "CU"; + BAmethod = "none"; + TMmethod = "none"; HSmethod = "with"; CLmethod = "all"; Backmethod = "grey"; @@ -487,6 +526,8 @@ void WaveletParams::setDefaults() { rescon = 0; resconH = 0; reschro = 0; + tmrs = 0; + gamma = 1; sky = 0.; sup = 0; thres = 7; @@ -510,7 +551,8 @@ void WaveletParams::setDefaults() { bllev.setValues(0, 2, 50, 25); pastlev.setValues(0, 2, 30, 20); satlev.setValues(30, 45, 130, 100); - edgcont.setValues(bl, tl, br, tr); +// edgcont.setValues(bl, tl, br, tr); + edgcont.setValues(0, 10, 75, 40); level0noise.setValues(0, 0); level1noise.setValues(0, 0); level2noise.setValues(0, 0); @@ -846,10 +888,10 @@ void ProcParams::setDefaults () { dirpyrDenoise.setDefaults(); epd.enabled = false; - epd.strength = 0.8; + epd.strength = 0.5; epd.gamma = 1.0; epd.edgeStopping = 1.4; - epd.scale = 1.0; + epd.scale = 0.3; epd.reweightingIterates = 0; sh.enabled = false; @@ -1549,6 +1591,8 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol // save wavelet parameters if (!pedited || pedited->wavelet.enabled) keyFile.set_boolean ("Wavelet", "Enabled", wavelet.enabled); if (!pedited || pedited->wavelet.strength) keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); + if (!pedited || pedited->wavelet.balance) keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); + if (!pedited || pedited->wavelet.iter) keyFile.set_integer ("Wavelet", "Iter", wavelet.iter); if (!pedited || pedited->wavelet.thres) keyFile.set_integer ("Wavelet", "MaxLev", wavelet.thres); if (!pedited || pedited->wavelet.Tilesmethod) keyFile.set_string ("Wavelet", "TilesMethod", wavelet.Tilesmethod); if (!pedited || pedited->wavelet.choicemethod) keyFile.set_string ("Wavelet", "DaubMethod", wavelet.choicemethod); @@ -1606,6 +1650,8 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->wavelet.Medgreinf) keyFile.set_string ("Wavelet", "Medgreinf", wavelet.Medgreinf); if (!pedited || pedited->wavelet.CHSLmethod) keyFile.set_string ("Wavelet", "CHSLromaMethod", wavelet.CHSLmethod); if (!pedited || pedited->wavelet.EDmethod) keyFile.set_string ("Wavelet", "EDMethod", wavelet.EDmethod); + if (!pedited || pedited->wavelet.BAmethod) keyFile.set_string ("Wavelet", "BAMethod", wavelet.BAmethod); + if (!pedited || pedited->wavelet.TMmethod) keyFile.set_string ("Wavelet", "TMMethod", wavelet.TMmethod); if (!pedited || pedited->wavelet.chro) keyFile.set_integer ("Wavelet", "ChromaLink", wavelet.chro); if (!pedited || pedited->wavelet.ccwcurve) { Glib::ArrayHandle ccwcurve = wavelet.ccwcurve; @@ -1628,6 +1674,15 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol Glib::ArrayHandle curve = wavelet.opacityCurveBY; keyFile.set_double_list("Wavelet", "OpacityCurveBY", curve); } + if (!pedited || pedited->wavelet.opacityCurveW) { + Glib::ArrayHandle curve = wavelet.opacityCurveW; + keyFile.set_double_list("Wavelet", "OpacityCurveW", curve); + } + if (!pedited || pedited->wavelet.opacityCurveWL) { + Glib::ArrayHandle curve = wavelet.opacityCurveWL; + keyFile.set_double_list("Wavelet", "OpacityCurveWL", curve); + } + if (!pedited || pedited->wavelet.hhcurve) { Glib::ArrayHandle curve = wavelet.hhcurve; keyFile.set_double_list("Wavelet", "HHcurve", curve); @@ -1636,6 +1691,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol Glib::ArrayHandle curve = wavelet.Chcurve; keyFile.set_double_list("Wavelet", "CHcurve", curve); } + if (!pedited || pedited->wavelet.wavclCurve) { + Glib::ArrayHandle wavclCurve = wavelet.wavclCurve; + keyFile.set_double_list("Wavelet", "WavclCurve", wavclCurve); + } if (!pedited || pedited->wavelet.median) keyFile.set_boolean ("Wavelet", "Median", wavelet.median); @@ -1652,14 +1711,18 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->wavelet.edgrad) keyFile.set_integer ("Wavelet", "Edgrad", wavelet.edgrad); if (!pedited || pedited->wavelet.edgval) keyFile.set_integer ("Wavelet", "Edgval", wavelet.edgval); if (!pedited || pedited->wavelet.edgthresh) keyFile.set_integer ("Wavelet", "ThrEdg", wavelet.edgthresh); - if (!pedited || pedited->wavelet.strength) keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); + // if (!pedited || pedited->wavelet.strength) keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); + // if (!pedited || pedited->wavelet.balance) keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); if (!pedited || pedited->wavelet.avoid) keyFile.set_boolean ("Wavelet", "AvoidColorShift", wavelet.avoid); + if (!pedited || pedited->wavelet.tmr) keyFile.set_boolean ("Wavelet", "TMr", wavelet.tmr); if (!pedited || pedited->wavelet.rescon) keyFile.set_integer ("Wavelet", "ResidualcontShadow", wavelet.rescon); if (!pedited || pedited->wavelet.resconH) keyFile.set_integer ("Wavelet", "ResidualcontHighlight", wavelet.resconH); if (!pedited || pedited->wavelet.thr) keyFile.set_integer ("Wavelet", "ThresholdResidShadow", wavelet.thr); if (!pedited || pedited->wavelet.thrH) keyFile.set_integer ("Wavelet", "ThresholdResidHighLight", wavelet.thrH); if (!pedited || pedited->wavelet.reschro) keyFile.set_integer ("Wavelet", "Residualchroma", wavelet.reschro); + if (!pedited || pedited->wavelet.tmrs) keyFile.set_double ("Wavelet", "ResidualTM", wavelet.tmrs); + if (!pedited || pedited->wavelet.gamma) keyFile.set_double ("Wavelet", "Residualgamma", wavelet.gamma); if (!pedited || pedited->wavelet.sky) keyFile.set_double ("Wavelet", "HueRangeResidual", wavelet.sky); if (!pedited || pedited->wavelet.hueskin2) { Glib::ArrayHandle thresh (wavelet.hueskin2.value, 4, Glib::OWNERSHIP_NONE); @@ -2388,12 +2451,15 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_group ("Wavelet")) { if (keyFile.has_key ("Wavelet", "Enabled")) { wavelet.enabled = keyFile.get_boolean ("Wavelet", "Enabled"); if (pedited) pedited->wavelet.enabled = true; } if (keyFile.has_key ("Wavelet", "Strength")) { wavelet.strength = keyFile.get_integer ("Wavelet", "Strength"); if (pedited) pedited->wavelet.strength = true; } + if (keyFile.has_key ("Wavelet", "Balance")) { wavelet.balance = keyFile.get_integer ("Wavelet", "Balance"); if (pedited) pedited->wavelet.balance = true; } + if (keyFile.has_key ("Wavelet", "Iter")) { wavelet.iter = keyFile.get_integer ("Wavelet", "Iter"); if (pedited) pedited->wavelet.iter = true; } if (keyFile.has_key ("Wavelet", "Median")) {wavelet.median = keyFile.get_boolean ("Wavelet", "Median");if (pedited) pedited->wavelet.median = true;} if (keyFile.has_key ("Wavelet", "Medianlev")) {wavelet.medianlev = keyFile.get_boolean ("Wavelet", "Medianlev");if (pedited) pedited->wavelet.medianlev = true;} if (keyFile.has_key ("Wavelet", "Linkedg")) {wavelet.linkedg = keyFile.get_boolean ("Wavelet", "Linkedg");if (pedited) pedited->wavelet.linkedg = true;} // if (keyFile.has_key ("Wavelet", "Edgreinf")) {wavelet.edgreinf = keyFile.get_boolean ("Wavelet", "Edgreinf");if (pedited) pedited->wavelet.edgreinf = true;} if (keyFile.has_key ("Wavelet", "Lipst")) {wavelet.lipst = keyFile.get_boolean ("Wavelet", "Lipst");if (pedited) pedited->wavelet.lipst = true;} if (keyFile.has_key ("Wavelet", "AvoidColorShift")) {wavelet.avoid = keyFile.get_boolean ("Wavelet", "AvoidColorShift");if (pedited) pedited->wavelet.avoid = true;} + if (keyFile.has_key ("Wavelet", "TMr")) {wavelet.tmr = keyFile.get_boolean ("Wavelet", "TMr");if (pedited) pedited->wavelet.tmr = true;} if (keyFile.has_key ("Wavelet", "LevMethod")) {wavelet.Lmethod = keyFile.get_string ("Wavelet", "LevMethod"); if (pedited) pedited->wavelet.Lmethod = true; } if (keyFile.has_key ("Wavelet", "ChoiceLevMethod")) {wavelet.CLmethod = keyFile.get_string ("Wavelet", "ChoiceLevMethod"); if (pedited) pedited->wavelet.CLmethod = true; } if (keyFile.has_key ("Wavelet", "BackMethod")) {wavelet.Backmethod = keyFile.get_string ("Wavelet", "BackMethod"); if (pedited) pedited->wavelet.Backmethod = true; } @@ -2403,11 +2469,15 @@ if (keyFile.has_group ("Wavelet")) { if (keyFile.has_key ("Wavelet", "Medgreinf")) {wavelet.Medgreinf = keyFile.get_string ("Wavelet", "Medgreinf"); if (pedited) pedited->wavelet.Medgreinf = true; } if (keyFile.has_key ("Wavelet", "CHSLromaMethod")) {wavelet.CHSLmethod = keyFile.get_string ("Wavelet", "CHSLromaMethod"); if (pedited) pedited->wavelet.CHSLmethod = true; } if (keyFile.has_key ("Wavelet", "EDMethod")) {wavelet.EDmethod = keyFile.get_string ("Wavelet", "EDMethod"); if (pedited) pedited->wavelet.EDmethod = true; } + if (keyFile.has_key ("Wavelet", "BAMethod")) {wavelet.BAmethod = keyFile.get_string ("Wavelet", "BAMethod"); if (pedited) pedited->wavelet.BAmethod = true; } + if (keyFile.has_key ("Wavelet", "TMMethod")) {wavelet.TMmethod = keyFile.get_string ("Wavelet", "TMMethod"); if (pedited) pedited->wavelet.TMmethod = true; } if (keyFile.has_key ("Wavelet", "HSMethod")) {wavelet.HSmethod = keyFile.get_string ("Wavelet", "HSMethod"); if (pedited) pedited->wavelet.HSmethod = true; } if (keyFile.has_key ("Wavelet", "DirMethod")) {wavelet.Dirmethod = keyFile.get_string ("Wavelet", "DirMethod"); if (pedited) pedited->wavelet.Dirmethod = true; } if (keyFile.has_key ("Wavelet", "ResidualcontShadow")) {wavelet.rescon = keyFile.get_integer ("Wavelet", "ResidualcontShadow"); if (pedited) pedited->wavelet.rescon = true; } if (keyFile.has_key ("Wavelet", "ResidualcontHighlight")) {wavelet.resconH = keyFile.get_integer ("Wavelet", "ResidualcontHighlight"); if (pedited) pedited->wavelet.resconH = true; } if (keyFile.has_key ("Wavelet", "Residualchroma")) {wavelet.reschro = keyFile.get_integer ("Wavelet", "Residualchroma"); if (pedited) pedited->wavelet.reschro = true; } + if (keyFile.has_key ("Wavelet", "ResidualTM")) {wavelet.tmrs = keyFile.get_double ("Wavelet", "ResidualTM"); if (pedited) pedited->wavelet.tmrs = true; } + if (keyFile.has_key ("Wavelet", "Residualgamma")) {wavelet.gamma = keyFile.get_double ("Wavelet", "Residualgamma"); if (pedited) pedited->wavelet.gamma = true; } if (keyFile.has_key ("Wavelet", "ContExtra")) {wavelet.sup = keyFile.get_integer ("Wavelet", "ContExtra"); if (pedited) pedited->wavelet.sup = true; } if (keyFile.has_key ("Wavelet", "HueRangeResidual")) {wavelet.sky = keyFile.get_double ("Wavelet", "HueRangeResidual"); if (pedited) pedited->wavelet.sky = true; } if (keyFile.has_key ("Wavelet", "MaxLev")) {wavelet.thres = keyFile.get_integer ("Wavelet", "MaxLev"); if (pedited) pedited->wavelet.thres = true; } @@ -2427,8 +2497,11 @@ if (keyFile.has_group ("Wavelet")) { if (keyFile.has_key ("Wavelet", "ContrastCurve")) {wavelet.ccwcurve = keyFile.get_double_list ("Wavelet", "ContrastCurve"); if (pedited) pedited->wavelet.ccwcurve = true; } if (keyFile.has_key ("Wavelet", "OpacityCurveRG")) { wavelet.opacityCurveRG = keyFile.get_double_list ("Wavelet", "OpacityCurveRG"); if (pedited) pedited->wavelet.opacityCurveRG = true; } if (keyFile.has_key ("Wavelet", "OpacityCurveBY")) { wavelet.opacityCurveBY = keyFile.get_double_list ("Wavelet", "OpacityCurveBY"); if (pedited) pedited->wavelet.opacityCurveBY = true; } + if (keyFile.has_key ("Wavelet", "OpacityCurveW")) { wavelet.opacityCurveW = keyFile.get_double_list ("Wavelet", "OpacityCurveW"); if (pedited) pedited->wavelet.opacityCurveW = true; } + if (keyFile.has_key ("Wavelet", "OpacityCurveWL")) { wavelet.opacityCurveWL = keyFile.get_double_list ("Wavelet", "OpacityCurveWL"); if (pedited) pedited->wavelet.opacityCurveWL = true; } if (keyFile.has_key ("Wavelet", "HHcurve")) { wavelet.hhcurve = keyFile.get_double_list ("Wavelet", "HHcurve"); if (pedited) pedited->wavelet.hhcurve = true; } if (keyFile.has_key ("Wavelet", "CHcurve")) { wavelet.Chcurve = keyFile.get_double_list ("Wavelet", "CHcurve"); if (pedited) pedited->wavelet.Chcurve = true; } + if (keyFile.has_key ("Wavelet", "WavclCurve")) { wavelet.wavclCurve = keyFile.get_double_list ("Wavelet", "WavclCurve"); if (pedited) pedited->wavelet.wavclCurve = true; } if (keyFile.has_key ("Wavelet", "Hueskin")) { Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Hueskin"); wavelet.hueskin.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); @@ -3034,17 +3107,22 @@ bool ProcParams::operator== (const ProcParams& other) { && wavelet.CHmethod == other.wavelet.CHmethod && wavelet.CHSLmethod == other.wavelet.CHSLmethod && wavelet.EDmethod == other.wavelet.EDmethod + && wavelet.BAmethod == other.wavelet.BAmethod + && wavelet.TMmethod == other.wavelet.TMmethod && wavelet.HSmethod == other.wavelet.HSmethod && wavelet.Dirmethod == other.wavelet.Dirmethod && wavelet.rescon == other.wavelet.rescon && wavelet.resconH == other.wavelet.resconH && wavelet.reschro == other.wavelet.reschro + && wavelet.tmrs == other.wavelet.tmrs + && wavelet.gamma == other.wavelet.gamma && wavelet.sup == other.wavelet.sup && wavelet.sky == other.wavelet.sky && wavelet.thres == other.wavelet.thres && wavelet.threshold == other.wavelet.threshold && wavelet.chroma == other.wavelet.chroma && wavelet.chro == other.wavelet.chro + && wavelet.tmr == other.wavelet.tmr && wavelet.contrast == other.wavelet.contrast && wavelet.median == other.wavelet.median && wavelet.medianlev == other.wavelet.medianlev @@ -3073,11 +3151,16 @@ bool ProcParams::operator== (const ProcParams& other) { && wavelet.satlev == other.wavelet.satlev && wavelet.opacityCurveRG == other.wavelet.opacityCurveRG && wavelet.opacityCurveBY == other.wavelet.opacityCurveBY + && wavelet.opacityCurveW == other.wavelet.opacityCurveW + && wavelet.opacityCurveWL == other.wavelet.opacityCurveWL && wavelet.hhcurve == other.wavelet.hhcurve && wavelet.Chcurve == other.wavelet.Chcurve && wavelet.ccwcurve == other.wavelet.ccwcurve + && wavelet.wavclCurve == other.wavelet.wavclCurve && wavelet.skinprotect == other.wavelet.skinprotect && wavelet.strength == other.wavelet.strength + && wavelet.balance == other.wavelet.balance + && wavelet.iter == other.wavelet.iter && dirpyrequalizer == other.dirpyrequalizer // && dirpyrequalizer.algo == other.dirpyrequalizer.algo && dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6e0901e0a..b328215d7 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -36,6 +36,8 @@ class NoiseCurve; class WavCurve; class WavOpacityCurveRG; class WavOpacityCurveBY; +class WavOpacityCurveW; +class WavOpacityCurveWL; namespace procparams { @@ -861,8 +863,11 @@ class WaveletParams { std::vector ccwcurve; std::vector opacityCurveRG; std::vector opacityCurveBY; + std::vector opacityCurveW; + std::vector opacityCurveWL; std::vector hhcurve; std::vector Chcurve; + std::vector wavclCurve; bool enabled; bool median; bool medianlev; @@ -870,7 +875,10 @@ class WaveletParams { bool lipst; // bool edgreinf; bool avoid; + bool tmr; int strength; + int balance; + int iter; int c[9]; int ch[9]; @@ -883,11 +891,15 @@ class WaveletParams { Glib::ustring Medgreinf; Glib::ustring CHSLmethod; Glib::ustring EDmethod; + Glib::ustring BAmethod; + Glib::ustring TMmethod; Glib::ustring Dirmethod; Glib::ustring HSmethod; int rescon; int resconH; int reschro; + double tmrs; + double gamma; int sup; double sky; int thres; @@ -919,10 +931,12 @@ class WaveletParams { WaveletParams (); void setDefaults(); - void getCurves(WavCurve &cCurve,WavOpacityCurveRG &opacityCurveLUTRG , WavOpacityCurveBY &opacityCurveLUTBY) const; + void getCurves(WavCurve &cCurve,WavOpacityCurveRG &opacityCurveLUTRG , WavOpacityCurveBY &opacityCurveLUTBY, WavOpacityCurveW &opacityCurveLUTW, WavOpacityCurveWL &opacityCurveLUTWL) const; static void getDefaultCCWCurve(std::vector &curve); static void getDefaultOpacityCurveRG(std::vector &curve); static void getDefaultOpacityCurveBY(std::vector &curve); + static void getDefaultOpacityCurveW(std::vector &curve); + static void getDefaultOpacityCurveWL(std::vector &curve); }; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index fd9bfefdb..cadb91064 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -381,7 +381,16 @@ DIRPYREQUALIZER, //EvWavedgedetectthr2 DIRPYREQUALIZER, //EvWavlinkedg DIRPYREQUALIZER, //EvWavCHCurve DARKFRAME, //EvPreProcessHotDeadThresh -SHARPENING //EvEPDgamma - +SHARPENING, //EvEPDgamma +DIRPYREQUALIZER, //EvWavtmr +DIRPYREQUALIZER, //EvWavTMmet +DIRPYREQUALIZER, //EvWavtmrs +DIRPYREQUALIZER, //EvWavbalance +DIRPYREQUALIZER, //EvWaviter +DIRPYREQUALIZER, //EvWavgamma +DIRPYREQUALIZER, //EvWavCLCurve +DIRPYREQUALIZER, //EvWavopacity +DIRPYREQUALIZER, //EvWavBAmet +DIRPYREQUALIZER //EvWavopacityWL }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1e093fd34..73a3d5643 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -193,13 +193,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw ); // we only need image reduced to 1/4 here - for(int ii=0;iir(ii>>1,jj>>1) = origCropPart->r(ii,jj); provicalc->g(ii>>1,jj>>1) = origCropPart->g(ii,jj); provicalc->b(ii>>1,jj>>1) = origCropPart->b(ii,jj); } - } + } imgsrc->convertColorSpace(provicalc, params.icm, currWB, params.raw);//for denoise luminance curve float maxr=0.f; float maxb=0.f; @@ -349,13 +349,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p PreviewProps ppP (coordW[wcr] , coordH[hcr], crW, crH, 1); imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw); // we only need image reduced to 1/4 here - for(int ii=0;iir(ii>>1,jj>>1) = origCropPart->r(ii,jj); provicalc->g(ii>>1,jj>>1) = origCropPart->g(ii,jj); provicalc->b(ii>>1,jj>>1) = origCropPart->b(ii,jj); } - } + } imgsrc->convertColorSpace(provicalc, params.icm, currWB, params.raw);//for denoise luminance curve int nb = 0; float chaut=0.f, redaut=0.f, blueaut=0.f, maxredaut=0.f, maxblueaut=0.f, minredaut=0.f, minblueaut=0.f, nresi=0.f, highresi=0.f, chromina=0.f, sigma=0.f, lumema=0.f, sigma_L=0.f, redyel=0.f, skinc=0.f, nsknc=0.f; @@ -527,13 +527,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // we only need image reduced to 1/4 here calclum = new Imagefloat ((fw+1)/2, (fh+1)/2);//for luminance denoise curve #pragma omp parallel for - for(int ii=0;iir(ii>>1,jj>>1) = baseImg->r(ii,jj); calclum->g(ii>>1,jj>>1) = baseImg->g(ii,jj); calclum->b(ii>>1,jj>>1) = baseImg->b(ii,jj); } - } + } imgsrc->convertColorSpace(calclum, params.icm, currWB, params.raw); } if (denoiseParams.enabled) { @@ -596,6 +596,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p LUTf clcurve (65536,0); LUTf clToningcurve (65536,0); LUTf cl2Toningcurve (65536,0); + LUTf wavclCurve (65536,0); LUTf rCurve (65536,0); LUTf gCurve (65536,0); @@ -773,13 +774,19 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p WavCurve wavCLVCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; + WavOpacityCurveW waOpacityCurveW; + WavOpacityCurveWL waOpacityCurveWL; - params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY); + params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL ); // directional pyramid wavelet if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) ipf.dirpyrequalizer (labView, 1);//TODO: this is the luminance tonecurve, not the RGB one int kall=2; - if((params.wavelet.enabled)) ipf.ip_wavelet(labView, labView, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, 1); + bool wavcontlutili=false; + + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); + + if((params.wavelet.enabled)) ipf.ip_wavelet(labView, labView, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, wavcontlutili, 1); wavCLVCurve.Reset(); //Colorappearance and tone-mapping associated diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index b851e620e..f9d6b6ef1 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -105,8 +105,10 @@ #define ADDSET_WA_EDGEDETECT 97 #define ADDSET_WA_EDGEDETECTTHR 98 #define ADDSET_WA_EDGEDETECTTHR2 99 +#define ADDSET_WA_TMRS 100 +#define ADDSET_WA_GAMMA 101 // When adding items, make sure to update ADDSET_PARAM_NUM -#define ADDSET_PARAM_NUM 100 // THIS IS USED AS A DELIMITER!! +#define ADDSET_PARAM_NUM 102 // THIS IS USED AS A DELIMITER!! #endif diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 4cbea64b1..c8be105f2 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -148,7 +148,7 @@ void BatchToolPanelCoordinator::initSession () { shadowshighlights->setAdjusterBehavior (false, false, false); dirpyrequalizer->setAdjusterBehavior (false, false, false); - wavelet->setAdjusterBehavior (false, false, false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false, false, false); + wavelet->setAdjusterBehavior (false, false, false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false, false, false); dirpyrdenoise->setAdjusterBehavior (false, false,false,false,false,false, false); bayerpreprocess->setAdjusterBehavior (false, false); rawcacorrection->setAdjusterBehavior (false); @@ -186,7 +186,7 @@ void BatchToolPanelCoordinator::initSession () { blackwhite->setAdjusterBehavior (options.baBehav[ADDSET_BLACKWHITE_HUES],options.baBehav[ADDSET_BLACKWHITE_GAMMA]); shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ], options.baBehav[ADDSET_DIRPYREQ_THRESHOLD], options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]); - wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2],options.baBehav[ADDSET_WA_THRES],options.baBehav[ADDSET_WA_CHRO],options.baBehav[ADDSET_WA_CHROMA],options.baBehav[ADDSET_WA_CONTRAST],options.baBehav[ADDSET_WA_SKINPROTECT],options.baBehav[ADDSET_WA_RESCHRO],options.baBehav[ADDSET_WA_RESCON],options.baBehav[ADDSET_WA_RESCONH],options.baBehav[ADDSET_WA_THRR],options.baBehav[ADDSET_WA_THRRH],options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD],options.baBehav[ADDSET_WA_EDGVAL],options.baBehav[ADDSET_WA_STRENGTH],options.baBehav[ADDSET_WA_EDGEDETECT], options.baBehav[ADDSET_WA_EDGEDETECTTHR], options.baBehav[ADDSET_WA_EDGEDETECTTHR2]); + wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2],options.baBehav[ADDSET_WA_THRES],options.baBehav[ADDSET_WA_CHRO],options.baBehav[ADDSET_WA_CHROMA],options.baBehav[ADDSET_WA_CONTRAST],options.baBehav[ADDSET_WA_SKINPROTECT],options.baBehav[ADDSET_WA_RESCHRO],options.baBehav[ADDSET_WA_TMRS],options.baBehav[ADDSET_WA_RESCON],options.baBehav[ADDSET_WA_RESCONH],options.baBehav[ADDSET_WA_THRR],options.baBehav[ADDSET_WA_THRRH],options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD],options.baBehav[ADDSET_WA_EDGVAL],options.baBehav[ADDSET_WA_STRENGTH],options.baBehav[ADDSET_WA_GAMMA],options.baBehav[ADDSET_WA_EDGEDETECT], options.baBehav[ADDSET_WA_EDGEDETECTTHR], options.baBehav[ADDSET_WA_EDGEDETECTTHR2]); dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_LUMA],options.baBehav[ADDSET_DIRPYRDN_LUMDET],options.baBehav[ADDSET_DIRPYRDN_CHROMA],options.baBehav[ADDSET_DIRPYRDN_CHROMARED],options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE], options.baBehav[ADDSET_DIRPYRDN_GAMMA], options.baBehav[ADDSET_DIRPYRDN_PASSES]); bayerpreprocess->setAdjusterBehavior (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE], options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]); rawcacorrection->setAdjusterBehavior (options.baBehav[ADDSET_RAWCACORR]); @@ -298,6 +298,7 @@ void BatchToolPanelCoordinator::initSession () { if (options.baBehav[ADDSET_WA_RESCON]) pparams.wavelet.rescon = 0; if (options.baBehav[ADDSET_WA_RESCONH]) pparams.wavelet.resconH = 0; if (options.baBehav[ADDSET_WA_RESCHRO]) pparams.wavelet.reschro = 0; + if (options.baBehav[ADDSET_WA_TMRS]) pparams.wavelet.tmrs = 0; if (options.baBehav[ADDSET_WA_THRR]) pparams.wavelet.thr = 0; if (options.baBehav[ADDSET_WA_THRRH]) pparams.wavelet.thrH = 0; if (options.baBehav[ADDSET_WA_SKYPROTECT]) pparams.wavelet.sky = 0; @@ -305,6 +306,7 @@ void BatchToolPanelCoordinator::initSession () { if (options.baBehav[ADDSET_WA_EDGVAL]) pparams.wavelet.edgval = 0; if (options.baBehav[ADDSET_WA_STRENGTH]) pparams.wavelet.strength = 0; if (options.baBehav[ADDSET_WA_EDGEDETECT]) pparams.wavelet.edgedetect = 0; + if (options.baBehav[ADDSET_WA_GAMMA]) pparams.wavelet.gamma = 0; if (options.baBehav[ADDSET_DIRPYRDN_LUMA]) pparams.dirpyrDenoise.luma = 0; diff --git a/rtgui/epd.cc b/rtgui/epd.cc index f20a66c13..34f6a6842 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -27,10 +27,10 @@ EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPa setEnabledTooltipMarkup(M("TP_EPD_TOOLTIP")); - strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.8)); + strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.5)); gamma = Gtk::manage(new Adjuster (M("TP_EPD_GAMMA"), 0.8, 1.5, 0.01, 1.)); edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4)); - scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 1.0)); + scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 0.3)); reweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0)); strength->setAdjusterListener(this); @@ -65,7 +65,11 @@ void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdite } setEnabled(pp->epd.enabled); - + strength->set_sensitive (true); + if(pp->wavelet.enabled){ + if(pp->wavelet.tmrs==0) {strength->set_sensitive (true);gamma->set_sensitive (true);} + else {strength->set_sensitive (false);gamma->set_sensitive (false);} + } strength->setValue(pp->epd.strength); gamma->setValue(pp->epd.gamma); edgeStopping->setValue(pp->epd.edgeStopping); @@ -82,7 +86,10 @@ void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited) pp->epd.scale = scale->getValue(); pp->epd.reweightingIterates = reweightingIterates->getValue(); pp->epd.enabled = getEnabled(); - + strength->set_sensitive (true); + if(pp->wavelet.enabled){ + if(pp->wavelet.tmrs==0) {strength->set_sensitive (true);gamma->set_sensitive (true);} else {strength->set_sensitive (false);gamma->set_sensitive (false);} + } if(pedited){ pedited->epd.strength = strength->getEditedState(); pedited->epd.gamma = gamma->getEditedState(); diff --git a/rtgui/options.cc b/rtgui/options.cc index 7e3d939a5..218dba886 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -537,6 +537,8 @@ void Options::setDefaults () { 0, //ADDSET_WA_EDGEDETECT 0, //ADDSET_WA_EDGEDETECTTHR 0, //ADDSET_WA_EDGEDETECTTHR2 + 0, //ADDSET_WA_TMRS + 0, //ADDSET_WA_GAMMA }; baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 83fe14d82..3037da47b 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -338,12 +338,15 @@ void ParamsEdited::set (bool v) { raw.exPreser = v; wavelet.enabled = v; wavelet.strength = v; + wavelet.balance = v; + wavelet.iter = v; wavelet.median = v; wavelet.medianlev = v; wavelet.linkedg = v; wavelet.lipst = v; wavelet.Medgreinf = v; wavelet.avoid = v; + wavelet.tmr = v; wavelet.Lmethod = v; wavelet.CLmethod = v; wavelet.Backmethod = v; @@ -352,11 +355,15 @@ void ParamsEdited::set (bool v) { wavelet.CHmethod = v; wavelet.CHSLmethod = v; wavelet.EDmethod = v; + wavelet.BAmethod = v; + wavelet.TMmethod = v; wavelet.HSmethod = v; wavelet.Dirmethod = v; wavelet.rescon = v; wavelet.resconH = v; wavelet.reschro = v; + wavelet.tmrs = v; + wavelet.gamma = v; wavelet.sup = v; wavelet.sky = v; wavelet.thres = v; @@ -385,8 +392,12 @@ void ParamsEdited::set (bool v) { wavelet.ccwcurve = v; wavelet.opacityCurveRG = v; wavelet.opacityCurveBY = v; + wavelet.opacityCurveW = v; + wavelet.opacityCurveWL = v; wavelet.hhcurve = v; wavelet.Chcurve = v; + wavelet.wavclCurve = v; + wavelet.pastlev = v; wavelet.satlev = v; @@ -737,12 +748,15 @@ void ParamsEdited::initFrom (const std::vector raw.exPreser = raw.exPreser && p.raw.preser == other.raw.preser; wavelet.enabled = wavelet.enabled && p.wavelet.enabled == other.wavelet.enabled; wavelet.strength = wavelet.strength && p.wavelet.strength == other.wavelet.strength; + wavelet.balance = wavelet.balance && p.wavelet.balance == other.wavelet.balance; + wavelet.iter = wavelet.iter && p.wavelet.iter == other.wavelet.iter; wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median; wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev; wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg; wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst; wavelet.Medgreinf = wavelet.Medgreinf && p.wavelet.Medgreinf == other.wavelet.Medgreinf; wavelet.avoid = wavelet.avoid && p.wavelet.avoid == other.wavelet.avoid; + wavelet.tmr = wavelet.tmr && p.wavelet.tmr == other.wavelet.tmr; wavelet.Lmethod = wavelet.Lmethod && p.wavelet.Lmethod == other.wavelet.Lmethod; wavelet.CLmethod = wavelet.CLmethod && p.wavelet.CLmethod == other.wavelet.CLmethod; wavelet.Backmethod = wavelet.Backmethod && p.wavelet.Backmethod == other.wavelet.Backmethod; @@ -751,11 +765,15 @@ void ParamsEdited::initFrom (const std::vector wavelet.CHmethod = wavelet.CHmethod && p.wavelet.CHmethod == other.wavelet.CHmethod; wavelet.CHSLmethod = wavelet.CHSLmethod && p.wavelet.CHSLmethod == other.wavelet.CHSLmethod; wavelet.EDmethod = wavelet.EDmethod && p.wavelet.EDmethod == other.wavelet.EDmethod; + wavelet.BAmethod = wavelet.BAmethod && p.wavelet.BAmethod == other.wavelet.BAmethod; + wavelet.TMmethod = wavelet.TMmethod && p.wavelet.TMmethod == other.wavelet.TMmethod; wavelet.HSmethod = wavelet.HSmethod && p.wavelet.HSmethod == other.wavelet.HSmethod; wavelet.Dirmethod = wavelet.Dirmethod && p.wavelet.Dirmethod == other.wavelet.Dirmethod; wavelet.rescon = wavelet.rescon && p.wavelet.rescon == other.wavelet.rescon; wavelet.resconH = wavelet.resconH && p.wavelet.resconH == other.wavelet.resconH; wavelet.reschro = wavelet.reschro && p.wavelet.reschro == other.wavelet.reschro; + wavelet.tmrs = wavelet.tmrs && p.wavelet.tmrs == other.wavelet.tmrs; + wavelet.gamma = wavelet.gamma && p.wavelet.gamma == other.wavelet.gamma; wavelet.sup = wavelet.sup && p.wavelet.sup == other.wavelet.sup; wavelet.sky = wavelet.sky && p.wavelet.sky == other.wavelet.sky; wavelet.threshold = wavelet.threshold && p.wavelet.threshold == other.wavelet.threshold; @@ -785,6 +803,9 @@ void ParamsEdited::initFrom (const std::vector wavelet.ccwcurve = wavelet.ccwcurve && p.wavelet.ccwcurve == other.wavelet.ccwcurve; wavelet.opacityCurveRG = wavelet.opacityCurveRG && p.wavelet.opacityCurveRG == other.wavelet.opacityCurveRG; wavelet.opacityCurveBY = wavelet.opacityCurveBY && p.wavelet.opacityCurveBY == other.wavelet.opacityCurveBY; + wavelet.opacityCurveW = wavelet.opacityCurveW && p.wavelet.opacityCurveW == other.wavelet.opacityCurveW; + wavelet.opacityCurveWL = wavelet.opacityCurveWL && p.wavelet.opacityCurveWL == other.wavelet.opacityCurveWL; + wavelet.wavclCurve = wavelet.wavclCurve && p.wavelet.wavclCurve == other.wavelet.wavclCurve; wavelet.hhcurve = wavelet.hhcurve && p.wavelet.hhcurve == other.wavelet.hhcurve; wavelet.Chcurve = wavelet.Chcurve && p.wavelet.Chcurve == other.wavelet.Chcurve; wavelet.skinprotect = wavelet.skinprotect && p.wavelet.skinprotect == other.wavelet.skinprotect; @@ -1141,12 +1162,15 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (raw.ff_clipControl) toEdit.raw.ff_clipControl = dontforceSet && options.baBehav[ADDSET_RAWFFCLIPCONTROL] ? toEdit.raw.ff_clipControl + mods.raw.ff_clipControl : mods.raw.ff_clipControl; if (wavelet.enabled) toEdit.wavelet.enabled = mods.wavelet.enabled; if (wavelet.strength) toEdit.wavelet.strength = mods.wavelet.strength; + if (wavelet.balance) toEdit.wavelet.balance = mods.wavelet.balance; + if (wavelet.iter) toEdit.wavelet.iter = mods.wavelet.iter; if (wavelet.median) toEdit.wavelet.median = mods.wavelet.median; if (wavelet.medianlev) toEdit.wavelet.medianlev = mods.wavelet.medianlev; if (wavelet.linkedg) toEdit.wavelet.linkedg = mods.wavelet.linkedg; if (wavelet.lipst) toEdit.wavelet.lipst = mods.wavelet.lipst; if (wavelet.Medgreinf) toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf; if (wavelet.avoid) toEdit.wavelet.avoid = mods.wavelet.avoid; + if (wavelet.tmr) toEdit.wavelet.tmr = mods.wavelet.tmr; if (wavelet.Lmethod) toEdit.wavelet.Lmethod = mods.wavelet.Lmethod; if (wavelet.CLmethod) toEdit.wavelet.CLmethod = mods.wavelet.CLmethod; if (wavelet.Backmethod) toEdit.wavelet.Backmethod = mods.wavelet.Backmethod; @@ -1155,6 +1179,8 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.CHmethod) toEdit.wavelet.CHmethod = mods.wavelet.CHmethod; if (wavelet.CHSLmethod) toEdit.wavelet.CHSLmethod = mods.wavelet.CHSLmethod; if (wavelet.EDmethod) toEdit.wavelet.EDmethod = mods.wavelet.EDmethod; + if (wavelet.BAmethod) toEdit.wavelet.BAmethod = mods.wavelet.BAmethod; + if (wavelet.TMmethod) toEdit.wavelet.TMmethod = mods.wavelet.TMmethod; if (wavelet.HSmethod) toEdit.wavelet.HSmethod = mods.wavelet.HSmethod; if (wavelet.Dirmethod) toEdit.wavelet.Dirmethod = mods.wavelet.Dirmethod; if (wavelet.edgthresh) toEdit.wavelet.edgthresh = mods.wavelet.edgthresh; @@ -1173,8 +1199,11 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.ccwcurve) toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; if (wavelet.opacityCurveRG) toEdit.wavelet.opacityCurveRG = mods.wavelet.opacityCurveRG; if (wavelet.opacityCurveBY) toEdit.wavelet.opacityCurveBY = mods.wavelet.opacityCurveBY; + if (wavelet.opacityCurveW) toEdit.wavelet.opacityCurveW = mods.wavelet.opacityCurveW; + if (wavelet.opacityCurveWL) toEdit.wavelet.opacityCurveWL = mods.wavelet.opacityCurveWL; if (wavelet.hhcurve) toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; if (wavelet.Chcurve) toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; + if (wavelet.wavclCurve) toEdit.wavelet.wavclCurve = mods.wavelet.wavclCurve; for(int i = 0; i < 9; i++) { if(wavelet.c[i]) toEdit.wavelet.c[i] = dontforceSet && options.baBehav[ADDSET_WA] ? toEdit.wavelet.c[i] + mods.wavelet.c[i] : mods.wavelet.c[i]; } @@ -1186,6 +1215,8 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.hueskin2) toEdit.wavelet.hueskin2 = mods.wavelet.hueskin2; if (wavelet.resconH)toEdit.wavelet.resconH= dontforceSet && options.baBehav[ADDSET_WA_RESCONH] ? toEdit.wavelet.resconH + mods.wavelet.resconH : mods.wavelet.resconH; if (wavelet.reschro)toEdit.wavelet.reschro= dontforceSet && options.baBehav[ADDSET_WA_RESCHRO] ? toEdit.wavelet.reschro + mods.wavelet.reschro : mods.wavelet.reschro; + if (wavelet.tmrs)toEdit.wavelet.tmrs= dontforceSet && options.baBehav[ADDSET_WA_TMRS] ? toEdit.wavelet.tmrs + mods.wavelet.tmrs : mods.wavelet.tmrs; + if (wavelet.gamma)toEdit.wavelet.gamma= dontforceSet && options.baBehav[ADDSET_WA_GAMMA] ? toEdit.wavelet.gamma + mods.wavelet.gamma : mods.wavelet.gamma; if (wavelet.rescon)toEdit.wavelet.rescon= dontforceSet && options.baBehav[ADDSET_WA_RESCON] ? toEdit.wavelet.rescon + mods.wavelet.rescon : mods.wavelet.rescon; if (wavelet.thres)toEdit.wavelet.thres= dontforceSet && options.baBehav[ADDSET_WA_THRES] ? toEdit.wavelet.thres + mods.wavelet.thres : mods.wavelet.thres; if (wavelet.threshold)toEdit.wavelet.threshold= dontforceSet && options.baBehav[ADDSET_WA_THRESHOLD] ? toEdit.wavelet.threshold + mods.wavelet.threshold : mods.wavelet.threshold; @@ -1198,7 +1229,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.contrast)toEdit.wavelet.contrast= dontforceSet && options.baBehav[ADDSET_WA_CONTRAST] ? toEdit.wavelet.contrast + mods.wavelet.contrast : mods.wavelet.contrast; if (wavelet.edgrad)toEdit.wavelet.edgrad= dontforceSet && options.baBehav[ADDSET_WA_EDGRAD] ? toEdit.wavelet.edgrad + mods.wavelet.edgrad : mods.wavelet.edgrad; if (wavelet.edgval)toEdit.wavelet.edgval= dontforceSet && options.baBehav[ADDSET_WA_EDGVAL] ? toEdit.wavelet.edgval + mods.wavelet.edgval : mods.wavelet.edgval; - if (wavelet.edgval)toEdit.wavelet.strength= dontforceSet && options.baBehav[ADDSET_WA_STRENGTH] ? toEdit.wavelet.strength + mods.wavelet.strength : mods.wavelet.strength; + if (wavelet.strength)toEdit.wavelet.strength= dontforceSet && options.baBehav[ADDSET_WA_STRENGTH] ? toEdit.wavelet.strength + mods.wavelet.strength : mods.wavelet.strength; if (dirpyrequalizer.enabled) toEdit.dirpyrequalizer.enabled = mods.dirpyrequalizer.enabled; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 1cad0cbbb..a2379760d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -478,18 +478,23 @@ class WaveletParamsEdited { public: bool enabled; bool strength; + bool balance; + bool iter; bool median; bool medianlev; bool linkedg; bool lipst; bool Medgreinf; bool avoid; + bool tmr; bool c[9]; bool ch[9]; bool Lmethod; bool CHmethod; bool CHSLmethod; bool EDmethod; + bool BAmethod; + bool TMmethod; bool HSmethod; bool CLmethod; bool Backmethod; @@ -499,6 +504,8 @@ class WaveletParamsEdited { bool rescon; bool resconH; bool reschro; + bool tmrs; + bool gamma; bool sup; bool sky; bool thres; @@ -527,10 +534,13 @@ class WaveletParamsEdited { bool ccwcurve; bool opacityCurveBY; bool opacityCurveRG; + bool opacityCurveW; + bool opacityCurveWL; bool hhcurve; bool Chcurve; bool pastlev; bool satlev; + bool wavclCurve; }; class DirPyrEqualizerParamsEdited { diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index d5e2350c2..ef2e57ae6 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -315,9 +315,11 @@ Gtk::Widget* Preferences::getBatchProcPanel () { appendBehavList (mi, M("TP_WAVELET_RESCONH"), ADDSET_WA_RESCONH, true); appendBehavList (mi, M("TP_WAVELET_THRH"), ADDSET_WA_THRRH, true); appendBehavList (mi, M("TP_WAVELET_RESCHRO"), ADDSET_WA_RESCHRO, true); + appendBehavList (mi, M("TP_WAVELET_TMSTRENGTH"), ADDSET_WA_TMRS, true); appendBehavList (mi, M("TP_WAVELET_SKY"), ADDSET_WA_SKYPROTECT, true); appendBehavList (mi, M("TP_WAVELET_CONTRA"), ADDSET_WA_CONTRAST, true); appendBehavList (mi, M("TP_WAVELET_STRENGTH"), ADDSET_WA_STRENGTH, true); + appendBehavList (mi, M("TP_WAVELET_COMPGAMMA"), ADDSET_WA_GAMMA, true); appendBehavList (mi, M("TP_WAVELET_EDGEDETECT"), ADDSET_WA_EDGEDETECT, true); appendBehavList (mi, M("TP_WAVELET_EDGEDETECTTHR"), ADDSET_WA_EDGEDETECTTHR, true); appendBehavList (mi, M("TP_WAVELET_EDGEDETECTTHR2"), ADDSET_WA_EDGEDETECTTHR2, true); diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 1fef95641..bbd4af9d3 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -134,6 +134,17 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), //hbresid->pack_start(*cbresid); // add a CheckButton to the box. // residualFrame->set_label_widget(*hbresid); // put the box as label for the frame. tbresid->signal_toggled().connect( sigc::mem_fun(this, &Wavelet::expresidTog)); + + + finalFrame = Gtk::manage (new Gtk::Frame () ); + expfinal = Gtk::manage (new Gtk::Expander (M("TP_WAVELET_FINAL"))); + Gtk::HBox* hbfinal = Gtk::manage( new Gtk::HBox()); + tbfinal = Gtk::manage( new Gtk::ToggleButton()); + finalFrame->add(*expfinal); + hbfinal->set_spacing(8); + hbfinal->pack_start(*tbfinal); + tbfinal->signal_toggled().connect( sigc::mem_fun(this, &Wavelet::expfinalTog)); + //**************************************************** @@ -176,12 +187,14 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), choicemethod->set_tooltip_text (M("TP_WAVELET_DAUB_TOOLTIP")); choiceHBox->pack_start(*choiceLabel, Gtk::PACK_SHRINK, 4); choiceHBox->pack_start(*choicemethod); - - + + // Gtk::HSeparator *separatorbal = Gtk::manage (new Gtk::HSeparator()); settingsVBox->pack_start(*strength); settingsVBox->pack_start(*thres); settingsVBox->pack_start(*tilesizeHBox); settingsVBox->pack_start(*choiceHBox); + // settingsVBox->pack_start(*separatorbal, Gtk::PACK_SHRINK, 2); + settingsFrame->add(*settingsVBox); pack_start (*settingsFrame, Gtk::PACK_EXPAND_WIDGET, 4); @@ -287,11 +300,11 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), ss =Glib::ustring::compose( "%1",(i+1)); } - correction[i] = Gtk::manage ( new Adjuster (ss, -100, 250, 1, 0) ); + correction[i] = Gtk::manage ( new Adjuster (ss, -100, 350, 1, 0) ); correction[i]->setAdjusterListener(this); levBox->pack_start(*correction[i]); } - sup = Gtk::manage (new Adjuster (M("TP_WAVELET_SUPE"), -100, 250, 1, 0)); + sup = Gtk::manage (new Adjuster (M("TP_WAVELET_SUPE"), -100, 350, 1, 0)); levBox->pack_start(*sup); sup->setAdjusterListener (this); wavLabels->show(); @@ -543,12 +556,13 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), ctboxED->pack_start(*EDmethod); edgBox->pack_start (*ctboxED); // edgcont = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_EDGCONT"), 0., 100., 0., 20., 100., 75., 0, false)); - double tr=options.rtSettings.top_right; - double br=options.rtSettings.bot_right; - double tl=options.rtSettings.top_left; - double bl=options.rtSettings.bot_left; + tr=options.rtSettings.top_right; + br=options.rtSettings.bot_right; + tl=options.rtSettings.top_left; + bl=options.rtSettings.bot_left; edgcont = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_EDGCONT"), 0., 100., bl, tl, br, tr, 0., false)); + // edgcont = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_EDGCONT"), 0., 100., 0, 10, 75, 40, 0., false)); edgcont->setAdjusterListener (this); edgcont->setBgGradient(milestones2); edgcont->set_tooltip_markup (M("TP_WAVELET_EDGCONT_TOOLTIP")); @@ -661,7 +675,6 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), thr = Gtk::manage (new Adjuster (M("TP_WAVELET_THR"), 0, 100, 1, 35)); resBox->pack_start(*thr); - thr->setAdjusterListener (this); resconH = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCONH"), -100, 100, 1, 0)); @@ -683,6 +696,42 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), resBox->pack_start(*reschro); + ctboxTM = Gtk::manage (new Gtk::HBox ()); + labmTM = Gtk::manage (new Gtk::Label (M("TP_WAVELET_TMTYPE")+":")); + ctboxTM->pack_start (*labmTM, Gtk::PACK_SHRINK, 1); + + Gtk::HSeparator *separatorR0 = Gtk::manage (new Gtk::HSeparator()); + resBox->pack_start(*separatorR0, Gtk::PACK_SHRINK, 2); + + TMmethod = Gtk::manage (new MyComboBoxText ()); + TMmethod->append_text (M("TP_WAVELET_COMPCONT")); + TMmethod->append_text (M("TP_WAVELET_COMPTM")); +// TMmethod->append_text (M("TP_WAVELET_COMBOTH")); + TMmethodconn = TMmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::TMmethodChanged) ); + ctboxTM->pack_start(*TMmethod); + resBox->pack_start (*ctboxTM); + + + tmrs = Gtk::manage(new Adjuster (M("TP_WAVELET_TMSTRENGTH"), -1.0, 2.0, 0.01, 0.0)); + tmrs->set_tooltip_text (M("TP_WAVELET_TMSTRENGTH_TOOLTIP")); + + resBox->pack_start(*tmrs); + tmrs->setAdjusterListener (this); + + gamma = Gtk::manage(new Adjuster (M("TP_WAVELET_COMPGAMMA"), 0.4, 2.0, 0.01, 1.0)); + gamma->set_tooltip_text (M("TP_WAVELET_COMPGAMMA_TOOLTIP")); + resBox->pack_start(*gamma); + gamma->setAdjusterListener (this); + + /* tmr = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_TMR"))); + tmr->set_active (true); + tmr->set_tooltip_text (M("TP_WAVELET_TMR_TOOLTIP")); + tmrConn = tmr->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::tmrToggled) ); + resBox->pack_start(*tmr); +*/ + Gtk::HSeparator *separatorR1 = Gtk::manage (new Gtk::HSeparator()); + resBox->pack_start(*separatorR1, Gtk::PACK_SHRINK, 2); + hueskin2 = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false)); hueskin2->set_tooltip_markup (M("TP_WAVELET_HUESKY_TOOLTIP")); hueskin2->setBgGradient(milestones); @@ -717,6 +766,106 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), resBox->pack_start (*curveEditorRES, Gtk::PACK_SHRINK, 4); //-------------------------------------- + //final touchup + ctboxBA = Gtk::manage (new Gtk::HBox ()); + labmBA = Gtk::manage (new Gtk::Label (M("TP_WAVELET_BATYPE")+":")); + ctboxBA->pack_start (*labmBA, Gtk::PACK_SHRINK, 1); + + + BAmethod = Gtk::manage (new MyComboBoxText ()); + BAmethod->append_text (M("TP_WAVELET_BANONE")); + BAmethod->append_text (M("TP_WAVELET_BASLI")); + BAmethod->append_text (M("TP_WAVELET_BACUR")); + BAmethodconn = BAmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::BAmethodChanged) ); + ctboxBA->pack_start(*BAmethod); + + + balance = Gtk::manage (new Adjuster (M("TP_WAVELET_BALANCE"), -30, 100, 1, 0)); + balance->setAdjusterListener (this); + balance->set_tooltip_text (M("TP_WAVELET_BALANCE_TOOLTIP")); + std::vector milestonesW; + + milestonesW.clear(); + milestonesW.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestonesW.push_back( GradientMilestone(1., 1., 1., 1.) ); + + opacityCurveEditorW = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITYW")); + opacityCurveEditorW->setCurveListener (this); + + rtengine::WaveletParams::getDefaultOpacityCurveW(defaultCurve); + opacityShape = static_cast(opacityCurveEditorW->addCurve(CT_Flat, "", NULL, false)); + opacityShape->setIdentityValue(0.); + opacityShape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + opacityShape->setBottomBarBgGradient(milestonesW); + + // This will add the reset button at the end of the curveType buttons + opacityCurveEditorW->curveListComplete(); + opacityCurveEditorW->show(); + + + + iter = Gtk::manage (new Adjuster (M("TP_WAVELET_ITER"), -3, 3, 1, 0)); + iter->setAdjusterListener (this); + iter->set_tooltip_text (M("TP_WAVELET_ITER_TOOLTIP")); + + Gtk::HSeparator *separatorbalend = Gtk::manage (new Gtk::HSeparator()); + + opacityCurveEditorWL = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITYWL")); + opacityCurveEditorWL->setCurveListener (this); + + rtengine::WaveletParams::getDefaultOpacityCurveWL(defaultCurve); + opacityShapeWL = static_cast(opacityCurveEditorWL->addCurve(CT_Flat, "", NULL, false)); + opacityShapeWL->setIdentityValue(0.); + opacityShapeWL->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + opacityShapeWL->setTooltip(M("TP_WAVELET_OPACITYWL_TOOLTIP")); + +// opacityShape->setBottomBarBgGradient(milestonesW); + + // This will add the reset button at the end of the curveType buttons + opacityCurveEditorWL->curveListComplete(); + opacityCurveEditorWL->show(); + + + curveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir,M("TP_WAVELET_CONTEDIT")); + curveEditorG->setCurveListener (this); + + clshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_WAVELET_CURVEEDITOR_CL"))); + clshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CL_TOOLTIP")); + std::vector milestones22; + + milestones22.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones22.push_back( GradientMilestone(1., 1., 1., 1.) ); + clshape->setBottomBarBgGradient(milestones22); + clshape->setLeftBarBgGradient(milestones22); + + + curveEditorG->curveListComplete(); + + tmr = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_BALCHRO"))); + tmr->set_active (true); + tmr->set_tooltip_text (M("TP_WAVELET_BALCHRO_TOOLTIP")); + tmrConn = tmr->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::tmrToggled) ); + + + Gtk::VBox * finalBox = Gtk::manage (new Gtk::VBox()); + finalBox->set_border_width(4); + finalBox->set_spacing(2); + + finalBox->pack_start (*ctboxBA); + finalBox->pack_start(*balance); + + finalBox->pack_start( *opacityCurveEditorW, Gtk::PACK_SHRINK, 2); + + finalBox->pack_start(*iter); + + finalBox->pack_start(*tmr); + finalBox->pack_start(*separatorbalend, Gtk::PACK_SHRINK, 2); + finalBox->pack_start( *opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); + + finalBox->pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); + + +//----------------------------- expdisplay->add(*diBox); pack_start (*dispFrame, Gtk::PACK_EXPAND_WIDGET, 4); @@ -740,6 +889,9 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), expresid->add(*resBox); pack_start(*residualFrame, Gtk::PACK_EXPAND_WIDGET, 4); + + expfinal->add(*finalBox); + pack_start(*finalFrame, Gtk::PACK_EXPAND_WIDGET, 4); show_all_children (); } @@ -750,6 +902,9 @@ Wavelet::~Wavelet () { delete CCWcurveEditorG; delete curveEditorRES; delete curveEditorGAM; + delete curveEditorG; + delete opacityCurveEditorW; + delete opacityCurveEditorWL; } int wavChangedUI (void* data) { @@ -795,6 +950,8 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { CHmethodconn.block(true); CHSLmethodconn.block(true); EDmethodconn.block(true); + BAmethodconn.block(true); + TMmethodconn.block(true); HSmethodconn.block(true); MedgreinfConn.block(true); HSmethod->set_active (1); @@ -837,6 +994,26 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { EDmethod->set_active (1); EDmethodChanged(); + BAmethod->set_active (0); + if (pp->wavelet.BAmethod=="none") + BAmethod->set_active (0); + else if (pp->wavelet.BAmethod=="sli") + BAmethod->set_active (1); + else if (pp->wavelet.BAmethod=="cur") + BAmethod->set_active (2); + BAmethodChanged(); + + TMmethod->set_active (1); + if (pp->wavelet.TMmethod=="cont") + TMmethod->set_active (0); + else if (pp->wavelet.TMmethod=="tm") + TMmethod->set_active (1); + // else if (pp->wavelet.TMmethod=="both") + // TMmethod->set_active (2); + + TMmethodChanged(); + + Backmethod->set_active (3); if (pp->wavelet.Backmethod=="black") { Backmethod->set_active (0); @@ -920,6 +1097,10 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { CHSLmethod->set_active (1); if (!pedited->wavelet.EDmethod) EDmethod->set_active (1); + if (!pedited->wavelet.BAmethod) + BAmethod->set_active (1); + if (!pedited->wavelet.TMmethod) + TMmethod->set_active (1); if (!pedited->wavelet.HSmethod) HSmethod->set_active (1); if (!pedited->wavelet.Medgreinf) @@ -929,16 +1110,24 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { ccshape->setUnChanged (!pedited->wavelet.ccwcurve); opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); + opacityShape->setCurve (pp->wavelet.opacityCurveW); + opacityShapeWL->setCurve (pp->wavelet.opacityCurveWL); hhshape->setUnChanged (!pedited->wavelet.hhcurve); Chshape->setUnChanged (!pedited->wavelet.Chcurve); + clshape->setUnChanged (!pedited->wavelet.wavclCurve); avoid->set_inconsistent (!pedited->wavelet.avoid); + tmr->set_inconsistent (!pedited->wavelet.tmr); edgthresh->setEditedState (pedited->wavelet.edgthresh ? Edited : UnEdited); rescon->setEditedState (pedited->wavelet.rescon ? Edited : UnEdited); resconH->setEditedState (pedited->wavelet.resconH ? Edited : UnEdited); reschro->setEditedState (pedited->wavelet.reschro ? Edited : UnEdited); + tmrs->setEditedState (pedited->wavelet.tmrs ? Edited : UnEdited); + gamma->setEditedState (pedited->wavelet.gamma ? Edited : UnEdited); sup->setEditedState (pedited->wavelet.sup ? Edited : UnEdited); sky->setEditedState (pedited->wavelet.sky ? Edited : UnEdited); thres->setEditedState (pedited->wavelet.thres ? Edited : UnEdited); + balance->setEditedState (pedited->wavelet.balance ? Edited : UnEdited); + iter->setEditedState (pedited->wavelet.iter ? Edited : UnEdited); threshold->setEditedState (pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setEditedState (pedited->wavelet.threshold2 ? Edited : UnEdited); edgedetect->setEditedState (pedited->wavelet.edgedetect ? Edited : UnEdited); @@ -979,13 +1168,19 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { ccshape->setCurve (pp->wavelet.ccwcurve); opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); + opacityShape->setCurve (pp->wavelet.opacityCurveW); + opacityShapeWL->setCurve (pp->wavelet.opacityCurveWL); hhshape->setCurve (pp->wavelet.hhcurve); Chshape->setCurve (pp->wavelet.Chcurve); + clshape->setCurve (pp->wavelet.wavclCurve); setEnabled(pp->wavelet.enabled); avoidConn.block (true); avoid->set_active (pp->wavelet.avoid); avoidConn.block (false); + tmrConn.block (true); + tmr->set_active (pp->wavelet.tmr); + tmrConn.block (false); medianConn.block (true); median->set_active (pp->wavelet.median); medianConn.block (false); @@ -1008,9 +1203,12 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { lastlinkedg = pp->wavelet.linkedg; lastlipst = pp->wavelet.lipst; lastavoid = pp->wavelet.avoid; + lasttmr = pp->wavelet.tmr; rescon->setValue (pp->wavelet.rescon); resconH->setValue (pp->wavelet.resconH); reschro->setValue (pp->wavelet.reschro); + tmrs->setValue (pp->wavelet.tmrs); + gamma->setValue (pp->wavelet.gamma); sup->setValue (pp->wavelet.sup); sky->setValue (pp->wavelet.sky); thres->setValue (pp->wavelet.thres); @@ -1039,6 +1237,8 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { level1noise->setValue(pp->wavelet.level1noise); level2noise->setValue(pp->wavelet.level2noise); strength->setValue(pp->wavelet.strength); + balance->setValue(pp->wavelet.balance); + iter->setValue(pp->wavelet.iter); for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); } @@ -1054,9 +1254,16 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { for(z=y;z<9;z++) correctionch[z]->hide(); for(z=0;zshow(); } + float tm; +/* tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); +*/ CHmethodChanged(); CHSLmethodChanged(); EDmethodChanged(); + BAmethodChanged(); + TMmethodChanged(); MedgreinfChanged(); if(z==9) sup->show(); else sup->hide(); Lmethodconn.block(false); @@ -1067,6 +1274,8 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { CHmethodconn.block(false); CHSLmethodconn.block(false); EDmethodconn.block(false); + BAmethodconn.block(false); + TMmethodconn.block(false); HSmethodconn.block(false); Dirmethodconn.block(false); MedgreinfConn.block(false); @@ -1082,8 +1291,12 @@ void Wavelet::setEditProvider (EditDataProvider *provider) { ccshape->setEditProvider(provider); opacityShapeRG->setEditProvider(provider); opacityShapeBY->setEditProvider(provider); + opacityShape->setEditProvider(provider); + opacityShapeWL->setEditProvider(provider); hhshape->setEditProvider(provider); Chshape->setEditProvider(provider); + clshape->setEditProvider(provider); + } void Wavelet::autoOpenCurve () { @@ -1096,9 +1309,12 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pp->wavelet.enabled = getEnabled(); pp->wavelet.avoid = avoid->get_active (); + pp->wavelet.tmr = tmr->get_active (); pp->wavelet.rescon = rescon->getValue(); pp->wavelet.resconH = resconH->getValue(); pp->wavelet.reschro = reschro->getValue(); + pp->wavelet.tmrs = tmrs->getValue(); + pp->wavelet.gamma = gamma->getValue(); pp->wavelet.sup = sup->getValue(); pp->wavelet.sky = sky->getValue(); pp->wavelet.thres = thres->getValue(); @@ -1132,11 +1348,16 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pp->wavelet.ccwcurve = ccshape->getCurve (); pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve (); pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve (); + pp->wavelet.opacityCurveW = opacityShape->getCurve (); + pp->wavelet.opacityCurveWL = opacityShapeWL->getCurve (); pp->wavelet.hhcurve = hhshape->getCurve (); pp->wavelet.Chcurve = Chshape->getCurve (); pp->wavelet.pastlev = pastlev->getValue (); pp->wavelet.satlev = satlev->getValue (); pp->wavelet.strength = (int) strength->getValue(); + pp->wavelet.balance = (int) balance->getValue(); + pp->wavelet.iter = (int) iter->getValue(); + pp->wavelet.wavclCurve = clshape->getCurve (); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); @@ -1148,6 +1369,7 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { if (pedited) { pedited->wavelet.enabled = !get_inconsistent(); pedited->wavelet.avoid = !avoid->get_inconsistent(); + pedited->wavelet.tmr = !tmr->get_inconsistent(); pedited->wavelet.median = !median->get_inconsistent(); pedited->wavelet.medianlev = !medianlev->get_inconsistent(); pedited->wavelet.linkedg = !linkedg->get_inconsistent(); @@ -1161,12 +1383,16 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pedited->wavelet.CHmethod = CHmethod->get_active_row_number() != 2; pedited->wavelet.CHSLmethod = CHSLmethod->get_active_row_number() != 1; pedited->wavelet.EDmethod = EDmethod->get_active_row_number() != 1; + pedited->wavelet.BAmethod = BAmethod->get_active_row_number() != 3; + pedited->wavelet.TMmethod = TMmethod->get_active_row_number() != 2; pedited->wavelet.HSmethod = HSmethod->get_active_row_number() != 1; pedited->wavelet.Dirmethod = Dirmethod->get_active_row_number() != 3; pedited->wavelet.edgthresh = edgthresh->getEditedState(); pedited->wavelet.rescon = rescon->getEditedState(); pedited->wavelet.resconH = resconH->getEditedState(); pedited->wavelet.reschro = reschro->getEditedState(); + pedited->wavelet.tmrs = tmrs->getEditedState(); + pedited->wavelet.gamma = gamma->getEditedState(); pedited->wavelet.sup = sup->getEditedState(); pedited->wavelet.sky = sky->getEditedState(); pedited->wavelet.thres = thres->getEditedState(); @@ -1193,12 +1419,17 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pedited->wavelet.level2noise = level2noise->getEditedState (); pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged (); pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged (); + pedited->wavelet.opacityCurveW = !opacityShape->isUnChanged (); + pedited->wavelet.opacityCurveWL = !opacityShapeWL->isUnChanged (); pedited->wavelet.hhcurve = !hhshape->isUnChanged (); pedited->wavelet.Chcurve = !Chshape->isUnChanged (); pedited->wavelet.bllev = bllev->getEditedState (); pedited->wavelet.pastlev = pastlev->getEditedState (); pedited->wavelet.satlev = satlev->getEditedState (); pedited->wavelet.strength = strength->getEditedState (); + pedited->wavelet.balance = balance->getEditedState (); + pedited->wavelet.iter = iter->getEditedState (); + pedited->wavelet.wavclCurve = !clshape->isUnChanged (); for(int i = 0; i < 9; i++) { pedited->wavelet.c[i] = correction[i]->getEditedState(); @@ -1232,6 +1463,20 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { else if (EDmethod->get_active_row_number()==1) pp->wavelet.EDmethod = "CU"; + if (BAmethod->get_active_row_number()==0) + pp->wavelet.BAmethod = "none"; + else if (BAmethod->get_active_row_number()==1) + pp->wavelet.BAmethod = "sli"; + else if (BAmethod->get_active_row_number()==2) + pp->wavelet.BAmethod = "cur"; + + if (TMmethod->get_active_row_number()==0) + pp->wavelet.TMmethod = "cont"; + else if (TMmethod->get_active_row_number()==1) + pp->wavelet.TMmethod = "tm"; + // else if (TMmethod->get_active_row_number()==2) + // pp->wavelet.TMmethod = "both"; + if (HSmethod->get_active_row_number()==0) pp->wavelet.HSmethod = "without"; else if (HSmethod->get_active_row_number()==1) @@ -1295,10 +1540,16 @@ void Wavelet::curveChanged (CurveEditor* ce) { listener->panelChanged (EvWavColor, M("HISTORY_CUSTOMCURVE")); else if (ce == opacityShapeBY) listener->panelChanged (EvWavOpac, M("HISTORY_CUSTOMCURVE")); + else if (ce == opacityShape) + listener->panelChanged (EvWavopacity, M("HISTORY_CUSTOMCURVE")); + else if (ce == opacityShapeWL) + listener->panelChanged (EvWavopacityWL, M("HISTORY_CUSTOMCURVE")); else if (ce == hhshape) listener->panelChanged (EvWavHHCurve, M("HISTORY_CUSTOMCURVE")); else if (ce == Chshape) listener->panelChanged (EvWavCHCurve, M("HISTORY_CUSTOMCURVE")); + else if (ce == clshape) + listener->panelChanged (EvWavCLCurve, M("HISTORY_CUSTOMCURVE")); } } @@ -1312,9 +1563,13 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi correctionch[i]->setDefault(defParams->wavelet.ch[i]); } strength->setDefault(defParams->wavelet.strength ); + balance->setDefault(defParams->wavelet.balance ); + iter->setDefault(defParams->wavelet.iter ); rescon->setDefault (defParams->wavelet.rescon); resconH->setDefault (defParams->wavelet.resconH); reschro->setDefault (defParams->wavelet.reschro); + tmrs->setDefault (defParams->wavelet.tmrs); + gamma->setDefault (defParams->wavelet.gamma); sup->setDefault (defParams->wavelet.sup); sky->setDefault (defParams->wavelet.sky); thres->setDefault (defParams->wavelet.thres); @@ -1346,6 +1601,8 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi rescon->setDefault (defParams->wavelet.rescon); resconH->setDefault (defParams->wavelet.resconH); reschro->setDefault (defParams->wavelet.reschro); + tmrs->setDefault (defParams->wavelet.tmrs); + gamma->setDefault (defParams->wavelet.gamma); sup->setDefault (defParams->wavelet.sup); sky->setDefaultEditedState(pedited->wavelet.sky ? Edited : UnEdited); thres->setDefaultEditedState(pedited->wavelet.thres ? Edited : UnEdited); @@ -1371,6 +1628,8 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi satlev->setDefaultEditedState (pedited->wavelet.satlev ? Edited : UnEdited); edgcont->setDefaultEditedState (pedited->wavelet.edgcont ? Edited : UnEdited); strength->setDefaultEditedState (pedited->wavelet.strength ? Edited : UnEdited); + balance->setDefaultEditedState (pedited->wavelet.balance ? Edited : UnEdited); + iter->setDefaultEditedState (pedited->wavelet.iter ? Edited : UnEdited); level0noise->setDefaultEditedState (pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setDefaultEditedState (pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setDefaultEditedState (pedited->wavelet.level2noise ? Edited : UnEdited); @@ -1386,6 +1645,8 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi rescon->setDefaultEditedState(Irrelevant); resconH->setDefaultEditedState(Irrelevant); reschro->setDefaultEditedState(Irrelevant); + tmrs->setDefaultEditedState(Irrelevant); + gamma->setDefaultEditedState(Irrelevant); sup->setDefaultEditedState(Irrelevant); sky->setDefaultEditedState(Irrelevant); thres->setDefaultEditedState(Irrelevant); @@ -1414,6 +1675,8 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi pastlev->setDefaultEditedState (Irrelevant); satlev->setDefaultEditedState (Irrelevant); strength->setDefaultEditedState (Irrelevant); + balance->setDefaultEditedState (Irrelevant); + iter->setDefaultEditedState (Irrelevant); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(Irrelevant); @@ -1620,6 +1883,50 @@ void Wavelet::EDmethodChanged() { } } +void Wavelet::BAmethodChanged() { + if (!batchMode) { + if(BAmethod->get_active_row_number()==0 ) {//none + balance->hide(); + opacityCurveEditorW->hide(); + iter->hide(); + + } + else if(BAmethod->get_active_row_number()==1) {//sli + opacityCurveEditorW->hide(); + balance->show(); + iter->show(); + } + + else if(BAmethod->get_active_row_number()==2) {//CU + opacityCurveEditorW->show(); + balance->hide(); + iter->show(); + + } + + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavBAmet, BAmethod->get_active_text ()); + } +} + + +void Wavelet::TMmethodChanged() { + if (!batchMode) { + /* + if(TMmethod->get_active_row_number()==0 ) {// + tmr->hide(); + } + else { + tmr->show(); + } + */ + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavTMmet, TMmethod->get_active_text ()); + } +} + void Wavelet::BackmethodChanged() { if (!batchMode) { } @@ -1708,16 +2015,22 @@ void Wavelet::setBatchMode (bool batchMode) { Medgreinf->append_text (M("GENERAL_UNCHANGED")); CHSLmethod->append_text (M("GENERAL_UNCHANGED")); EDmethod->append_text (M("GENERAL_UNCHANGED")); + BAmethod->append_text (M("GENERAL_UNCHANGED")); + TMmethod->append_text (M("GENERAL_UNCHANGED")); HSmethod->append_text (M("GENERAL_UNCHANGED")); Dirmethod->append_text (M("GENERAL_UNCHANGED")); CCWcurveEditorG->setBatchMode (batchMode); opaCurveEditorG->setBatchMode (batchMode); opacityCurveEditorG->setBatchMode (batchMode); + opacityCurveEditorW->setBatchMode (batchMode); + opacityCurveEditorWL->setBatchMode (batchMode); curveEditorRES->setBatchMode (batchMode); curveEditorGAM->setBatchMode (batchMode); rescon->showEditedCB (); resconH->showEditedCB (); reschro->showEditedCB (); + tmrs->showEditedCB (); + gamma->showEditedCB (); sup->showEditedCB (); sky->showEditedCB (); thres->showEditedCB (); @@ -1743,6 +2056,8 @@ void Wavelet::setBatchMode (bool batchMode) { satlev->showEditedCB (); edgcont->showEditedCB (); strength->showEditedCB (); + balance->showEditedCB (); + iter->showEditedCB (); level0noise->showEditedCB (); level1noise->showEditedCB (); level2noise->showEditedCB (); @@ -1784,6 +2099,30 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) { Glib::ustring::format(std::fixed, std::setprecision(0), reschro->getValue())) ); } + else if (a == tmrs ) { + float tm; + /* + tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + */ + listener->panelChanged (EvWavtmrs, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), tmrs->getValue())) + ); + } + else if (a == gamma ) { + float tm; + /* + tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + */ + listener->panelChanged (EvWavgamma, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), gamma->getValue())) + ); + } else if (a == sky ) { listener->panelChanged (EvWavsky, @@ -1900,6 +2239,18 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) { Glib::ustring::format(std::fixed, std::setprecision(2), strength->getValue())) ); } + else if (a == balance) { + listener->panelChanged (EvWavbalance, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), balance->getValue())) + ); + } + else if (a == iter) { + listener->panelChanged (EvWaviter, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), iter->getValue())) + ); + } else if (a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8] ) { @@ -1941,6 +2292,13 @@ void Wavelet::enabledChanged () { for(z=y;z<9;z++) correction[z]->hide(); for(z=0;zshow(); if(z==9) sup->show(); else sup->hide(); + + float tm; + /* tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + */ + } if (listener) { if (get_inconsistent()) @@ -1994,6 +2352,16 @@ void Wavelet::expgamutTog () { controlFrame->hide(); } } + +void Wavelet::expfinalTog () { + if (tbcontrast->get_active ()) { + finalFrame->show(); + } + else { + finalFrame->hide(); + } +} + void Wavelet::expdisplayTog () { if (tbdisplay->get_active ()) { dispFrame->show(); @@ -2191,6 +2559,28 @@ void Wavelet::avoidToggled () { } } +void Wavelet::tmrToggled () { + + if (batchMode) { + if (tmr->get_inconsistent()) { + tmr->set_inconsistent (false); + tmrConn.block (true); + tmr->set_active (false); + tmrConn.block (false); + } + else if (lasttmr) + tmr->set_inconsistent (true); + + lasttmr = tmr->get_active (); + } + if (listener && getEnabled ()) { + if (tmr->get_active ()) + listener->panelChanged (EvWavtmr, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvWavtmr, M("GENERAL_DISABLED")); + } +} + void Wavelet::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { @@ -2227,7 +2617,7 @@ void Wavelet::colorForValue (double valX, double valY, enum ColorCaller::ElemTyp caller->ccGreen = double(G); caller->ccBlue = double(B); } -void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool edgedetectadd, bool edgedetectthradd ,bool edgedetectthr2add) { +void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd ,bool edgedetectthr2add) { for (int i=0; i<9; i++) correction[i]->setAddMode(multiplieradd); @@ -2241,12 +2631,14 @@ void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool t rescon->setAddMode(resconadd); resconH->setAddMode(resconHadd); reschro->setAddMode(reschroadd); + tmrs->setAddMode(tmrsadd); thr->setAddMode(thradd); thrH->setAddMode(thrHadd); sky->setAddMode(skyadd); edgrad->setAddMode(edgradadd); edgval->setAddMode(edgvaladd); strength->setAddMode(strengthadd); + gamma->setAddMode(gammaadd); edgedetect->setAddMode(edgedetectadd); edgedetectthr->setAddMode(edgedetectthradd); edgedetectthr2->setAddMode(edgedetectthr2add); diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index cf6620205..327fff84e 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -37,6 +37,7 @@ protected: Glib::RefPtr srTTips; Glib::RefPtr bgPixbuf; Glib::RefPtr srPixbuf; + CurveEditorGroup* curveEditorG; CurveEditorGroup* CCWcurveEditorG; CurveEditorGroup* curveEditorRES; @@ -47,8 +48,13 @@ protected: FlatCurveEditor* opacityShapeRG; CurveEditorGroup* opacityCurveEditorG; FlatCurveEditor* opacityShapeBY; + CurveEditorGroup* opacityCurveEditorW; + CurveEditorGroup* opacityCurveEditorWL; + FlatCurveEditor* opacityShape; + FlatCurveEditor* opacityShapeWL; FlatCurveEditor* hhshape; FlatCurveEditor* Chshape; + DiagonalCurveEditor* clshape; FlatCurveEditor* ccshape; Gtk::CheckButton * display; @@ -62,9 +68,11 @@ protected: // Gtk::CheckButton * edgreinf; Gtk::CheckButton * lipst; Gtk::CheckButton * avoid; + Gtk::CheckButton * tmr; Gtk::ToggleButton * tbresid; Gtk::ToggleButton * tbcontrast; Gtk::ToggleButton * tbgamut; + Gtk::ToggleButton * tbfinal; Gtk::ToggleButton * tbchroma; Gtk::ToggleButton * tbtoning; Gtk::ToggleButton * tbnoise; @@ -79,6 +87,8 @@ protected: Adjuster* rescon; Adjuster* resconH; Adjuster* reschro; + Adjuster* tmrs; + Adjuster* gamma; Adjuster* sup; Adjuster* sky; Adjuster* thres; @@ -92,6 +102,8 @@ protected: Adjuster* edgval; Adjuster* edgthresh; Adjuster* strength; + Adjuster* balance; + Adjuster* iter; ThresholdAdjuster* hueskin; ThresholdAdjuster* hueskin2; @@ -117,6 +129,10 @@ protected: sigc::connection CHSLmethodconn; MyComboBoxText* EDmethod; sigc::connection EDmethodconn; + MyComboBoxText* BAmethod; + sigc::connection BAmethodconn; + MyComboBoxText* TMmethod; + sigc::connection TMmethodconn; MyComboBoxText* HSmethod; sigc::connection HSmethodconn; MyComboBoxText* CLmethod; @@ -141,6 +157,7 @@ protected: Gtk::Frame* edgeFrame; Gtk::Frame* noiseFrame; Gtk::Frame* contrastSHFrame; + Gtk::Frame* finalFrame; Gtk::Label* colLabel; Gtk::Label* interLabel; Gtk::Label* wavLabels; @@ -150,11 +167,14 @@ protected: Gtk::Label* labmC; Gtk::Label* labmch; Gtk::Label* labmED; + Gtk::Label* labmTM; + Gtk::Label* labmBA; Gtk::Label* labmedgr; Gtk::Label* labmednois; Gtk::Expander* expcontrast; Gtk::Expander* expresid; Gtk::Expander* expgamut; + Gtk::Expander* expfinal; Gtk::Expander* expchroma; Gtk::Expander* exptoning; Gtk::Expander* expdisplay; @@ -169,6 +189,8 @@ protected: Gtk::HBox* choiceHBox; Gtk::HBox* ctboxCH; Gtk::HBox* ctboxED; + Gtk::HBox* ctboxTM; + Gtk::HBox* ctboxBA; Gtk::HBox* ctboxch; Gtk::HBox* edbox; Gtk::HBox* ednoisbox; @@ -179,14 +201,18 @@ protected: Gtk::Label* previewLevelsLabel; Gtk::Label* previewBackLabel; - sigc::connection expConn, medianConn, avoidConn, medianlevConn, linkedgConn, lipstConn; + sigc::connection expConn, medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn; sigc::connection neutralPressedConn; sigc::connection contrastPlusPressedConn; sigc::connection contrastMinusPressedConn; sigc::connection neutralchPressedConn; - bool lastdisplay, lastdisplaygam,lastdisplayres,lastdisplaychro, lastdisplaylevel,lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst; + bool lastdisplay, lastdisplaygam,lastdisplayres,lastdisplaychro, lastdisplaylevel,lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr; int nextnlevel; + double tr; + double br; + double tl; + double bl; public: @@ -211,7 +237,7 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); void setBatchMode (bool batchMode); void adjusterChanged2 (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR); - void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add); + void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add); void adjusterChanged (Adjuster* a, double newval); void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop); @@ -225,9 +251,11 @@ public: void expresidTog (); void expdisplayTog (); void expgamutTog (); + void expfinalTog (); void expchromaTog (); void exptoningTog (); void avoidToggled (); + void tmrToggled (); void neutralPressed (); void neutralchPressed (); void contrastPlusPressed (); @@ -238,6 +266,8 @@ public: void MedgreinfChanged (); void CHSLmethodChanged (); void EDmethodChanged (); + void BAmethodChanged (); + void TMmethodChanged (); void HSmethodChanged (); void CLmethodChanged (); void BackmethodChanged ();