diff --git a/rtdata/languages/default b/rtdata/languages/default index 1f7afa614..8d20cf93c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -887,7 +887,7 @@ HISTORY_MSG_641;Local - Use SH mask HISTORY_MSG_642;Local - radius SH HISTORY_MSG_643;Local - Blur SH HISTORY_MSG_644;Local - inverse SH -HISTORY_MSG_645;Local - SD - ab-L balance +HISTORY_MSG_645;Local - SD - Lightness-chroma balance HISTORY_MSG_646;Local - Exp mask chroma HISTORY_MSG_647;Local - Exp mask gamma HISTORY_MSG_648;Local - Exp mask slope @@ -1101,7 +1101,7 @@ HISTORY_MSG_863;Local - Wavelet merge original image HISTORY_MSG_864;Local - Wavelet dir contrast attenuation HISTORY_MSG_865;Local - Wavelet dir contrast delta HISTORY_MSG_866;Local - Wavelet dir compression -HISTORY_MSG_868;Local - SD - C-H balance +HISTORY_MSG_868;Local - SD - Hue-Chroma balance HISTORY_MSG_869;Local - Denoise by level HISTORY_MSG_870;Local - Wavelet mask curve H HISTORY_MSG_871;Local - Wavelet mask curve C @@ -1568,12 +1568,27 @@ HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift HISTORY_MSG_LOCAL_LOGCIE12;Local - CIECAM - Log encoding +HISTORY_MSG_LOCAL_GHSMETHOD;Local - GHS - Method +HISTORY_MSG_LOCAL_GHS_D;Local - GHS - Stretch factor +HISTORY_MSG_LOCAL_GHS_SLOPE;Local - GHS - Lab slope factor +HISTORY_MSG_LOCAL_GHS_CHRO;Local - GHS - Lab chromaticity factor +HISTORY_MSG_LOCAL_GHS_B;Local - GHS - Local intensity +HISTORY_MSG_LOCAL_GHS_SP;Local - GHS - Symmetry point +HISTORY_MSG_LOCAL_GHS_LP;Local - GHS - Protect shadows +HISTORY_MSG_LOCAL_GHS_HP;Local - GHS - Protect highlights +HISTORY_MSG_LOCAL_GHS_LC;Local - GHS - Local Contrast +HISTORY_MSG_LOCAL_GHS_MID;Local - GHS - Midtones +HISTORY_MSG_LOCAL_GHS_BLP;Local - GHS - Black point +HISTORY_MSG_LOCAL_GHS_HLP;Local - GHS - White point +HISTORY_MSG_LOCAL_GHS_INV;Local - GHS - Inverse +HISTORY_MSG_LOCAL_GHS_SMOOTH;Local - GHS - Highlight attenuation HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution HISTORY_MSG_LOCAL_OFFSETWAV;Local Wav offset HISTORY_MSG_LOCAL_PROCESSWAV;Local - Wavelets - Show modifications +HISTORY_MSG_LOCAL_NLITER;Local - Nlmeans - Iterations HISTORY_MSG_LOCAL_QJMETHOD;Local - CIECAM Tone mapping operator Q and J HISTORY_MSG_LOCAL_SIGBLCIE;Local - CIECAM Blend 5.11 HISTORY_MSG_LOCAL_SIGDACIE;Local - CIECAM Contrast 5.11 @@ -2989,7 +3004,7 @@ TP_LOCALLAB_ACTIV;Luminance only TP_LOCALLAB_ACTIVSPOT;Enable Spot TP_LOCALLAB_ADJ;Equalizer Color TP_LOCALLAB_AMOUNT;Amount -TP_LOCALLAB_ARTIF;Shape detection +TP_LOCALLAB_ARTIF;ΔE Shape detection TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) TP_LOCALLAB_AUTOGRAYCIE;Automatic @@ -2999,9 +3014,9 @@ TP_LOCALLAB_AVOIDMUN;Munsell correction only TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. TP_LOCALLAB_AVOIDNEG;Pre-filter zero and negative values TP_LOCALLAB_AVOIDRAD;Soft radius -TP_LOCALLAB_BALAN;ab-L balance (ΔE) +TP_LOCALLAB_BALAN;Lightness-Chroma balance TP_LOCALLAB_BALANEXP;Laplacian balance -TP_LOCALLAB_BALANH;C-H balance (ΔE) +TP_LOCALLAB_BALANH;Hue-Chroma balance TP_LOCALLAB_BALAN_TOOLTIP;Changes the ΔE algorithm parameters.\nTakes into account more or less a*b* or L*, or more or less C or H.\nNot for Denoise. TP_LOCALLAB_BASELOG;Shadows range (logarithm base) TP_LOCALLAB_BILATERAL;Bilateral filter @@ -3209,12 +3224,12 @@ TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small defects such as red-eye, sensor dust etc. TP_LOCALLAB_EXPCOMP;Exposure compensation ƒ TP_LOCALLAB_EXPCOMPINV;Exposure compensation -TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' +TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'Lightness-chroma balance (ΔE)' TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. TP_LOCALLAB_EXPCURV;Curves TP_LOCALLAB_EXPGRAD;Graduated Filter -TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color & Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance gradient), Exposure Mask (luminance gradient), Shadows/Highlights (luminance gradient), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast gradient).\nThe graduated filter preview is only accurate when the image is viewed in fit-to-screen mode.\n\nThe graduated filter is only available in Full image or Global mode. TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3259,6 +3274,51 @@ TP_LOCALLAB_GAMUTNON;None TP_LOCALLAB_GAMUTXYZABSO;XYZ Absolute TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative TP_LOCALLAB_GAMW;Gamma (wavelet pyramids) +TP_LOCALLAB_GHSBPWP;Clipped pixel count - Shadows:%1 Highlights:%2 +TP_LOCALLAB_GHSBPWPVALUE;Pixel values - Darkest:%1 Lightest:%2 +TP_LOCALLAB_GHS_GHSDIAG;GHS Curve Visualization +TP_LOCALLAB_GHS_SIMUL_TOOLTIP;Gives a representation of the GHS function. +TP_LOCALLAB_GHSRGBLUM;RGB Luminance +TP_LOCALLAB_GHSRGBSTD;RGB Standard +TP_LOCALLAB_GHSLAB;Lightness & chromaticity (Lab) +TP_LOCALLAB_GHSHUE;Hue (HSL) +TP_LOCALLAB_GHSLUM;Luminance (HSL) +TP_LOCALLAB_GHSSAT;Saturation (HSL) +TP_LOCALLAB_GHSFRA;Stretch Settings +TP_LOCALLAB_GHS_D;Stretch factor (D) +TP_LOCALLAB_GHS_B;Local intensity (b) +TP_LOCALLAB_GHS_SP;Symmetry point (SP) +TP_LOCALLAB_GHS_LP;Protect shadows (LP) +TP_LOCALLAB_GHS_HP;Protect highlights (HP) +TP_LOCALLAB_GHS_LC;Value (LC) +TP_LOCALLAB_GHS_LC_FRAME;Stretch Regularization & Midtones +TP_LOCALLAB_GHS_LC_TOOLTIP;Slightly increases local contrast that was weakened by stretching.\nCan be completed by other tools specific to local contrast such as wavelets.\n\nWhen Stretch factor is 0.002 or less, Stretch Regularization & Midtones is disabled. +TP_LOCALLAB_GHS_MID;Midtones +TP_LOCALLAB_GHS_MID_TOOLTIP;Adjusts midtone balance after GHS transformation.\n Can be used to rebalance the midtones of the image after stretching.\n\nWhen Stretch factor is 0.002 or less, Stretch Regularization & Midtones is disabled +TP_LOCALLAB_GHS_BPFRAME_TOOLTIP;Sets the Black point (BP linear), White point (WP linear) and Highlight for a linear stretch of the image.\n\n * Black Point (BP linear) and White Point (WP linear) settings are only available if Stretch factor (D) is between 0.001 and 0.002 so as to not affect the histogram.\n\n * When Stretch factor is 0.002 or less, all stretch settings except for Black point and White point have no effect.\n\n * Black point (BP linear) and White point (WP linear) settings are sensitive to the general settings upstream of GHS: Highlight reconstruction, White balance and RAW processes.\n\n * To have relevant Black Point (BP linear) and White Point (WP linear) settings, the entire image must be analyzed. It is recommended to use 'Fit whole image to screen - Shortcut Alt-f'. +TP_LOCALLAB_GHS_BLACKPOINT_FRAME;Black point/White point/Highlights +TP_LOCALLAB_GHS_BLP;Black point (BP linear) +TP_LOCALLAB_GHS_BLP_TOOLTIP;Sets the Black point for a linear stretch of the image.\n * For negatives slider values, in GHS ‘normal’, shadows are raised linearly to avoid excessive noise build-up and facilitate GHS work.\n * For positives slider values, the histogram is shifted to the left. For Raw images, you can also use Raw-Tab > Raw Black Points – Dehaze, which is more precise.\n * Contrast gained by performing the linear stretch will be evenly distributed over the image.\n\n * You can adjust a linear black point offset to either:\n - account for noise in the deep shadows.\n - adjust the histogram.\n\n * It is recommended to adjust these sliders before the main GHS sliders to avoid clipping data. A very low Stretch factor (D) value (0.001 by default) is recommended for performing this adjustment.\n * The label 'Clipped pixel count Shadows:x Highlights=y' shows you the number of pixels that would be clipped without adjusting the two sliders.\n * The label Pixel values - Darkest:w Lightest:z shows you the minimum and maximum values in the range [0, 1].\n\n * In ‘Inverse GHS’ mode the behavior is reversed and there are possible interactions with the White point. +TP_LOCALLAB_GHS_HLP;White point (WP linear) +TP_LOCALLAB_GHS_METHOD_TOOLTIP;The Generalized Hyperbolic Stretch (GHS) process allows you to transform the values of pixels in your image to improve the representation of the underlying data for human visualisation.\nThe generalized hyperbolic equations used in the GHS process have five main parameters. This allows significant flexibility in designing the "shape" of the transformation.\n\nTypical uses of pixel intensity transformations include:\n * Initial stretch of pixel data from linear state.\n * Addition of contrast to key areas of the image.\n * Overall brightening or darkening of the image.\n * Adjustment of the image dynamic range.\n * Adjustment of pixel data in RGB Luminance, RGB standard, Luminance - chromaticity (Lab/Lch), Luminance (HSL), Saturation (HSL), or Hue (HSL) channels.\n\n * For a better results, you can proceed in several steps, creating 2 or more RT-spots each superimposed with the GHS tool. For each of the RT-Spots, the Symmetry point (SP) base value will be different. Use the histogram peak to position the SP value.\n * For example, you can start the system in RGB mode (1st Spot), then the 2nd Spot in RGB mode with a different SP, and the 3rd in Saturation or Hue mode.\n * You can mix RT-spots in 'Normal' mode and 'Inverse' mode to restore contrast balance.\n * Full Image allows you to limit the effect to specific colors based on the deltaE. +TP_LOCALLAB_GHS_HLP_TOOLTIP;Sets the White point for a linear stretch of the image. Any pixel with value greater than the White point input will be clipped and the data lost.\n * Contrast gained by performing the linear stretch will be evenly distributed over the image, which will be brightened. Pixels with values greater than the White point will appear white and have a value of 1.0.\n * Setting this parameter to a value greater than 1 will extend the dynamic range at the high end.\n * The 'Highlight reconstruction' method has a very strong impact on the White-point value.\n\n * It is recommended to adjust this slider before the main GHS sliders to avoid clipping data. A very low Stretch factor (D) value (0.001 by default) is recommended for performing this adjustment.\n * The label 'Clipped pixel count - Shadows:x Highlights=y' shows you the number of pixels that would be clipped without adjusting the two sliders.\n * The label Pixel values - Darkest:w Lightest:z shows you the minimum and maximum values in the range [0, 1].\n\n * In ‘Inverse GHS’ mode the behavior is reversed and there are possible interactions with the Black point. +TP_LOCALLAB_GHS_MODELIN;Linear +TP_LOCALLAB_GHS_MODECUR;GHS +TP_LOCALLAB_GHS_D_TOOLTIP;This parameter controls the amount of stretch. If the Stretch factor is set to zero, there is no stretch. In other words, the transformation is the identity transformation.\n\n * Black Point (BP linear) and White Point (WP linear) settings are only available if Stretch factor (D) is between 0.001 and 0.002. +TP_LOCALLAB_GHS_B_TOOLTIP;This parameter controls how tightly focused the stretch is around the Symmetry point (SP) by changing the form of the transform itself:\n * For concentrated stretches (such as initial stretches on linear images) a large 'b' factor should be employed to focus a stretch within a histogram peak while de-focusing the stretch away from the histogram peak.\n * For adjustment of non-linear images, lower 'b' parameters should be employed to distribute contrast and brightness more evenly.\n * Large positive values of 'b' can be thought of as a histogram widener, i.e. spreading the histogram wider about the focus point, SP.\n * By contrast, lower values of 'b' tend to shift the histogram to a brighter or dimmer position without affecting its width too greatly.\n * As a general rule, the level of 'b' employed will decrease as a stretch sequence nears completion, although larger 'b' values can still be employed for precise placement of additional contrast. +TP_LOCALLAB_GHS_SLOPE;Slope Lab factor (S) +TP_LOCALLAB_GHS_SLOPE_TOOLTIP;Changes the slope of the Lab transform to improve shadow rendering. +TP_LOCALLAB_GHS_CHRO;Chromaticity Lab factor (C) +TP_LOCALLAB_GHS_CHRO_TOOLTIP;GHS chromaticity - compensate large stretches +TP_LOCALLAB_GHSLABFRA;Lab settings +TP_LOCALLAB_GHS_SP_TOOLTIP;The default value of 0.015 is suitable for the majority of images.\n * This is the key balance value of the GHS system.\n * Sets the focus point around which the stretch is applied - contrast will be distributed symmetrically about SP.\n * While 'b' provides the degree of focus of the stretch, SP determines where that focus is applied.\n * SP should generally be placed within a histogram peak so that the stretch will widen and lower the peak by adding the most contrast in the stretch at that point. Pixel values will move away from the SP location. +TP_LOCALLAB_GHS_LP_TOOLTIP;Sets a value below which the stretch is modified to preserve contrast in the shadows/lowlights. This is done by performing a linear stretch of the data below the 'LP' level by reserving contrast from the rest of the image. Moving the LP level towards the current setting of SP changes both the scope (range) and the amount of this contrast reservation. The net effect is to push the overall stretch to higher brightness levels while keeping the contrast and definition in the background. The amount of contrast reserved for the lowlights is such that the continuity of the stretch is preserved.\n * This parameter must be at least 0 and no greater than the Symmetry point.\n * The adjuster will automatically limit the maximum value to the Symmetry Point (SP).\n\n * Using Black point - negative values - when possible, allows to change both the value of Symmetry point (SP) and the action of Protect shadows (LP). +TP_LOCALLAB_GHS_HP_TOOLTIP;Sets a value above which the stretch is modified to preserve contrast in the highlights. This is done by performing a linear stretch of the data above the 'HP' level by reserving contrast from the rest of the image. Moving the HP level towards the current setting of SP increases both the scope (range) and the amount of this contrast reservation. The net effect is to push the overall stretch to lower brightness levels while keeping the contrast and definition in the highlights. The amount of contrast reserved for the highlights is such that the continuity of the stretch is preserved.\n * This parameter must be at most 1 and no less than the Symmetry point.\n * The adjuster will automatically limits the maximum value to the Symmetry Point (SP).\n\n * Using Highlight attenuation helps to reinforce the action of Protect highlights (HP). +TP_LOCALLAB_GHS_SMOOTH_TOOLTIP;Smooth and soften highlight areas. Amplifies 'Protect highlights (HP)' action. +TP_LOCALLAB_GHS_SMOOTH;Highlight attenuation +TP_LOCALLAB_GHS_CURVE_TOOLTIP;Shows the 'S' curve generated by GHS calculations. Mainly for educational purposes.\n\n * The curve only reacts to the adjusters and cannot be modified directly. +TP_LOCALLAB_GHS_INV;Inverse GHS +TP_LOCALLAB_GHS_INV_TOOLTIP;The inverse GHS is useful for working in negative space. It adds contrast on the far right and left of the histogram, brightening the deep shadows, darkening the bright highlights, and squeezing the histogram to the middle.\n\n * The Generalized Hyperbolic inverse transformation allows you to recover your original image, subject to mathematical precision, but you can use it for other purposes.\n\n * If the White point and Black point were changed in normal mode, they will likely need to be readjusted. The White point often needs to be readjusted lower. There is interaction between the two settings. TP_LOCALLAB_GRADANG;Gradient angle TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. TP_LOCALLAB_GRADFRA;Graduated Filter Mask @@ -3274,7 +3334,7 @@ TP_LOCALLAB_GRADSTRLUM;Luma gradient strength TP_LOCALLAB_GRAINFRA;Film Grain 1:1 TP_LOCALLAB_GRAINFRA2;Coarseness TP_LOCALLAB_GRAIN_TOOLTIP;Adds film-like grain to the image. -TP_LOCALLAB_GRALWFRA;Graduated filter (local contrast) +TP_LOCALLAB_GRALWFRA;Graduated filter (local contrast: Full image & Global) TP_LOCALLAB_GRIDFRAME_TOOLTIP;You can use this tool as a brush. Use a small spot and adapt the 'Transition value' and 'Transition decay'\nOnly 'Normal' mode and possibly Hue, Saturation, Color, Luminosity are concerned by Merge background (ΔE). TP_LOCALLAB_GRIDMETH_TOOLTIP;Color toning: the luminance is taken into account when varying chroma. Equivalent to H=f(H) if the 'white dot' on the grid remains at zero and you only vary the 'black dot'. Equivalent to 'Color toning' if you vary the 2 dots.\n\nDirect: acts directly on the chroma. TP_LOCALLAB_GRIDONE;Color Toning @@ -3520,6 +3580,7 @@ TP_LOCALLAB_MRONE;None TP_LOCALLAB_MRTHR;Original Image TP_LOCALLAB_MULTIPL_TOOLTIP;Wide-range tone adjustment: -18EV to +4EV. The first slider acts on very dark tones between -18EV and -6EV. The last slider acts on light tones up to 4EV. TP_LOCALLAB_NEIGH;Radius +TP_LOCALLAB_NLDENOISENLITER_TOOLTIP;Run multiple iterations of Nlmeans. Results are often better with multiple iterations and low Strength. TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denoise to the size of the objects to be processed. TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Higher values increase denoise at the expense of processing time. @@ -3528,6 +3589,7 @@ TP_LOCALLAB_NLDET;Detail recovery TP_LOCALLAB_NLFRA;Non-local Means: Luminance TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means denoising takes a mean of all pixels in the image, weighted by how similar they are to the target pixel.\nReduces loss of detail compared with local mean algorithms.\nOnly luminance noise is taken into account. Chrominance noise is best processed using wavelets and Fourier transforms (DCT).\nCan be used in conjunction with 'Luminance denoise by level' or on its own. TP_LOCALLAB_NLGAM;Gamma +TP_LOCALLAB_NLITER;Iterations TP_LOCALLAB_NLLUM;Strength TP_LOCALLAB_NLPAT;Maximum patch size TP_LOCALLAB_NLRAD;Maximum radius size @@ -3635,12 +3697,13 @@ TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the scope of the action:\nSmall values limit t TP_LOCALLAB_SETTINGS;Settings TP_LOCALLAB_SH1;Shadows Highlights TP_LOCALLAB_SH2;Equalizer +TP_LOCALLAB_SH3;Generalized Hyperbolic Stretch TP_LOCALLAB_SHADEX;Shadows TP_LOCALLAB_SHADEXCOMP;Shadow compression -TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer +TP_LOCALLAB_SHADHIGH;Shadows/Highlights, Equalizer & GHS TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with 'Shadows Highlights' sliders, 'Tone Equalizer', or 'Generalized Hyperbolic Stretch' (GHS).\nCan be used instead of, or in conjunction with the Exposure module, or for GHS as a tone mapper. TP_LOCALLAB_SHAMASKCOL;Shadows TP_LOCALLAB_SHAPETYPE;Spot shape TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3685,7 +3748,7 @@ TP_LOCALLAB_SHOWT;Mask And Modifications TP_LOCALLAB_SHOWVI;Mask And Modifications TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). -TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer +TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights, Equalizer & GHS TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution TP_LOCALLAB_SIGCIE;Sigmoid TP_LOCALLAB_SIGFRA;Sigmoid Q & Slope based @@ -3776,7 +3839,7 @@ TP_LOCALLAB_SYMSL;Symmetrical (mouse + sliders) TP_LOCALLAB_TARGET_GRAY;Mean luminance (Yb%) TP_LOCALLAB_TE_PIVOT;Pivot (Ev) TP_LOCALLAB_THRES;Threshold structure -TP_LOCALLAB_THRESDELTAE;ΔE scope threshold +TP_LOCALLAB_THRESDELTAE;Range TP_LOCALLAB_THRESRETI;Threshold TP_LOCALLAB_THRESWAV;Balance threshold TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Mean=%3 Sig=%4 @@ -3795,10 +3858,10 @@ TP_LOCALLAB_TOOLMASK;Mask Tools TP_LOCALLAB_TOOLMASK_2;Wavelets TP_LOCALLAB_TOOLMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' checked: in this case a mask showing the structure will be generated after one or more of the 2 curves L(L) or LC(H) has been modified.\n Here, the 'Structure mask' behaves like the other Mask tools : Gamma, Slope, etc.\n It allows you to vary the action on the mask according to the structure of the image. TP_LOCALLAB_TRANSIT;Transition Gradient -TP_LOCALLAB_TRANSITGRAD;Transition differentiation XY +TP_LOCALLAB_TRANSITGRAD;Symmetry X & Y TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. -TP_LOCALLAB_TRANSITVALUE;Transition value -TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) +TP_LOCALLAB_TRANSITVALUE;Value +TP_LOCALLAB_TRANSITWEAK;Decay (linear-log) TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 5e92ab8cf..a651adffa 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -875,6 +875,7 @@ void Crop::update(int todo) auto& lmasklocalcurve2 = parent->lmasklocalcurve; auto& lmaskexplocalcurve2 = parent->lmaskexplocalcurve; auto& lmaskSHlocalcurve2 = parent->lmaskSHlocalcurve; + // auto& ghslocalcurve2 = parent->ghslocalcurve; auto& lmaskviblocalcurve2 = parent->lmaskviblocalcurve; auto& lmasktmlocalcurve2 = parent->lmasktmlocalcurve; auto& lmaskretilocalcurve2 = parent->lmaskretilocalcurve; @@ -954,6 +955,8 @@ void Crop::update(int todo) auto& locwavCurveden = parent->locwavCurveden; auto& lmasklocal_curve2 = parent->lmasklocal_curve; auto& loclmasCurve_wav = parent->loclmasCurve_wav; + //big bug found 29//11/2024 + std::vector localldenoiselc; for (int sp = 0; sp < (int)params.locallab.spots.size(); sp++) { locRETgainCurve.Set(params.locallab.spots.at(sp).localTgaincurve); @@ -1026,6 +1029,7 @@ void Crop::update(int todo) const bool localmaskutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve2, skip); const bool localmaskexputili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskexpcurve, lmaskexplocalcurve2, skip); const bool localmaskSHutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).LmaskSHcurve, lmaskSHlocalcurve2, skip); + // const bool localghsutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).ghscurve, ghslocalcurve2, skip); const bool localmaskvibutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskvibcurve, lmaskviblocalcurve2, skip); const bool localmasktmutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmasktmcurve, lmasktmlocalcurve2, skip); const bool localmaskretiutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskreticurve, lmaskretilocalcurve2, skip); @@ -1050,7 +1054,6 @@ void Crop::update(int todo) if (black < 0. && params.locallab.spots.at(sp).expMethod == "pde" ) { black *= 1.5; } - std::vector localldenoiselc; double cont = params.locallab.spots.at(sp).contrast; double huere, chromare, lumare, huerefblu, chromarefblu, lumarefblu, sobelre; @@ -1094,6 +1097,9 @@ void Crop::update(int todo) float slopeg = 1.f; bool linkrgb = true; float lightsig = params.locallab.spots.at(sp).lightsigqcie; + int ghsbpwp[2]; + float ghsbpwpvalue[2]; + /* huerefp[sp] = huere; chromarefp[sp] = chromare; lumarefp[sp] = lumare; @@ -1107,7 +1113,7 @@ void Crop::update(int todo) if (sp == params.locallab.selspot) { - parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop.get(), savenormtmCrop.get(), savenormretiCrop.get(), lastorigCrop.get(), fw, fh, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, locRETtransCurve, + parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop.get(), savenormtmCrop.get(), savenormretiCrop.get(), lastorigCrop.get(), fw, fh, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), trafx, trafy, trafw, trafh , skip, locRETgainCurve, locRETtransCurve, lllocalcurve2,locallutili, cllocalcurve2, localclutili, lclocalcurve2, locallcutili, @@ -1117,6 +1123,7 @@ void Crop::update(int todo) lmasklocalcurve2, localmaskutili, lmaskexplocalcurve2, localmaskexputili, lmaskSHlocalcurve2, localmaskSHutili, + // ghslocalcurve2, localghsutili, lmaskviblocalcurve2, localmaskvibutili, lmasktmlocalcurve2, localmasktmutili, lmaskretilocalcurve2, localmaskretiutili, @@ -1164,18 +1171,9 @@ void Crop::update(int todo) parent->previewDeltaE, parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallExpMaskinv, parent->locallSHMask, parent->locallSHMaskinv, parent->locallvibMask, parent->localllcMask, parent->locallsharMask, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask, parent->localllogMask, parent->locall_Mask, parent->locallcieMask, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, meantme, stdtme, meanretie, stdretie, fab, maxicam,rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, - highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46, slopeg, linkrgb); + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46,slopeg, linkrgb, + ghsbpwp, ghsbpwpvalue); - LocallabListener::locallabDenoiseLC denoiselc; - denoiselc.highres = highresi; - denoiselc.nres = nresi; - denoiselc.highres46 = highresi46; - denoiselc.nres46 = nresi46; - denoiselc.Lhighres = Lhighresi; - denoiselc.Lnres = Lnresi; - denoiselc.Lhighres46 = Lhighresi46; - denoiselc.Lnres46 = Lnresi46; - localldenoiselc.push_back(denoiselc); if (parent->previewDeltaE || parent->locallColorMask == 5 || parent->locallvibMask == 4 || parent->locallExpMask == 5 || parent->locallSHMask == 4 || parent->localllcMask == 4 || parent->localltmMask == 4 || parent->localllogMask == 4 || parent->locallsoftMask == 6 || parent->localllcMask == 4 || parent->locallcieMask == 4) { params.blackwhite.enabled = false; @@ -1206,23 +1204,8 @@ void Crop::update(int todo) } */ - denoiselc.highres = highresi; - denoiselc.nres = nresi; - denoiselc.highres46 = highresi46; - denoiselc.nres46 = nresi46; - denoiselc.Lhighres = Lhighresi; - denoiselc.Lnres = Lnresi; - denoiselc.Lhighres46 = Lhighresi46; - denoiselc.Lnres46 = Lnresi46; - localldenoiselc.push_back(denoiselc); - - - if (parent->locallListener) { - parent->locallListener->denChanged(localldenoiselc, params.locallab.selspot); - } - } else { - parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop.get(), savenormtmCrop.get(), savenormretiCrop.get(), lastorigCrop.get(), fw, fh, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, locRETtransCurve, + parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop.get(), savenormtmCrop.get(), savenormretiCrop.get(), lastorigCrop.get(), fw, fh, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), trafx, trafy, trafw , trafh, skip, locRETgainCurve, locRETtransCurve, lllocalcurve2,locallutili, cllocalcurve2, localclutili, lclocalcurve2, locallcutili, @@ -1231,6 +1214,7 @@ void Crop::update(int todo) lmasklocalcurve2, localmaskutili, lmaskexplocalcurve2, localmaskexputili, lmaskSHlocalcurve2, localmaskSHutili, + // ghslocalcurve2, localghsutili, lmaskviblocalcurve2, localmaskvibutili, lmasktmlocalcurve2, localmasktmutili, lmaskretilocalcurve2, localmaskretiutili, @@ -1277,8 +1261,25 @@ void Crop::update(int todo) huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, - highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46, slopeg, linkrgb); + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46,slopeg, linkrgb, + ghsbpwp, ghsbpwpvalue); } + + + LocallabListener::locallabDenoiseLC denoiselc; + denoiselc.highres = highresi; + denoiselc.nres = nresi; + denoiselc.highres46 = highresi46; + denoiselc.nres46 = nresi46; + denoiselc.Lhighres = Lhighresi; + denoiselc.Lnres = Lnresi; + denoiselc.Lhighres46 = Lhighresi46; + denoiselc.Lnres46 = Lnresi46; + localldenoiselc.push_back(denoiselc); + + if (parent->locallListener) { + parent->locallListener->denChanged(localldenoiselc, params.locallab.selspot); + } if (sp + 1u < params.locallab.spots.size()) { diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 106dbba90..376a67842 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -211,6 +211,7 @@ ImProcCoordinator::ImProcCoordinator() : lmasklocalcurve(65536, LUT_CLIP_OFF), lmaskexplocalcurve(65536, LUT_CLIP_OFF), lmaskSHlocalcurve(65536, LUT_CLIP_OFF), + ghslocalcurve(65536, LUT_CLIP_OFF), lmaskviblocalcurve(65536, LUT_CLIP_OFF), lmasktmlocalcurve(65536, LUT_CLIP_OFF), lmaskretilocalcurve(65536, LUT_CLIP_OFF), @@ -1151,6 +1152,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) //std::vector locallref; std::vector locallretiminmax; std::vector locallcielc; + std::vector locallshgshbw; std::vector locallsetlc; std::vector locallciesig; huerefs.resize(params->locallab.spots.size()); @@ -1265,6 +1267,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) const bool localmaskutili = CurveFactory::diagonalCurve2Lut(params->locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve, sca); const bool localmaskexputili = CurveFactory::diagonalCurve2Lut(params->locallab.spots.at(sp).Lmaskexpcurve, lmaskexplocalcurve, sca); const bool localmaskSHutili = CurveFactory::diagonalCurve2Lut(params->locallab.spots.at(sp).LmaskSHcurve, lmaskSHlocalcurve, sca); + // const bool localghsutili = CurveFactory::diagonalCurve2Lut(params->locallab.spots.at(sp).ghscurve, ghslocalcurve, sca); const bool localmaskvibutili = CurveFactory::diagonalCurve2Lut(params->locallab.spots.at(sp).Lmaskvibcurve, lmaskviblocalcurve, sca); const bool localmasktmutili = CurveFactory::diagonalCurve2Lut(params->locallab.spots.at(sp).Lmasktmcurve, lmasktmlocalcurve, sca); const bool localmaskretiutili = CurveFactory::diagonalCurve2Lut(params->locallab.spots.at(sp).Lmaskreticurve, lmaskretilocalcurve, sca); @@ -1398,13 +1401,18 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float Lnresi = 0.f; float Lhighresi46 = 0.f; float Lnresi46 = 0.f; + int ghsbpwp[2] = {0, 0}; + float ghsbpwpvalue[2] = {0.f, 1.f}; + Glib::ustring prof = params->icm.workingProfile; if(params->locallab.spots.at(sp).complexcie == 2) { params->locallab.spots.at(sp).primMethod = prof;//in Basic mode set to Working profile } float slopeg = 1.f; bool linkrgb = true; - ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv.get(), savenormtm.get(), savenormreti.get(), lastorigimp.get(), fw, fh, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, + + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv.get(), savenormtm.get(), savenormreti.get(), lastorigimp.get(), fw, fh, 0, 0, pW, pH, pW, pH, pW, pH, scale, locRETgainCurve, locRETtransCurve, + // ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv.get(), savenormtm.get(), savenormreti.get(), lastorigimp.get(), fw, fh, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, lllocalcurve, locallutili, cllocalcurve, localclutili, lclocalcurve, locallcutili, @@ -1413,6 +1421,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lmasklocalcurve, localmaskutili, lmaskexplocalcurve, localmaskexputili, lmaskSHlocalcurve, localmaskSHutili, + // ghslocalcurve, localghsutili, lmaskviblocalcurve, localmaskvibutili, lmasktmlocalcurve, localmasktmutili, lmaskretilocalcurve, localmaskretiutili, @@ -1459,7 +1468,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, meantm, stdtm, meanreti, stdreti, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, - highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46, slopeg, linkrgb); + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46, slopeg, linkrgb, + ghsbpwp, ghsbpwpvalue); fabrefp[sp] = fab; @@ -1571,6 +1581,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locciesig.lightsigq = lightsig; locallciesig.push_back(locciesig); + LocallabListener::locallabshGHSbw locshghsbw;//ghs S curve + for(int j = 0; j < 2; j++) { + locshghsbw.ghsbw[j] = ghsbpwp[j]; + locshghsbw.ghsbwvalue[j] = ghsbpwpvalue[j]; + } + locallshgshbw.push_back(locshghsbw); + // Recalculate references after if (params->locallab.spots.at(sp).spotMethod == "exc") { @@ -1611,7 +1628,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) bool iscbdl = params->locallab.spots.at(sp).expcbdl; bool islog = params->locallab.spots.at(sp).explog; bool ismas = params->locallab.spots.at(sp).expmask; - bool iscie = params->locallab.spots.at(sp).expcie; + bool isci = params->locallab.spots.at(sp).expcie; // bool isset = iscolor || issh || isvib; //set select spot settings @@ -1630,7 +1647,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locsetlc.iscbd = iscbdl; locsetlc.islo = islog; locsetlc.isma = ismas; - locsetlc.isci = iscie; + locsetlc.isci = isci; locallsetlc.push_back(locsetlc); if (locallListener) { @@ -1640,6 +1657,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locallListener->cieChanged(locallcielc,params->locallab.selspot); } locallListener->sigChanged(locallciesig,params->locallab.selspot); + if (params->locallab.spots.at(sp).expshadhigh && params->locallab.spots.at(sp).shMethod == "ghs") { + locallListener->ghsbwChanged(locallshgshbw,params->locallab.selspot);//Black and White point + } + /* if(params->locallab.spots.at(sp).colorscope != 0) {//compatibility with old method in controlspotpanel locallListener->scopeChangedcol(scopefp[sp], params->locallab.selspot, iscolor); @@ -1670,7 +1691,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) //************************************************************* } - if ((todo & M_RGBCURVE) || (todo & M_CROP)) { //complexCurve also calculated pre-curves histogram depending on crop CurveFactory::complexCurve(params->toneCurve.expcomp, params->toneCurve.black / 65535.0, diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 52ad8e6f6..2d96ff5fb 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -280,6 +280,7 @@ protected: LUTf lmasklocalcurve; LUTf lmaskexplocalcurve; LUTf lmaskSHlocalcurve; + LUTf ghslocalcurve; LUTf lmaskviblocalcurve; LUTf lmasktmlocalcurve; LUTf lmaskretilocalcurve; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 801f74f0d..a4d2d0f91 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -107,6 +107,32 @@ struct WaveletParams; enum RenderingIntent : int; +// From Siril. +struct ght_compute_params { + float qlp;//protect shadows + float q0; + float qwp;//protect highlights - white point + float q1; + float q; + float b1; + float a1; + float a2; + float b2; + float c2; + float d2; + float e2; + float a3; + float b3; + float c3; + float d3; + float e3; + float a4; + float b4; + float LPT;//inverse protect shadow + float SPT;//inverse symmetric point + float HPT;//inverse protect highlight +}; + class ImProcFunctions { cmsHTRANSFORM monitorTransform; @@ -273,7 +299,7 @@ enum class BlurType { void idirpyr(LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab, int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/); //locallab Local adjustments - void maskcalccol(bool invmask, bool pde, int bfw, int bfh, int xstart, int ystart, int sk, int cx, int cy, LabImage* bufcolorig, LabImage* bufmaskblurcol, LabImage* originalmaskcol, LabImage* original, LabImage* reserved, int inv, struct local_params & lp, + void maskcalccol(int call, bool invmask, bool pde, int bfw, int bfh, int oW, int oH, int tX, int tY, int tW, int tH, int xstart, int ystart, int xend, int yend, int sk, int cx, int cy, LabImage* bufcolorig, LabImage* bufmaskblurcol, LabImage* originalmaskcol, LabImage* original, LabImage* reserved, int inv, struct local_params & lp, float strumask, bool astool, const LocCCmaskCurve & locccmasCurve, bool lcmasutili, const LocLLmaskCurve & locllmasCurve, bool llmasutili, @@ -282,7 +308,7 @@ enum class BlurType { const LUTf& lmasklocalcurve, bool localmaskutili, const LocwavCurve & loclmasCurvecolwav, bool lmasutilicolwav, int level_bl, int level_hl, int level_br, int level_hr, int shortcu, bool delt, const float hueref, const float chromaref, const float lumaref, - float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope, bool fftt, float blu_ma, float cont_ma, int indic, float &fab); + float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope, bool fftt, float blu_ma, float cont_ma, int indic, float &fab, int fw, int fh, float ksk, float kskx, float kbh, float kbw); void avoidcolshi(const struct local_params& lp, int sp, LabImage *transformed, LabImage *reserved, int cy, int cx, int sk); @@ -332,7 +358,7 @@ enum class BlurType { void calc_ref(int sp, LabImage* original, LabImage* transformed, int cx, int cy, int oW, int oH, int sk, double &huerefblur, double &chromarefblur, double &lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, float &avg, const LocwavCurve & locwavCurveden, bool locwavdenutili); void copy_ref(LabImage* spotbuffer, LabImage* original, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp, double &huerefspot, double &chromarefspot, double &lumarefspot); void paste_ref(LabImage* spotbuffer, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp); - void Lab_Local(int call, int sp, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, LabImage * savenormtm, LabImage * savenormreti, LabImage* lastorig, int fw, int fh, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve& locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, + void Lab_Local(int call, int sp, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, LabImage * savenormtm, LabImage * savenormreti, LabImage* lastorig, int fw, int fh, int cx, int cy, int oW, int oH, int tX, int tY, int tW, int tH, int sk, const LocretigainCurve& locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, const LUTf& lllocalcurve, bool locallutili, const LUTf& cllocalcurve, bool localclutili, const LUTf& lclocalcurve, bool locallcutili, @@ -341,6 +367,7 @@ enum class BlurType { const LUTf& lmasklocalcurve, bool localmaskutili, const LUTf& lmaskexplocalcurve, bool localmaskexputili, const LUTf& lmaskSHlocalcurve, bool localmaskSHutili, + // const LUTf& ghslocalcurve, bool localghsutili, const LUTf& lmaskviblocalcurve, bool localmaskvibutili, const LUTf& lmasktmlocalcurve, bool localmasktmutili, LUTf& lmaskretilocalcurve, bool localmaskretiutili, @@ -389,7 +416,16 @@ enum class BlurType { bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &prim, int &ill, float &contsig, float &lightsig, - float &highresi, float &nresi, float &highresi46, float &nresi46, float &Lhighresi, float &Lnresi, float &Lhighresi46, float &Lnresi46, float &slopeg, bool &linkrgb); + float &highresi, float &nresi, float &highresi46, float &nresi46, float &Lhighresi, float &Lnresi, float &Lhighresi46, float &Lnresi46, float &slopeg, bool &linkrgb, + int *ghsbpwp, float *ghsbpwpvalue); + + enum class GHTStrType { + NORMAL, + INVERSE, + }; + + static ght_compute_params GHT_setup(float in_B, float D, float LP, float SP, float HP, GHTStrType strtype); + static float GHT(float x, float B, float D, float LP, float SP, float HP, ght_compute_params c, GHTStrType strtype); void tone_eqcam2(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread); void tone_eqdehaz(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread); @@ -411,13 +447,13 @@ enum class BlurType { static void strcurv_data(std::string retistr, int *s_datc, int &siz); void blendstruc(int bfw, int bfh, LabImage* bufcolorig, float radius, float stru, array2D & blend2, int sk, bool multiThread); - void wavcontrast4(struct local_params& lp, float ** tmp, float ** tmpa, float ** tmpb, float contrast, float radblur, float radlevblur, int bfw, int bfh, int level_bl, int level_hl, int level_br, int level_hr, int sk, int numThreads, const LocwavCurve & locwavCurve, bool locwavutili, bool wavcurve, + void wavcontrast4(int call, struct local_params& lp, float ** tmp, float ** tmpa, float ** tmpb, float contrast, float radblur, float radlevblur, int bfw, int bfh, int oW, int oH, int tX, int tY, int tW, int tH, int level_bl, int level_hl, int level_br, int level_hr, int sk, int numThreads, const LocwavCurve & locwavCurve, bool locwavutili, bool wavcurve, const LocwavCurve & loclevwavCurve, bool loclevwavutili, bool wavcurvelev, const LocwavCurve & locconwavCurve, bool locconwavutili, bool wavcurvecon, const LocwavCurve & loccompwavCurve, bool loccompwavutili, bool wavcurvecomp, const LocwavCurve & loccomprewavCurve, bool loccomprewavutili, bool wavcurvecompre, const LocwavCurve & locedgwavCurve, bool locedgwavutili, - float sigm, float offs,int & maxlvl, float sigmadc, float deltad, float chromalev, float chromablu, bool blurlc, bool blurena, bool levelena, bool comprena, bool compreena, float compress, float thres); + float sigm, float offs,int & maxlvl, float sigmadc, float deltad, float chromalev, float chromablu, bool blurlc, bool blurena, bool levelena, bool comprena, bool compreena, float compress, float thres, int fw, int fh, int cx, int cy, float ksk, float kskx, float kbh, float kbw); void wavcont(const struct local_params& lp, float ** tmp, wavelet_decomposition &wdspot, int level_bl, int maxlvl, const LocwavCurve & loclevwavCurve, bool loclevwavutili, @@ -430,7 +466,12 @@ enum class BlurType { void wavcbd(wavelet_decomposition &wdspot, int level_bl, int maxlvl, const LocwavCurve& locconwavCurve, bool locconwavutili, float sigm, float offs, float chromalev, int sk); - void transit_shapedetect2(int sp, float meantm, float stdtm, int call, int senstype, const LabImage * bufexporig, const LabImage * bufexpfin, LabImage * originalmask, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk); + enum class LocalLabGradientMode { + STANDARD, + PLAIN_IMAGE, + }; + + void transit_shapedetect2(int sp, float meantm, float stdtm, int call, int senstype, const LabImage * bufexporig, const LabImage * bufexpfin, LabImage * originalmask, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage *tmp1, LocalLabGradientMode grad, int cx, int cy, int sk); void transit_shapedetect_retinex(int call, int senstype, LabImage * bufexporig, LabImage * bufexpfin, LabImage * bufmask, LabImage * buforigmas, float **buflight, float **bufchro, const float hueref, const float chromaref, const float lumaref, struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk); void transit_shapedetect(int senstype, const LabImage *bufexporig, LabImage * originalmask, float **bufchro, bool HHutili, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, const struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index cc88b4d46..148545142 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -45,7 +45,7 @@ inline void copyAndClampLine(const float *src, unsigned char *dst, const int W) } -inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double rgb_xyz[3][3], bool multiThread) +inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double rgb_xyz[3][3], bool multiThread, int pro)//int pro to switch to Working Profile histogram mode without gamma { const int W = src->W; const int H = src->H; @@ -89,9 +89,15 @@ inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double r vfloat x_, y_, z_; Color::Lab2XYZ(LVFU(rL[j]), LVFU(ra[j]), LVFU(rb[j]), x_, y_, z_); Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyzv); - STVF(rbuffer[j], Color::gamma2curve[R]); - STVF(gbuffer[j], Color::gamma2curve[G]); - STVF(bbuffer[j], Color::gamma2curve[B]); + if(pro == 0) { + STVF(rbuffer[j], Color::gamma2curve[R]); + STVF(gbuffer[j], Color::gamma2curve[G]); + STVF(bbuffer[j], Color::gamma2curve[B]); + } else {//Working profile and gamma=1 + STVF(rbuffer[j], R); + STVF(gbuffer[j], G); + STVF(bbuffer[j], B); + } } for (; j < W; ++j) { @@ -99,9 +105,15 @@ inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double r float x_, y_, z_; Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_); Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyzf); - rbuffer[j] = Color::gamma2curve[R]; - gbuffer[j] = Color::gamma2curve[G]; - bbuffer[j] = Color::gamma2curve[B]; + if(pro == 0) { + rbuffer[j] = Color::gamma2curve[R]; + gbuffer[j] = Color::gamma2curve[G]; + bbuffer[j] = Color::gamma2curve[B]; + } else {//Working profile and gamma=1 + rbuffer[j] = R; + gbuffer[j] = G; + bbuffer[j] = B; + } } for (j = 0; j < W; ++j) { @@ -117,10 +129,15 @@ inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double r float x_, y_, z_; Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_); Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyzf); - - dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[R]); - dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[G]); - dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[B]); + if(pro == 0) { + dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[R]); + dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[G]); + dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[B]); + } else {//Working profile and gamma=1 + dst[ix++] = uint16ToUint8Rounded(R); + dst[ix++] = uint16ToUint8Rounded(G); + dst[ix++] = uint16ToUint8Rounded(B); + } } #endif @@ -204,7 +221,7 @@ void ImProcFunctions::lab2monitorRgb(LabImage* lab, Image8* image) } } // End of parallelization } else { - copyAndClamp(lab, image->data, sRGB_xyz, multiThread); + copyAndClamp(lab, image->data, sRGB_xyz, multiThread, 0);//int pro = 0 always sent 'normal' to monitor } } @@ -239,12 +256,13 @@ Image8* ImProcFunctions::lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile; cmsHPROFILE oprof = nullptr; - + int pro = 0;//int pro to switch to Working Profile histogram mode without gamma if (settings->HistogramWorking && consider_histogram_settings) { profile = icm.workingProfile; + pro = 1;//no gamma for histogram and navigator panel and Lockable color picker } else { profile = icm.outputProfile; - + //pro = 0 histogram and navigator panel and Lockable color picker with gamma if (icm.outputProfile.empty() || icm.outputProfile == ColorManagementParams::NoICMString) { profile = "sRGB"; } @@ -300,7 +318,7 @@ Image8* ImProcFunctions::lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, } else { const auto xyz_rgb = ICCStore::getInstance()->workingSpaceInverseMatrix(profile); - copyAndClamp(lab, image->data, xyz_rgb, multiThread); + copyAndClamp(lab, image->data, xyz_rgb, multiThread, pro);//int pro = 1 to switch to Working Profile for histogram and navigator panel and Lockable color picker whitout gamma } return image; diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 2e32acb00..696a6f68c 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -127,6 +127,182 @@ float softlig(float a, float b, float minc, float maxc) } } +// GHT filter ported from Siril. +// +// see https://siril.org/tutorials/ghs/ for more info +// +// Copyright of the original code follows +/* + * Copyright (C) 2005-2011 Francois Meyer (dulle at free.fr) + * Copyright (C) 2012-2023 team free-astro (see more in AUTHORS file) + * Reference site is https://free-astro.org/index.php/Siril + * + * Siril is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Siril is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Siril. If not, see . + */ +/* +//Copyright algorithm Pixlnsight David Payne 2021 +https://www.ghsastro.co.uk/doc/tools/GeneralizedHyperbolicStretch/GeneralizedHyperbolicStretch.html#__Description_:_About_GHS__ +*/ +/* + * Thanks to Alberto Griggio for the code CTL ght.ctl +*/ + +/* +https://www.ghsastro.co.uk/doc/tools/GeneralizedHyperbolicStretch/GeneralizedHyperbolicStretch.html#equationLabel + +Summary of calculations made during GHS + + +5.2.1 Definition of variables +D = e(Stretch factor) - 1 +b = Local intensity +SP = Symmetry point +LP = Protect shadows +HP = Protect highlights + +5.2.2 Base transformation equations +The base transformation for each transformation type is defined by T : x → T(x) in the following table. The table also shows the first derivative of T, denoted T', as this is needed to build the full transformation. + +Generalised hyperbolic +Exponential +b = 0 +T ->1 - e-D.x +T'->D.e-D.x + +Generalised hyperbolic +Logarithmic +b = -1 +T ->ln( 1 + D.x ) +T'= D/( 1 + D.x ) + +Generalised hyperbolic +Integral +b < 0, b ≠ -1 +T->(1 - (1 - b.D.x)((b + 1)/b))/(D.(b + 1)) +T'->( 1 - b.D.x )(1/b) + +Generalised hyperbolic +Harmonic +b = 1 +T->1 - ( 1 + D.x )-1 +T'-> D.( 1 + D.x )-2 + +Generalised hyperbolic +Hyperbolic +b > 0, b ≠ 1 +T-> 1 - ( 1 + b.D.x )(-1/b) +T'->D.(1 + b.D.x)(-(1+b)/b) + + +Power law +T(x) = 1 - (1 - x)1 + D +T'(x) = (1 + D).(1 - x)D + + +The maximum gradient for the base equations occurs at x=0. This point defines the point of maximum intensity and we want that to occur at x = SP. So we transform the equation by defining: +T3(x) = T(x-SP). +This broadly defines the transformation for the range SP ≤ x < HP although it will need to be normalised as described later below. +The transformation for LP ≤ x < SP is defined by symmetry as follows: +T2(x) = -T(SP-x). +This, in effect, is equivalent to rotating the graph above SP through 180° around the point (SP, 0) - hence the name, Symmetry point. +For the range 0.0 ≤ x < LP we want a linear transformation so we calculate the gradient of T2 at LP, ie T2'(LP), where the prime represents the first derivative. We also want the line to pass through the point (LP, T2(LP)). So we define: +T1(x) = T2'(LP) * (x - LP) + T2(LP) +Similarly for the range HP ≤ x ≤ 1.0, we calculate a linear transformation as follows: +T4(x) = T3'(HP) * (x - HP) + T3(HP) +Finally we want the transformed values to run from 0.0 to 1.0 so we need to normalise. We define: +NormTi(x) = (Ti(x) - T1(0))/(T4(1) - T1(0)), for i = 1, 2, 3, 4 + +We then define the full transformation: NormT: x → NormT(x), as follows: +0 ≤ x < LP +NormT1(x) + +LP ≤ x < SP +NormT2(x) + +SP ≤ x < HP +NormT3(x) + +HP ≤ x ≤ 1 +NormT4(x) + + +Inverse transformation equations +Generalised hyperbolic +Exponential +b = 0 +InvT(x) = -ln(1 - x)/D + +Generalised hyperbolic +Logarithmic +b = -1 +InvT(x) = (ex - 1)/D + +Generalised hyperbolic +Integral +b < 0, b ≠ -1 +InvT(x) = ((1 - (1 - (b+1).D.x)(b/(b+1)))/(D.b) + +Generalised hyperbolic +Harmonic +b = 1 +InvT(x) = /(D.(1 - x)) + +Generalised hyperbolic +Hyperbolic +b > 0, b ≠ 1 +InvT(x) = ((1 - x)-b - 1)/(b.D) + +Power law +InvT(x) = 1 - (1 - x)1/(1 + D) + +Then we can define the full inverse transformation InvNormT: x -> InvNormT(x), as follows: + +0 ≤ x < NormT(LP) +LP + (x' - T2(LP))/T2'(LP) + +NormT(LP) ≤ x < NormT(SP) +SP - InvT(-x') + +NormT(SP) ≤ x < NormT(HP) +SP + InvT(x') + +NormT(HP) ≤ x ≤ 1 +HP + (x' - T3(HP))/T3'(HP) + +where +x' = T1(0) + x.(T4(1) - T1(0)) +*/ + +/* +In a simplified way, an S-curve (or inverted S-curve) modifies the image. +The inflection point is defined by SP (Symmetry Point), for example 0.5 will generate a symmetrical 'S-curve' for RGB values ​​lower than SP or Higher. + +Stretch factor will make this curve more or less pronounced with very gradual asymptotes in the low and high lights. + +Linear factor will change the shape of the S, reducing or increasing the "length" of the asymptotic parts. + +All 3 allow you to modify the contrast of the image by filling the valleys and reducing the peaks + +*/ +float clamp(float x, float lo, float hi) +{ + return fmax(fmin(x, hi), lo); +} + +// end GHT Siril + + float softlig3(float a, float b) { // as w3C @@ -359,10 +535,10 @@ float calclightinv(float lum, float koef, const LUTf &lightCurveloc) float balancedeltaE(float kL) { - constexpr float mincurs = 0.3f; // minimum slider balan_ - constexpr float maxcurs = 1.7f; // maximum slider balan_ - constexpr float maxkab = 1.35; // 0.5 * (3 - 0.3) - constexpr float minkab = 0.65; // 0.5 * (3 - 1.7) + constexpr float mincurs = 0.05f; //0.3f; // minimum slider balan_ + constexpr float maxcurs = 2.5f; //1.7f; // maximum slider balan_ + constexpr float maxkab = 1.475f; //1.35; // 0.5 * (3 - 0.3) + constexpr float minkab = 0.25f; //0.65; // 0.5 * (3 - 1.7) constexpr float abal = (maxkab - minkab) / (mincurs - maxcurs); constexpr float bbal = maxkab - mincurs * abal; return abal * kL + bbal; @@ -470,6 +646,7 @@ using namespace procparams; struct local_params { float yc, xc; + float ycent, xcent; float lx, ly; float lxL, lyT; float transweak; @@ -716,6 +893,8 @@ struct local_params { float contciemask; bool islogcie; bool issmoothcie; + bool issmoothghs; + float ghshp; int noiselequal; float noisechrodetail; float bilat; @@ -723,6 +902,7 @@ struct local_params { int nldet; int nlpat; int nlrad; + int nliter; float nlgam; float noisegam; float noiselc; @@ -1000,6 +1180,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.fftcieMask = locallab.spots.at(sp).fftcieMask; lp.islogcie = locallab.spots.at(sp).logcie && locallab.spots.at(sp).expprecam; lp.issmoothcie = locallab.spots.at(sp).smoothcie; + lp.issmoothghs = locallab.spots.at(sp).ghs_smooth; + lp.ghshp = locallab.spots.at(sp).ghs_HP; lp.enaColorMask = locallab.spots.at(sp).enaColorMask && llsoftMask == 0 && llColorMaskinv == 0 && llSHMaskinv == 0 && llColorMask == 0 && llExpMaskinv == 0 && lllcMask == 0 && llsharMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaColorMaskinv = locallab.spots.at(sp).enaColorMask && llColorMaskinv == 0 && llSHMaskinv == 0 && llsoftMask == 0 && lllcMask == 0 && llsharMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaExpMask = locallab.spots.at(sp).enaExpMask && llExpMask == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && llColorMask == 0 && llColorMaskinv == 0 && llsoftMask == 0 && lllcMask == 0 && llsharMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0;// Exposure mask is deactivated if Color & Light mask is visible @@ -1064,6 +1246,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.shmeth = 0; } else if (locallab.spots.at(sp).shMethod == "tone") { lp.shmeth = 1; + } else if (locallab.spots.at(sp).shMethod == "ghs") { + lp.shmeth = 2; } @@ -1558,6 +1742,9 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.actsp = acti; lp.xc = w * local_center_x; lp.yc = h * local_center_y; + lp.xcent = local_center_x; + lp.ycent = local_center_y; + // printf("lp.xc=%f lp.yc=%f \n", (double) lp.xc, (double) lp.yc); lp.lx = w * local_x; lp.ly = h * local_y; lp.lxL = w * local_xL; @@ -1801,6 +1988,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.nlpat = locallab.spots.at(sp).nlpat; lp.nlrad = locallab.spots.at(sp).nlrad; lp.nlgam = locallab.spots.at(sp).nlgam; + lp.nliter = locallab.spots.at(sp).nliter; lp.noisegam = locallab.spots.at(sp).noisegam; lp.adjch = (float) locallab.spots.at(sp).adjblur; lp.strengt = streng; @@ -2402,6 +2590,7 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool [=](float s, float c) -> float { if (c > noise) { + return 1.f - min(std::abs(s) / c, 1.f); } else { return 0.f; @@ -2698,7 +2887,6 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, void tone_eq(ImProcFunctions *ipf, Imagefloat *rgb, const struct local_params &lp, const Glib::ustring &workingProfile, double scale, bool multithread) { - ToneEqualizerParams params; params.enabled = true; params.regularization = lp.detailsh; @@ -2723,7 +2911,6 @@ void ImProcFunctions::tone_eqcam(ImProcFunctions *ipf, Imagefloat *rgb, int midt params.bands[1] = sign(midtone) * (mid - threshmid); params.bands[3] = sign(midtone) * (mid - threshmid); } - ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); } @@ -2743,14 +2930,18 @@ void tone_eqsmooth(ImProcFunctions *ipf, Imagefloat *rgb, const struct local_par if(lp.whiteevjz < 6) {//EV = 6 majority of images params.bands[4] = -15; } - if(lp.islogcie) {//with log encoding Cie - params.bands[4] = -15; - params.bands[5] = -50; - if(lp.whiteevjz < 6) { + if(lp.islogcie || lp.issmoothghs) {//with log encoding Cie and GHS shadows Highlight + if(!lp.issmoothghs) { + params.bands[4] = -15; + params.bands[5] = -50; + } else { + params.bands[4] = -15 -(1.f-lp.ghshp) * 60.f;//in function of HP GHS highligt protection + params.bands[5] = -30 -(1.f-lp.ghshp) * 50.f;; + } + if(lp.whiteevjz < 6 && !lp.issmoothghs) { params.bands[4] = -10; } } - ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); } @@ -2771,7 +2962,7 @@ void ImProcFunctions::tone_eqcam2(ImProcFunctions *ipf, Imagefloat *rgb, int whi if(bla > threshblawhi2) { params.bands[2] = sign(blacks) * (bla - threshblawhi2); } - + params.bands[4] = whits; int whi = abs(whits); if(whi > threshblawhi) { @@ -2780,7 +2971,17 @@ void ImProcFunctions::tone_eqcam2(ImProcFunctions *ipf, Imagefloat *rgb, int whi if(whi > threshblawhi3) { params.bands[5] = sign(whits) * (whi - threshblawhi3); } - + ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); +} + + +void tone_eqblack(ImProcFunctions *ipf, Imagefloat *rgb, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread) +{ + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = blacks; ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); } @@ -2994,13 +3195,12 @@ void ImProcFunctions::tone_eqdehaz(ImProcFunctions *ipf, Imagefloat *rgb, int wh if(bla > threshblawhi2) { params.bands[2] = blred * sign(blacks) * (bla - threshblawhi2); } - + params.bands[4] = whits; int whi = abs(whits); if(whi > threshblawhi) { params.bands[3] = sign(whits) * (whi - threshblawhi); } - ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); } @@ -5284,6 +5484,7 @@ void ImProcFunctions::addGaNoise(LabImage *lab, LabImage *dst, const float mean, } } + void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, LabImage* originalmask, int levred, float hueref, float lumaref, float chromaref, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy, int sk) { //warning, but I hope used it next @@ -5418,7 +5619,6 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab transformed->L[y][x] = CLIP(original->L[y][x] + difL); transformed->a[y][x] = clipC((original->a[y][x] + difa) * factnoise); transformed->b[y][x] = clipC((original->b[y][x] + difb) * factnoise) ; - if (blshow && lp.fullim != 3) { transformed->L[y][x] = CLIP(12000.f + amplabL * difL);// * 10.f empirical to can visualize modifications transformed->a[y][x] = clipC(amplabL * difa);// * 10.f empirical to can visualize modifications @@ -5955,13 +6155,66 @@ struct grad_params { int h; }; -void calclocalGradientParams(const struct local_params& lp, struct grad_params& gp, float ystart, float xstart, int bfw, int bfh, int indic) +void calclocalGradientParams(int call, const struct local_params& lp, struct grad_params& gp, float ystart, float xstart, float yend, float xend, int bfw, int bfh, int oW, int oH, int tX, int tY, int tW, int tH, int indic, int sk, int fw, int fh, int cx, int cy, float &ksk, float &kskx, float &kbh, float &kbw) { - int w = bfw; - int h = bfh; + int w = bfw;//??? oW, tW.. + int h = bfh;//??? oH, tH.. float stops = 0.f; float angs = 0.f; - double varfeath = 0.25; //0.01f * lp.feath; + double varfeath = 0.25; + // big problem with preview as soon as the preview no longer covers the entire image + // I have tried a lot of things adding parameters that may have an impact oW, oH, tX, tY, tW, tH, fW, fH, sk, call, etc. + // but nothing works really... + // Perhaps with PreviewProps, but I don't know how to do ? + // It seems that you need to change the position of the center of the GF which varies depending on the preview, but how? + // parameters passe to calcGradientFactor may also be involved + + //others parameters to chnage behavior of GF complete those in beginning of lab_local + //all these parameters allows to chnage behavior of GF with all factors preview oW, oH, tX, tY, tW, tH, fW, fH, sk, call, cx, cy, bfw, bfh + + int kx = 0; + int ky = 0; + //kx ky - try to take account of position of window in preview + //acts on center of GF we can easiy chnage - kx in a function of oW, bfw, etc. + // it is only here in calclocalGradientParams + + // double kstop = 0.5; // to simulate stops in GF main - 0.5 arbitrary only here in calclocalGradientParams + double kstop = 1.0; // keep all agressive settings - to simulate stops in GF main - 0.5 arbitrary only here in calclocalGradientParams + + float ktyoh = 1.f; //acts on cy - Try to take into account position of window in preview with various factors...ex: -2.f * ((float)(oH - tY) / (float)oH); + float ktxoh = 1.f; //acts on cx - Try to take into account position of window in preview with various factors...ex: -2.f * ((float)(oH - tY) / (float)oH); + if(sk == 1) {//try empirical to see, not good + ktyoh = 0.86f; + ktxoh = 0.86f; + } else if (sk == 2) { + ktyoh = 0.95f; + ktxoh = 0.95f; + } + + ksk *= ktyoh; + kskx *= ktxoh; + + float ktbh = 1.f; //acts on bfw in calcgradientfactor - repartition of gradient + float ktbw = 1.f; //acts on bfh in calcgradientfactor - repartition of gradient + + kbh *= ktbh; + kbw *= ktbw; + + // cannot be used for RT-Spot "normal" or "exclude" : only in fullimage or Global + double gradient_center_x = LIM01((lp.xcent * (oW + kx)) / bfw);//for dcrop and improccordinator + double gradient_center_y = LIM01((lp.ycent * (oH + ky)) / bfh); + //This solution works better than the old one, you can move the window, but is still - a little less - with a malfunction with Zoom + +/* old settings 5.11 - different from lp.xcent and take into account xstart and ystart + // double gradient_center_x = LIM01((lp.xc - xstart) / bfw); + // double gradient_center_y = LIM01((lp.yc - ystart) / bfh); +*/ + + if(call == 2 || lp.fullim == 0 ) {//simpleprocess or compatibility 5.11 for Spot normal (I don't keep "exclude") + gradient_center_x = LIM01((lp.xcent * (bfw)) / bfw);//I keep this formula because perhaps not bfw, for the first + gradient_center_y = LIM01((lp.ycent * (bfh)) / bfh); + } + if (indic == 0) { stops = -lp.strmaexp; @@ -5987,12 +6240,11 @@ void calclocalGradientParams(const struct local_params& lp, struct grad_params& } else { redu = 0.15f; } - stops = redu * lp.strcolab; angs = lp.angcol; varfeath = 0.01f * lp.feathcol; } else if (indic == 5) { - stops = lp.strcolab; + stops = lp.strcolab ; angs = lp.angcol; varfeath = 0.01f * lp.feathcol; } else if (indic == 6) { @@ -6033,18 +6285,21 @@ void calclocalGradientParams(const struct local_params& lp, struct grad_params& stops = lp.strgradcie; angs = lp.anggradcie; varfeath = 0.01f * lp.feathercie; + } + int sk2 = 1;//not used very bad behavior + double gradient_stops = stops / sk2;//I have test with Skip but does not work well, even bad + + gradient_stops *= kstop; + +//hide these informations to clean console, if need +//all parameters send by Dcrop are here... But it is not evident why it does not work correctly + if (settings->verbose) { + printf("call=%i xcent=%.2f ycent=%.2f Gcx=%.2f Gcy=%.2f indic=%i cx=%i cy=%i strength(stops)=%f k_sk=%f k_skx=%f kbw=%f kbh=%f\n", call, (double) lp.xcent, (double) lp.ycent, gradient_center_x, gradient_center_y, indic, cx, cy, gradient_stops, (double) ksk, (double) kskx, (double) kbw, (double) kbh); + printf("fw=%i fh=%i bfw=%i bfh=%i oW=%i oH=%i tW=%i tH=%i tX=%i tY=%i xstart=%.1f ystrat=%.1f xend=%.1f yend=%.1f xc=%.1f yc=%.1f yT=%.1f xL=%.1f sk=%i\n", fw, fh, bfw, bfh, oW, oH, tW, tH, tX, tY, (double) xstart, (double) ystart, (double) xend, (double) yend, (double) lp.xc, (double) lp.yc, (double) lp.lyT, (double)lp.lxL, sk); } - - double gradient_stops = stops; - double gradient_center_x = LIM01((lp.xc - xstart) / bfw); - double gradient_center_y = LIM01((lp.yc - ystart) / bfh); double gradient_angle = static_cast(angs) / 180.0 * rtengine::RT_PI; - // double varfeath = 0.01f * lp.feath; - //printf("xstart=%f ysta=%f lpxc=%f lpyc=%f stop=%f bb=%f cc=%f ang=%f ff=%d gg=%d\n", xstart, ystart, lp.xc, lp.yc, gradient_stops, gradient_center_x, gradient_center_y, gradient_angle, w, h); - - // make 0.0 <= gradient_angle < 2 * rtengine::RT_PI gradient_angle = fmod(gradient_angle, 2 * rtengine::RT_PI); if (gradient_angle < 0.0) { @@ -6109,6 +6364,7 @@ void calclocalGradientParams(const struct local_params& lp, struct grad_params& gp.ys_inv = 0; gp.ys = 0; } + } void ImProcFunctions::blendstruc(int bfw, int bfh, LabImage* bufcolorig, float radius, float stru, array2D & blend2, int sk, bool multiThread) @@ -6787,7 +7043,7 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw #endif } -void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int xstart, int ystart, int sk, int cx, int cy, LabImage* bufcolorig, LabImage* bufmaskblurcol, LabImage* originalmaskcol, LabImage* original, LabImage* reserved, int inv, struct local_params & lp, +void ImProcFunctions::maskcalccol(int call, bool invmask, bool pde, int bfw, int bfh, int oW, int oH, int tX, int tY, int tW, int tH, int xstart, int ystart, int xend, int yend, int sk, int cx, int cy, LabImage* bufcolorig, LabImage* bufmaskblurcol, LabImage* originalmaskcol, LabImage* original, LabImage* reserved, int inv, struct local_params & lp, float strumask, bool astool, const LocCCmaskCurve & locccmasCurve, bool lcmasutili, const LocLLmaskCurve & locllmasCurve, bool llmasutili, @@ -6797,7 +7053,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int const LocwavCurve & loclmasCurvecolwav, bool lmasutilicolwav, int level_bl, int level_hl, int level_br, int level_hr, int shortcu, bool delt, const float hueref, const float chromaref, const float lumaref, float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope, - bool fftt, float blu_ma, float cont_ma, int indic, float &fab + bool fftt, float blu_ma, float cont_ma, int indic, float &fab, int fw, int fh, float ksk, float kskx, float kbh, float kbw ) @@ -7489,14 +7745,14 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int struct grad_params gp; if ((indic == 0 && lp.strmaexp != 0.f) || (indic == 12 && lp.str_mas != 0.f)) { - calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, indic); + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, indic, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - bufmaskblurcol->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); + bufmaskblurcol->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, cx*kskx + kbw*jr, cy*ksk + kbh*ir); } } } @@ -7657,7 +7913,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co const float difL = (loctemp[y][x] - original->L[y][x]) * (1.f - localFactor); transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE); - if (sharshow) { + if (sharshow && lp.fullim != 3) { transformed->a[y][x] = 0.f; transformed->b[y][x] = ampli * 5.f * difL * reducdE; } else if (previewshar || lp.prevdE) { @@ -9279,7 +9535,7 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, LabImage * originalmask, c const float maxdifab = rtengine::max(std::fabs(difa), std::fabs(difb)); - if ((blshow && lp.colorde < 0) && lp.fullim != 3 ) { //show modifications with use "b" + if ((blshow && lp.colorde < 0) && lp.fullim != 3) { //show modifications with use "b" // (origshow && lp.colorde < 0) { //original Retinex transformed->a[y][x] = 0.f; transformed->b[y][x] = ampli * 8.f * difL * reducdE; @@ -9314,8 +9570,10 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, LabImage * originalmask, c } } -void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, int call, int senstype, const LabImage * bufexporig, const LabImage * bufexpfin, LabImage * originalmask, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) +void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, int call, int senstype, const LabImage * bufexporig, const LabImage * bufexpfin, LabImage * originalmask, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage *tmp1, LocalLabGradientMode grad, int cx, int cy, int sk) { + + //initialize coordinates int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); @@ -9324,7 +9582,31 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in int bfw = xend - xstart; int bfh = yend - ystart; +// test to use in plain image + bool execgradsh = false; + if(lp.fullim == 3 || lp.fullim == 2 || lp.fullim == 0) { + execgradsh = true; + } + const std::unique_ptr buftmp1(new LabImage(bfw, bfh)); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if(multiThread) +#endif + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + buftmp1->L[ir][jr] = 1.f; + } + if(grad == LocalLabGradientMode::PLAIN_IMAGE && call != 2 && lp.strSH != 0.f && execgradsh) {//test mode GF plain image +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if(multiThread) +#endif + for (int y = ystart; y < yend; y++) { + for (int x = xstart; x < xend; x++) { + buftmp1->L[y - ystart][x - xstart] = tmp1->L[y][x]; + } + } + } + //initialize scope float varsens = lp.sensex;//exposure @@ -9673,13 +9955,23 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in if(varsens == 100.f) { reducdE = 1.f; } + float factgrad = 1.f; + // test to use in plain image + if(grad == LocalLabGradientMode::PLAIN_IMAGE && call == 1 && lp.strSH != 0.f && execgradsh) { + factgrad = buftmp1->L[y][x]; + + } - float cli = (bufexpfin->L[y][x] - bufexporig->L[y][x]); + float cli = (factgrad * bufexpfin->L[y][x] - bufexporig->L[y][x] ); float cla = (bufexpfin->a[y][x] - bufexporig->a[y][x]); float clb = (bufexpfin->b[y][x] - bufexporig->b[y][x]); - if (delt) { - cli = bufexpfin->L[y][x] - original->L[y + ystart][x + xstart]; + if (delt) {//mask deltaE + if(grad == LocalLabGradientMode::PLAIN_IMAGE && call == 1 && lp.strSH != 0.f && execgradsh) { //test mode plain image + cli = (buftmp1->L[y + ystart][x + xstart] * bufexpfin->L[y][x] - original->L[y + ystart][x + xstart]); + } else { + cli = (bufexpfin->L[y][x] - original->L[y + ystart][x + xstart]); + } cla = bufexpfin->a[y][x] - original->a[y + ystart][x + xstart]; clb = bufexpfin->b[y][x] - original->b[y + ystart][x + xstart]; } @@ -9689,17 +9981,16 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in clb = 0.f; } - // const float previewint = settings->previewselection; const float realstrdE = reducdE * cli; const float realstradE = reducdE * cla; const float realstrbdE = reducdE * clb; float factorx = localFactor; - + // printf("OK 4\n"); if (zone > 0) { //simplified transformed with deltaE and transition - transformed->L[y + ystart][x + xstart] = clipLoc(original->L[y + ystart][x + xstart] + factorx * realstrdE);//clipLoc now do nothing...just keep in ace off + transformed->L[y + ystart][x + xstart] = clipLoc(original->L[y + ystart][x + xstart] + factorx * realstrdE );//clipLoc now do nothing...just keep in ace off float diflc = factorx * realstrdE; transformed->a[y + ystart][x + xstart] = clipC(original->a[y + ystart][x + xstart] + factorx * realstradE); const float difa = factorx * realstradE; @@ -10774,13 +11065,13 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel } -void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float ** tmpa, float ** tmpb, float contrast, float radblur, float radlevblur, int bfw, int bfh, int level_bl, int level_hl, int level_br, int level_hr, int sk, int numThreads, +void ImProcFunctions::wavcontrast4(int call, struct local_params& lp, float ** tmp, float ** tmpa, float ** tmpb, float contrast, float radblur, float radlevblur, int bfw, int bfh, int oW, int oH, int tX, int tY, int tW, int tH, int level_bl, int level_hl, int level_br, int level_hr, int sk, int numThreads, const LocwavCurve & locwavCurve, bool locwavutili, bool wavcurve, const LocwavCurve& loclevwavCurve, bool loclevwavutili, bool wavcurvelev, const LocwavCurve & locconwavCurve, bool locconwavutili, bool wavcurvecon, const LocwavCurve & loccompwavCurve, bool loccompwavutili, bool wavcurvecomp, const LocwavCurve & loccomprewavCurve, bool loccomprewavutili, bool wavcurvecompre, const LocwavCurve & locedgwavCurve, bool locedgwavutili, - float sigm, float offs, int & maxlvl, float sigmadc, float deltad, float chromalev, float chromablu, bool blurlc, bool blurena, bool levelena, bool comprena, bool compreena, float compress, float thres) + float sigm, float offs, int & maxlvl, float sigmadc, float deltad, float chromalev, float chromablu, bool blurlc, bool blurena, bool levelena, bool comprena, bool compreena, float compress, float thres, int fw, int fh, int cx, int cy, float ksk, float kskx, float kbh, float kbw) { //BENCHFUN std::unique_ptr wdspot(new wavelet_decomposition(tmp[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); @@ -10800,7 +11091,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float if (lp.strwav != 0.f && lp.wavgradl) { array2D factorwav(W_Lm, H_Lm); - calclocalGradientParams(lp, gpwav, 0, 0, W_Lm, H_Lm, 10); + calclocalGradientParams(call, lp, gpwav, 0, 0, W_Lm, H_Lm, W_Lm, H_Lm, oW, oH, tX, tY, tW, tH, 10, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); const float mult = lp.strwav < 0.f ? -1.f : 1.f; #ifdef _OPENMP #pragma omp parallel for if (multiThread) @@ -10808,7 +11099,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float for (int y = 0; y < H_Lm; y++) { for (int x = 0; x < W_Lm; x++) { - factorwav[y][x] = mult * (1.f - ImProcFunctions::calcGradientFactor(gpwav, x, y)); + factorwav[y][x] = mult * (1.f - ImProcFunctions::calcGradientFactor(gpwav, cx*kskx + kbw*x, cy*ksk + kbh*y)); } } @@ -11868,7 +12159,10 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct tmp1.b[ir][jr] = original->b[ir][jr]; } if(lp.nlstr > 0) { - NLMeans(tmp1.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, GW, GH, float (sk), multiThread); + int iter = lp.nliter;//iterations Nlmeans + for(int it = 0; it < iter; it++) { + NLMeans(tmp1.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, GW, GH, float (sk), multiThread); + } } float gamma = lp.noisegam; @@ -13117,7 +13411,10 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct } if (lp.nlstr > 0) { - NLMeans(bufwv.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, bfw, bfh, 1.f, multiThread); + int iter = lp.nliter;//iterations Nlmeans + for(int it = 0; it < iter; it++) { + NLMeans(bufwv.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad , lp.nlgam, bfw, bfh, 1.f, multiThread); + } } @@ -14210,8 +14507,278 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int } +// From Siril. +ght_compute_params ImProcFunctions::GHT_setup(float in_B, float D, float LP, float SP, float HP, GHTStrType strtype) +{ + rtengine::ght_compute_params c; + float B = in_B; + if(strtype == GHTStrType::NORMAL) {//Normal Stretch + if (B == -1.0f) { + c.qlp = -1.0f * log(1.f + D * (SP - LP)); + c.q0 = c.qlp - D * LP / (1.0f + D * (SP - LP)); + c.qwp = log(1.f + D * (HP - SP)); + c.q1 = c.qwp + D * (1.0f - HP) / (1.0f + D * (HP - SP)); + c.q = 1.0f / (c.q1 - c.q0); + c.b1 = (1.0f + D * (SP - LP)) / (D * c.q); + c.a2 = (-c.q0) * c.q; + c.b2 = -c.q; + c.c2 = 1.0f + D * SP; + c.d2 = -D; + c.a3 = (-c.q0) * c.q; + c.b3 = c.q; + c.c3 = 1.0f - D * SP; + c.d3 = D; + c.a4 = (c.qwp - c.q0 - D * HP / (1.0f + D * (HP - SP))) * c.q; + c.b4 = c.q * D / (1.0f + D * (HP - SP)); + } else if (B < 0.0f) { + B = -B; + c.qlp = (1.0f - pow((1.0f + D * B * (SP - LP)), (B - 1.0f) / B)) / (B - 1.0f); + c.q0 = c.qlp - D * LP * (pow((1.0f + D * B * (SP - LP)), -1.0f / B)); + c.qwp = (pow((1.0f + D * B * (HP - SP)), (B - 1.0f) / B) - 1.0f) / (B - 1.0f); + c.q1 = c.qwp + D * (1.0f - HP) * (pow((1.0f + D * B * (HP - SP)), -1.0f / B)); + c.q = 1.0f / (c.q1 - c.q0); + c.b1 = D * pow(1.0f + D * B * (SP - LP), -1.0f / B) *c.q; + c.a2 = (1.0f / (B - 1.0f) - c.q0) * c.q; + c.b2 = -c.q / (B - 1.0f); + c.c2 = 1.0f + D * B * SP; + c.d2 = -D * B; + c.e2 = (B - 1.0f) / B; + c.a3 = (-1.0f / (B-1.0f) - c.q0) *c.q; + c.b3 = c.q/(B-1.0f); + c.c3 = 1.0f - D * B * SP; + c.d3 = D * B; + c.e3 = (B - 1.0f) / B; + c.a4 = (c.qwp - c.q0 - D * HP * pow((1.0f + D * B * (HP - SP)), -1.0f / B)) * c.q; + c.b4 = D * pow((1.0f + D * B * (HP - SP)), -1.0f / B) * c.q; + } else if (B == 0.0f) { + c.qlp = exp(-D * (SP - LP)); + c.q0 = c.qlp - D * LP * exp(-D*(SP - LP)); + c.qwp = 2.0f - exp(-D * (HP -SP)); + c.q1 = c.qwp + D * (1.0f - HP) * exp (-D * (HP - SP)); + c.q = 1.0f / (c.q1 - c.q0); + c.a1 = 0.0f; + c.b1 = D * exp (-D * (SP - LP)) * c.q; + c.a2 = -c.q0 * c.q; + c.b2 = c.q; + c.c2 = -D * SP; + c.d2 = D; + c.a3 = (2.0f - c.q0) * c.q; + c.b3 = -c.q; + c.c3 = D * SP; + c.d3 = -D; + c.a4 = (c.qwp - c.q0 - D * HP * exp(-D * (HP - SP))) * c.q; + c.b4 = D * exp(-D * (HP - SP)) * c.q; + } else if (B > 0.0f) { + c.qlp = pow((1.0f + D * B * (SP - LP)), -1.0f / B); + c.q0 = c.qlp - D * LP * pow((1.f + D * B * (SP - LP)), -(1.0f + B) / B); + c.qwp = 2.0f - pow(1.0f + D * B * (HP - SP), -1.0f / B); + c.q1 = c.qwp + D * (1.0f - HP) * pow((1.0f + D * B * (HP - SP)), -(1.0f + B) / B); + c.q = 1.0f / (c.q1 - c.q0); + c.b1 = D * pow((1.0f + D * B * (SP - LP)), -(1.0f+B)/B) * c.q; + c.a2 = -c.q0 * c.q; + c.b2 = c.q; + c.c2 = 1.0f + D * B * SP; + c.d2 = -D * B; + c.e2 = -1.0f / B; + c.a3 = (2.0f - c.q0) * c.q; + c.b3 = -c.q; + c.c3 = 1.0f - D * B * SP; + c.d3 = D * B; + c.e3 = -1.0f / B; + c.a4 = (c.qwp - c.q0 - D * HP * pow((1.0f + D * B * (HP - SP)), -(B + 1.0f) / B)) * c.q; + c.b4 = (D * pow((1.0f + D * B * (HP - SP)), -(B + 1.0f) / B)) * c.q; + } + } else if (strtype == GHTStrType::INVERSE) {//Inverse stretch + if (B == -1.0f) { + c.qlp = -1.0f * log(1.f + D * (SP - LP)); + c.q0 = c.qlp - D * LP / (1.0f + D * (SP - LP)); + c.qwp = log(1.f + D * (HP - SP)); + c.q1 = c.qwp + D * (1.0f - HP) / (1.0f + D * (HP - SP)); + c.q = 1.0f / (c.q1 - c.q0); + c.LPT = (c.qlp-c.q0)*c.q; + c.SPT = c.q0*c.q; + c.HPT = (c.qwp-c.q0)*c.q; + c.b1 = (1.0f + D * (SP - LP)) / (D * c.q); + c.a2 = (1.0f + D * SP) / D; + c.b2 = -1.0f / D; + c.c2 = - c.q0; + c.d2 = - 1.0f/c.q; + c.a3 = - (1.0f - D * SP) / D; + c.b3 = 1.0f / D; + c.c3 = c.q0; + c.d3 = 1.0f / c.q; + c.a4 = HP + (c.q0 - c.qwp) * (1.f + D * (HP-SP)) / D; + c.b4 = (1.0f + D * (HP - SP) )/(c.q * D) ; + } else if (B < 0.0f) { + B = -B; + c.qlp = (1.0f - pow((1.0f + D * B * (SP - LP)), (B - 1.0f) / B)) / (B - 1.0f); + c.q0 = c.qlp - D * LP * (pow((1.0f + D * B * (SP - LP)), -1.0f / B)); + c.qwp = (pow((1.0f + D * B * (HP - SP)), (B - 1.0f) / B) - 1.0f) / (B - 1.0f); + c.q1 = c.qwp + D * (1.0f - HP) * (pow((1.0f + D * B * (HP - SP)), -1.0f / B)); + c.q = 1.0f / (c.q1 - c.q0); + c.LPT = (c.qlp - c.q0)*c.q; + c.SPT = -c.q0 * c.q; + c.HPT = (c.qwp - c.q0) * c.q; + c.b1 = pow(1.0f + D * B * (SP - LP), 1.0f / B) / (c.q * D); + c.a2 = (1.0f + D * B * SP) / (D * B); + c.b2 = -1.0f / (D * B); + c.c2 = -c.q0 * (B-1.0f) + 1.0f; + c.d2 = (1.0f - B) / c.q; + c.e2 = B / (B - 1.0f); + c.a3 = (D * B * SP - 1.0f) / (D * B); + c.b3 = 1.0f / (D * B); + c.c3 = 1.0f + c.q0 * (B - 1); + c.d3 = (B - 1.0f) / c.q; + c.e3 = B / (B - 1.0f); + c.a4 = (c.q0 - c.qwp)/(D * pow((1.0f + D * B * (HP - SP)), -1.0f / B)) + HP; + c.b4 = 1.0f / (D * pow((1.0f + D * B * (HP - SP)), -1.0f / B) * c.q) ; + } else if (B == 0.0f) { + c.qlp = exp(-D * (SP - LP)); + c.q0 = c.qlp - D * LP * exp(-D*(SP - LP)); + c.qwp = 2.0f - exp(-D * (HP -SP)); + c.q1 = c.qwp + D * (1.0f - HP) * exp (-D * (HP - SP)); + c.q = 1.0f / (c.q1 - c.q0); + c.LPT = (c.qlp - c.q0) * c.q; + c.SPT = (1.0f - c.q0) * c.q; + c.HPT = (c.qwp - c.q0) * c.q; + c.a1 = 0.0f; + c.b1 = 1.0f / (D * exp(-D * (SP - LP)) * c.q); + c.a2 = SP; + c.b2 = 1.0f / D; + c.c2 = c.q0; + c.d2 = 1.0f / c.q; + c.a3 = SP; + c.b3 = -1.0f / D; + c.c3 = (2.0f - c.q0); + c.d3 = -1.0f / c.q; + c.a4 = (c.q0 - c.qwp)/(D * exp(-D * (HP - SP))) + HP; + c.b4 = 1.0f / (D * exp(-D * (HP - SP)) * c.q); + } else if (B > 0.0f) { + c.qlp = pow(( 1.0f + D * B * (SP - LP)), -1.0f/B); + c.q0 = c.qlp - D * LP * pow((1.0f + D * B * (SP - LP)), -(1.0f + B) / B); + c.qwp = 2.0f - pow(1.0f + D * B * (HP - SP), -1.0f / B); + c.q1 = c.qwp + D * (1.0f - HP) * pow((1.0f + D * B * (HP - SP)), -(1.0f + B) / B); + c.q = 1.0f / (c.q1 - c.q0); + c.LPT = (c.qlp - c.q0) * c.q; + c.SPT = (1.0f - c.q0) * c.q; + c.HPT = (c.qwp - c.q0) * c.q; + c.b1 = 1.f / (D * pow((1.0f + D * B * (SP - LP)), -(1.0f + B) / B) * c.q); + c.a2 = 1.0f / (D * B) + SP; + c.b2 = -1.0f / (D * B); + c.c2 = c.q0; + c.d2 = 1.0f / c.q; + c.e2 = -B; + c.a3 = -1.0f / (D * B) + SP; + c.b3 = 1.0f / (D * B); + c.c3 = (2.0f - c.q0); + c.d3 = -1.0f / c.q; + c.e3 = -B; + c.a4 = (c.q0 - c.qwp)/(D * pow((1.0f + D * B * (HP - SP)), -(B + 1.0f) / B)) + HP; + c.b4 = 1.0f/((D * pow((1.0f + D * B * (HP - SP)), -(B + 1.0f) / B)) * c.q); + } + } + return c; +} + +// From Siril. +float ImProcFunctions::GHT(float x, float B, float D, float LP, float SP, float HP, rtengine::ght_compute_params c, GHTStrType strtype) +{ + float out; + float in = clamp(x, 0.f, 1.f);//never negatives values or > 1. hence the need to control the Black point and White point + if (D == 0.0f) {//no stretch + out = in; + } else { + if(strtype == GHTStrType::NORMAL) {//Normal stretch + if (B == -1.0f) { + if (in < LP) { + out = c.b1 * in; + } else if (in < SP) { + out = c.a2 + c.b2 * log(c.c2 + c.d2 * in); + } else if (in < HP) { + out = c.a3 + c.b3 * log(c.c3 + c.d3 * in); + } else { + out = c.a4 + c.b4 * in; + } + } else if (B < 0.0f) { + if (in < LP) { + out = c.b1 * in; + } else if (in < SP) { + out = c.a2 + c.b2 * pow((c.c2 + c.d2 * in), c.e2); + } else if (in < HP) { + out = c.a3 + c.b3 * pow((c.c3 + c.d3 * in), c.e3); + } else { + out = c.a4 + c.b4 * in; + } + } else if (B == 0.0f) { + if (in < LP) { + out = c.a1 + c.b1 * in; + } else if (in < SP) { + out = c.a2 + c.b2 * exp(c.c2 + c.d2 * in); + } else if (in < HP) { + out = c.a3 + c.b3 * exp(c.c3 + c.d3 * in); + } else { + out = c.a4 + c.b4 * in; + } + } else /*if (B > 0)*/ { + if (in < LP) { + out = c.b1 * in; + } else if (in < SP) { + out = c.a2 + c.b2 * pow((c.c2 + c.d2 * in), c.e2); + } else if (in < HP) { + out = c.a3 + c.b3 * pow((c.c3 + c.d3 * in), c.e3); + } else { + out = c.a4 + c.b4 * in; + } + } + } if(strtype == GHTStrType::INVERSE) {//Inverse Stretch + if (B == -1.0f) { + if (in < c.LPT) { + out = c.b1 * in; + } else if (in < c.SPT) { + out = c.a2 + c.b2 * exp(c.c2 + c.d2 * in); + } else if (in < c.HPT) { + out = c.a3 + c.b3 * exp(c.c3 + c.d3 * in); + } else { + out = c.a4 + c.b4 * in; + } + } else if (B < 0.0f) { + if (in < c.LPT) { + out = c.b1 * in; + } else if (in < c.SPT) { + out = c.a2 + c.b2 * pow((c.c2 + c.d2 * in), c.e2); + } else if (in < c.HPT) { + out = c.a3 + c.b3 * pow((c.c3 + c.d3 * in), c.e3); + } else { + out = c.a4 + c.b4 * in; + } + } else if (B == 0.0f) { + if (in < c.LPT) { + out = c.a1 + c.b1 * in; + } else if (in < c.SPT) { + out = c.a2 + c.b2 * logf(c.c2 + c.d2 * in); + } else if (in < c.HPT) { + out = c.a3 + c.b3 * logf(c.c3 + c.d3 * in); + } else { + out = c.a4 + c.b4 * in; + } + } else /* if (B > 0) */{ + if (in < c.LPT) { + out = c.b1 * in; + } else if (in < c.SPT) { + out = c.a2 + c.b2 * pow((c.c2 + c.d2 * in), c.e2); + } else if (in < c.HPT) { + out = c.a3 + c.b3 * pow((c.c3 + c.d3 * in), c.e3); + } else { + out = c.a4 + c.b4 * in; + } + } + } + } + return out; +} + void ImProcFunctions::Lab_Local( - int call, int sp, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, LabImage * savenormtm, LabImage * savenormreti, LabImage * lastorig, int fw, int fh, int cx, int cy, int oW, int oH, int sk, + int call, int sp, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, LabImage * savenormtm, LabImage * savenormreti, LabImage * lastorig, int fw, int fh, int cx, int cy, int oW, int oH, int tX, int tY, int tW, int tH, int sk, const LocretigainCurve& locRETgainCcurve, const LocretitransCurve& locRETtransCcurve, const LUTf& lllocalcurve, bool locallutili, const LUTf& cllocalcurve, bool localclutili, @@ -14221,6 +14788,7 @@ void ImProcFunctions::Lab_Local( const LUTf& lmasklocalcurve, bool localmaskutili, const LUTf& lmaskexplocalcurve, bool localmaskexputili, const LUTf& lmaskSHlocalcurve, bool localmaskSHutili, +// const LUTf& ghslocalcurve, bool localghsutili, const LUTf& lmaskviblocalcurve, bool localmaskvibutili, const LUTf& lmasktmlocalcurve, bool localmasktmutili, LUTf& lmaskretilocalcurve, bool localmaskretiutili, @@ -14269,21 +14837,34 @@ void ImProcFunctions::Lab_Local( bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float& minCD, float& maxCD, float& mini, float& maxi, float& Tmean, float& Tsigma, float& Tmin, float& Tmax, float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab,float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &prim, int &ill, float &contsig, float &lightsig, - float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46, float &slopeg, bool &linkrgb + float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46, float &slopeg, bool &linkrgb, + int *ghsbpwp, float *ghsbpwpvalue) + + - ) { //general call of others functions : important return hueref, chromaref, lumaref if (!params->locallab.enabled) { return; } - - + MyTime t1, t2; + + // printf("OHWTHW ow=%i oh=%i tw=%i th=%i sk=%i\n", oW, oH, tW, tH, sk); constexpr int del = 3; // to avoid crash with [loy - begy] and [lox - begx] and bfh bfw // with gtk2 [loy - begy-1] [lox - begx -1 ] and del = 1 struct local_params lp; calcLocalParams(sp, oW, oH, params->locallab, lp, prevDeltaE, llColorMask, llColorMaskinv, llExpMask, llExpMaskinv, llSHMask, llSHMaskinv, llvibMask, lllcMask, llsharMask, llcbMask, llretiMask, llsoftMask, lltmMask, llblMask, lllogMask, ll_Mask, llcieMask, locwavCurveden, locwavdenutili); - + + //parameters to change behavior GF + float ksk = 1.f;//acts on cy + float kskx = 1.f;//acts on cx + float kbh = 1.f;//acts on bkh in calcGradientFactor + float kbw = 1.f;//acts on bfw in calcGradientFactor + //2 others parameters in calclocalGradientParams for GF center and GF strength + // kstop - strength GF + // kx, ky acts on center GF. + + //avoidcolshi(lp, sp, transformed, reserved, cy, cx, sk); //BENCHFUN @@ -14494,12 +15075,12 @@ void ImProcFunctions::Lab_Local( int lumask = params->locallab.spots.at(sp).lumask; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufexporig.get(), bufmaskoriglog.get(), originalmasklog.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufexporig.get(), bufmaskoriglog.get(), originalmasklog.get(), original, reserved, inv, lp, 0.f, false, locccmaslogCurve, lcmaslogutili, locllmaslogCurve, llmaslogutili, lochhmaslogCurve, lhmaslogutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskloglocalcurve, localmasklogutili, dummy, false, 1, 1, 5, 5, shortcu, delt, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmasklogmet == 3) { @@ -14573,14 +15154,14 @@ void ImProcFunctions::Lab_Local( //first solution "easy" but we can do other with log_encode...to see the results if (lp.strlog != 0.f) { struct grad_params gplog; - calclocalGradientParams(lp, gplog, ystart, xstart, bfw, bfh, 11); + calclocalGradientParams(call, lp, gplog, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 11, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif - for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gplog, jr, ir); + bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gplog, cx*kskx + kbw*jr, cy*ksk + kbh*ir); } } } @@ -14603,9 +15184,9 @@ void ImProcFunctions::Lab_Local( } if (lp.recothrl >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), originalmasklog.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), originalmasklog.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } } @@ -14712,11 +15293,11 @@ void ImProcFunctions::Lab_Local( LocHHmaskCurve lochhhmasCurve; const float strumask = 0.02 * params->locallab.spots.at(sp).strumaskbl; const bool astool = params->locallab.spots.at(sp).toolbl; - maskcalccol(false, pde, TW, TH, 0, 0, sk, cx, cy, bufblorig.get(), bufmaskblurbl.get(), originalmaskbl.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, TW, TH, oW, oH, tX, tY, tW, tH, 0, 0, 0, 0, sk, cx, cy, bufblorig.get(), bufmaskblurbl.get(), originalmaskbl.get(), original, reserved, inv, lp, strumask, astool, locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskbllocalcurve, localmaskblutili, loclmasCurveblwav, lmasutiliblwav, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, 0, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, 0, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskblmet == 3) { @@ -15530,12 +16111,12 @@ void ImProcFunctions::Lab_Local( float anchorcd = 50.f; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufgbm.get(), bufmaskorigtm.get(), originalmasktm.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufgbm.get(), bufmaskorigtm.get(), originalmasktm.get(), original, reserved, inv, lp, 0.f, false, locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmasktmlocalcurve, localmasktmutili, dummy, false, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmasktmmet == 3) { @@ -15602,12 +16183,12 @@ void ImProcFunctions::Lab_Local( float anchorcd = 50.f; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, tmp1.get(), bufmaskorigtm.get(), originalmasktm.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, tmp1.get(), bufmaskorigtm.get(), originalmasktm.get(), original, reserved, inv, lp, 0.f, false, locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmasktmlocalcurve, localmasktmutili, dummy, false, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmasktmmet == 3) {//display mask @@ -15684,9 +16265,9 @@ void ImProcFunctions::Lab_Local( // transit_shapedetect_retinex(call, 4, bufgb.get(),bufmaskorigtm.get(), originalmasktm.get(), buflight, bufchro, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); if (lp.recothrt >= 1.f) { - transit_shapedetect2(sp, meantm, stdtm, call, 8, bufgb.get(), tmp1.get(), originalmasktm.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, meantm, stdtm, call, 8, bufgb.get(), tmp1.get(), originalmasktm.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } else { - transit_shapedetect2(sp, meantm, stdtm, call, 8, bufgb.get(), tmp1.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, meantm, stdtm, call, 8, bufgb.get(), tmp1.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } // transit_shapedetect(8, tmp1.get(), originalmasktm.get(), bufchro, false, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); @@ -15743,7 +16324,7 @@ void ImProcFunctions::Lab_Local( dehazeloc(tmpImage.get(), dehazeParams, sk, sp); rgb2lab(*tmpImage.get(), *bufexpfin, params->icm.workingProfile); - transit_shapedetect2(sp, 0.f, 0.f, call, 30, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 30, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); if (lp.recur) { original->CopyFrom(transformed, multiThread); @@ -16555,12 +17136,12 @@ void ImProcFunctions::Lab_Local( int shortcu = 0; //lp.mergemet; //params->locallab.spots.at(sp).shortc; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, loctemp.get(), bufmaskorigcb.get(), originalmaskcb.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, loctemp.get(), bufmaskorigcb.get(), originalmaskcb.get(), original, reserved, inv, lp, 0.f, false, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskcblocalcurve, localmaskcbutili, dummy, false, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.0f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.0f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskcbmet == 3) { @@ -16787,12 +17368,12 @@ void ImProcFunctions::Lab_Local( float amountcd = 0.f; float anchorcd = 50.f; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufexporig.get(), bufmaskorigvib.get(), originalmaskvib.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufexporig.get(), bufmaskorigvib.get(), originalmaskvib.get(), original, reserved, inv, lp, 0.f, false, locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskviblocalcurve, localmaskvibutili, dummy, false, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskvibmet == 3) { @@ -16845,16 +17426,15 @@ void ImProcFunctions::Lab_Local( } if (lp.strvibh != 0.f) { - printf("a\n"); struct grad_params gph; - calclocalGradientParams(lp, gph, ystart, xstart, bfw, bfh, 9); + calclocalGradientParams(call, lp, gph, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 9, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { - float factor = ImProcFunctions::calcGradientFactor(gph, jr, ir); + float factor = ImProcFunctions::calcGradientFactor(gph, cx*kskx + kbw*jr, cy*ksk + kbh*ir); float aa = bufexpfin->a[ir][jr]; float bb = bufexpfin->b[ir][jr]; float chrm = std::sqrt(SQR(aa) + SQR(bb)); @@ -16886,30 +17466,30 @@ void ImProcFunctions::Lab_Local( if (lp.strvib != 0.f) { struct grad_params gp; - calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 7); + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 7, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); + bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, cx*kskx + kbw*jr, cy*ksk + kbh*ir); } } } if (lp.strvibab != 0.f) { - printf("c\n"); struct grad_params gpab; - calclocalGradientParams(lp, gpab, ystart, xstart, bfw, bfh, 8); + calclocalGradientParams(call, lp, gpab, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 8, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { - const float factor = ImProcFunctions::calcGradientFactor(gpab, jr, ir); + const float factor = ImProcFunctions::calcGradientFactor(gpab, cx*kskx + kbw*jr, cy*ksk + kbh*ir); bufexpfin->a[ir][jr] *= factor; bufexpfin->b[ir][jr] *= factor; } @@ -16995,9 +17575,9 @@ void ImProcFunctions::Lab_Local( } if (lp.recothrv >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 2, bufexporig.get(), bufexpfin.get(), originalmaskvib.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 2, bufexporig.get(), bufexpfin.get(), originalmaskvib.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 2, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 2, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } @@ -17029,22 +17609,33 @@ void ImProcFunctions::Lab_Local( tonecurv = true; } - if (! lp.invsh && (lp.highlihs > 0.f || lp.shadowhs > 0.f || tonequ || tonecurv || lp.strSH != 0.f || lp.showmaskSHmet == 2 || lp.enaSHMask || lp.showmaskSHmet == 3 || lp.showmaskSHmet == 4 || lp.prevdE) && call <= 3 && lp.hsena) { + bool ghsactiv = false; + float D = params->locallab.spots.at(sp).ghs_D;//enable GHS and Stretch factor + //float BLP = params->locallab.spots.at(sp).ghs_BLP; + //float HLP = params->locallab.spots.at(sp).ghs_HLP; + bool smoth = params->locallab.spots.at(sp).ghs_smooth;//Highlight attenuation + float MID = params->locallab.spots.at(sp).ghs_MID;//midtones + + if(D != 0.f /* || BLP != 0.f || HLP != 1.f* || smoth*/) { + ghsactiv = true; + } + if (! lp.invsh && (lp.highlihs > 0.f || lp.shadowhs > 0.f || tonequ || tonecurv || ghsactiv || lp.strSH != 0.f || lp.showmaskSHmet == 2 || lp.enaSHMask || lp.showmaskSHmet == 3 || lp.showmaskSHmet == 4 || lp.prevdE) && call <= 3 && lp.hsena) { const int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); const int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); const int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); const int xend = rtengine::min(static_cast(lp.xc + lp.lx) - cx, original->W); const int bfh = yend - ystart; const int bfw = xend - xstart; - + // printf("LP.XC=%f LP.YC=%f\n", (double) lp.xc, (double) lp.yc); if (bfw >= mSP && bfh >= mSP) { - + //printf("CALL=%i \n", call); const std::unique_ptr bufexporig(new LabImage(bfw, bfh)); const std::unique_ptr bufexpfin(new LabImage(bfw, bfh)); std::unique_ptr bufmaskorigSH; std::unique_ptr bufmaskblurSH; std::unique_ptr originalmaskSH; + const std::unique_ptr tmp1(new LabImage(transformed->W, transformed->H));// to use for plain image if (lp.showmaskSHmet == 2 || lp.enaSHMask || lp.showmaskSHmet == 3 || lp.showmaskSHmet == 4) { bufmaskorigSH.reset(new LabImage(bfw, bfh)); @@ -17115,12 +17706,12 @@ void ImProcFunctions::Lab_Local( int lumask = params->locallab.spots.at(sp).lumask; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufexporig.get(), bufmaskorigSH.get(), originalmaskSH.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufexporig.get(), bufmaskorigSH.get(), originalmaskSH.get(), original, reserved, inv, lp, 0.f, false, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskSHlocalcurve, localmaskSHutili, dummy, false, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskSHmet == 3) { @@ -17128,6 +17719,23 @@ void ImProcFunctions::Lab_Local( return; } + //to test gradiant in mode plain image GW GH instead of bfw bfh - I prefer to keep this code, even if it is not used, because it is another way to approach the graduated Filter in SE + LocalLabGradientMode grad = LocalLabGradientMode::STANDARD;// grad = 1 to plain image GF + int ca1 = 1;//dcrop + int ca2 = 2;//simpleprocess + int ca3 = 3;//improccordinator + int ca4 = 10;//do nothing + if(grad == LocalLabGradientMode::PLAIN_IMAGE) {//plain image GF + ca1 = 2; + ca2 = 2; + ca3 = 3; + ca4 = 1; + } + + bool execgradsh = false; + if(lp.fullim == 3 || lp.fullim == 2 || lp.fullim == 0) { + execgradsh = true; + } if (lp.showmaskSHmet == 0 || lp.showmaskSHmet == 1 || lp.showmaskSHmet == 2 || lp.showmaskSHmet == 4 || lp.enaSHMask) { @@ -17150,22 +17758,6 @@ void ImProcFunctions::Lab_Local( ImProcFunctions::shadowsHighlights(bufexpfin.get(), lp.hsena, 1, lp.highlihs, lp.shadowhs, lp.radiushs, sk, lp.hltonalhs, lp.shtonalhs); } -//gradient - struct grad_params gp; - - if (lp.strSH != 0.f) { - calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 2); -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); - } - } - } - if (lp.shmeth == 1) { double scal = (double)(sk); Imagefloat *tmpImage = nullptr; @@ -17193,6 +17785,415 @@ void ImProcFunctions::Lab_Local( delete tmpImage; } + + if (lp.shmeth == 2) { + if(ghsactiv) { + // GHT filter ported from Siril - help with ART CTL thanks to Alberto Griggio + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + + float B = params->locallab.spots.at(sp).ghs_B;//Local intensity + float LP = params->locallab.spots.at(sp).ghs_LP;//Protect shadows + float SP = params->locallab.spots.at(sp).ghs_SP;//Symmetry point + float HP = params->locallab.spots.at(sp).ghs_HP;//Protect highlights + int blackpoint = 100. * params->locallab.spots.at(sp).ghs_BLP;//Black point + float shiftblackpoint = params->locallab.spots.at(sp).ghs_BLP;//Black point + float shiftwhitepoint = params->locallab.spots.at(sp).ghs_HLP;//White point + if(LP > SP) { + LP = SP; + } + if(HP < SP) { + HP = SP; + } + //ghshp2 = HP; + bool ghsinv = params->locallab.spots.at(sp).ghs_inv;//Inverse stretch + int met = 0; + GHTStrType strtype = GHTStrType::NORMAL; + if(ghsinv) { + strtype = GHTStrType::INVERSE; + } else { + strtype = GHTStrType::NORMAL; + } + if (params->locallab.spots.at(sp).ghsMethod == "rgb") {//mode RGB default in luminance mode + met = 0; + } else if (params->locallab.spots.at(sp).ghsMethod == "rgbstd") {//mode RGB standard + met = 1; + } else if (params->locallab.spots.at(sp).ghsMethod == "llab") {//Mode Lab + met = 2; + } else if (params->locallab.spots.at(sp).ghsMethod == "lum") {// L hsl + met = 3; + } else if (params->locallab.spots.at(sp).ghsMethod == "sat") {// sat hsl + met = 4; + } else if (params->locallab.spots.at(sp).ghsMethod == "hue") {// hue hsl + met = 5; + } + + const ght_compute_params c = GHT_setup(B, D, LP, SP, HP, strtype);//setup system with entries + + std::unique_ptr tmpImage(new Imagefloat(bfw, bfh)); + lab2rgb(*bufexpfin, *tmpImage, params->icm.workingProfile); + Glib::ustring prof = params->icm.workingProfile; + float ghsslop = params->locallab.spots.at(sp).ghs_slope; + float ghschro = params->locallab.spots.at(sp).ghs_chro; + rtengine::GammaValues g_a; //gamma parameters + float gamma1 = 3.0f; //params->locallab.spots.at(sp).shargam; + + double pwr1 = 1.0 / (double) 3.0;//default 3.0 - gamma Lab + double ts1 = ghsslop;//always the same 'slope' in the extreme shadows - slope Lab + rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope + const float noise = pow_F(2.f, -16.f);//GHS - do not process very low values which are probably noise. + + if(shiftblackpoint < 0.f && strtype == GHTStrType::NORMAL) {//change only Black point with negatives values for in some cases out of gamut values + //rgb value can be very weakly negatives (eg working space sRGB in some rare cases) - tone_eqblack prevents it + //also change black value to help "ghs" and avoid noise + tone_eqblack(this, tmpImage.get(), -5 * blackpoint, params->icm.workingProfile, sk, multiThread);//Ev -16 to -8 + // -5 to be in range 0..100 + } + {//change black point and white point for GHS + // Sets the Blackpoint and Whitepoint for a linear stretch of the image + float shiftblackpoint2 = shiftblackpoint; + if(shiftblackpoint < 0.f && strtype == GHTStrType::NORMAL) { + shiftblackpoint2 = 0.f;//set to zero if balc point negatif, no change + } + if(strtype == GHTStrType::INVERSE) { + shiftblackpoint2 = shiftblackpoint; + } + int bpnb = 0; + int wpnb = 0; + float minbp = 1.f; + float maxwp = 0.f; + + t1.set(); + + +#ifdef _OPENMP + # pragma omp parallel for reduction(+:bpnb, wpnb) reduction(min:minbp) reduction(max:maxwp) if (multiThread) //for schedule(dynamic,16) +#endif + for (int i = 0; i < bfh; ++i) + for (int j = 0; j < bfw; ++j) { + float r = tmpImage->r(i, j) / 65535.f; + float g = tmpImage->g(i, j) / 65535.f; + float b = tmpImage->b(i, j) / 65535.f; + float Ro, Go, Bo; + float deltawp = rtengine::max(0.05f, shiftwhitepoint - shiftblackpoint2);//0.05 minimum acceptable + if(strtype == GHTStrType::NORMAL) { + Ro = (r - shiftblackpoint2) / deltawp; + Go = (g - shiftblackpoint2) / deltawp; + Bo = (b - shiftblackpoint2) / deltawp; + } else { + Ro = (shiftblackpoint2) + r * deltawp; + Go = (shiftblackpoint2) + g * deltawp; + Bo = (shiftblackpoint2) + b * deltawp; + } + float minrgb = rtengine::min(Ro, Go, Bo); + if(minrgb < minbp){ + minbp = minrgb; + } + + float maxrgb = rtengine::max(Ro, Go, Bo); + if(maxrgb > maxwp){ + maxwp = maxrgb; + } + + if(Ro < 0.f || Go < 0.f || Bo < 0.f) { + bpnb++; + } + if(Ro > 1.f || Go > 1.f || Bo > 1.f) { + wpnb++; + } + if( strtype == GHTStrType::NORMAL ) { //strtype == GHTStrType::NORMAL only strtype == GHTStrType::NORMAL if crash + tmpImage->r(i, j) = rtengine::max(0.00001f, Ro * 65535.f);//0.00001f to avoid crash + tmpImage->g(i, j) = rtengine::max(0.00001f, Go * 65535.f); + tmpImage->b(i, j) = rtengine::max(0.00001f, Bo * 65535.f); + } else if( strtype == GHTStrType::INVERSE) {//to uncomment if crash + tmpImage->r(i, j) = clipR(rtengine::max(0.00001f, Ro * 65535.f));//0.0001f to avoid crash different from 'normal' + tmpImage->g(i, j) = clipR(rtengine::max(0.00001f, Go * 65535.f));//clipR to avoid crash in some cases + tmpImage->b(i, j) = clipR(rtengine::max(0.00001f, Bo * 65535.f)); + } + } + ghsbpwp[0] = bpnb; + ghsbpwp[1] = wpnb; + ghsbpwpvalue[0] = minbp; + ghsbpwpvalue[1] = maxwp; + + t2.set(); + if (settings->verbose) { + printf("calculate Black Point and White Point: %d nsec\n", t2.etime(t1)); + } + + /* + if (settings->verbose) { + printf("Black Point-nb=%i White Point-nb=%i min-BlackPoint val=%f max-WhitePointPval=%f \n", ghsbpwp[0], ghsbpwp[1], (double)ghsbpwpvalue[0] , (double) ghsbpwpvalue[1]); + } + */ + } + + if(met == 0 || met == 1) {//RGB mode + const auto sf = + [=](float s, float c) -> float + { + if (c > noise) { + return 1.f - min(std::abs(s) / c, 1.f); + } else { + return 0.f; + } + }; + //saturation + const auto apply_sat = + [&](float &r, float &g, float &b, float f, float ll) -> void + { + float rl = r - ll; + float gl = g - ll; + float bl = b - ll; + float s = intp(max(sf(rl, r), sf(gl, g), sf(bl, b)), pow_F(f, 0.3f) * 0.6f + 0.4f, 1.f); + r = ll + s * rl; + g = ll + s * gl; + b = ll + s * bl; + }; + + //local contrast with guidedfilter incorporated in RGB luminance met = 0 + array2D Yc(bfw, bfh); + { + constexpr float base_posterization = 20.f; + array2D Y2(bfw, bfh); + +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + for (int y = 0; y < bfh; ++y) { + for (int x = 0; x < bfw; ++x) { + Y2[y][x] = norm2(tmpImage->r(y, x), tmpImage->g(y, x), tmpImage->b(y, x), wprof) / 65535.f;//norm ? + float l = xlogf(rtengine::max(Y2[y][x], 1e-9f)); + float ll = round(l * base_posterization) / base_posterization; + Yc[y][x] = xexpf(ll); + assert(std::isfinite(Yc[y][x])); + } + } + + const float radius = rtengine::max(bfw, bfh) / 30.f; + const float epsilon = 0.005f; + if(D > 0.002f) {//to preserve settings WP and BP + rtengine::guidedFilter(Y2, Yc, Yc, radius, epsilon, multiThread); + } + } + float blend = 0.01 * params->locallab.spots.at(sp).ghs_LC; + blend = rtengine::max(0.0001f, blend); + //end local contrast integrate to stretch + +#ifdef _OPENMP + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int i = 0; i < bfh; ++i) + for (int j = 0; j < bfw; ++j) { + float r = tmpImage->r(i, j)/65535.f; + float g = tmpImage->g(i, j)/65535.f; + float b = tmpImage->b(i, j)/65535.f; + float Ro = 0.f; + float Go = 0.f; + float Bo = 0.f; + if(met == 0) { + float tlc = Yc[i][j]; + tlc = rtengine::max(tlc, noise); + float ci = GHT(tlc, B, D, LP, SP, HP, c, strtype); + float flc = ci / tlc; + float gh = norm2(r, g, b, wprof);//Calculate Luminance in function working profile Wprof norm ? + gh = rtengine::max(gh, noise); + float Mgh = GHT(gh, B, D, LP, SP, HP, c, strtype);//ghs transform with "luminance" + float fgh = Mgh / gh; + fgh = intp(blend, flc, fgh); + + Ro = r * fgh;//new values for r, g, b + Go = g * fgh; + Bo = b * fgh; + apply_sat(Ro, Go, Bo, fgh, gh);//always apply saturation + + } else if (met == 1) { + float gh = norm(r, g, b, wprof);//Calculate Luminance in function working profile Wprof + r = rtengine::max(r, noise); + g = rtengine::max(g, noise); + b = rtengine::max(b, noise); + + Ro = GHT(r, B, D, LP, SP, HP, c, strtype);//ghs R RGB standard + Go = GHT(g, B, D, LP, SP, HP, c, strtype);//ghs G RGB standard + Bo = GHT(b, B, D, LP, SP, HP, c, strtype);//ghs B RGB standard + + float fgh = 0.333f * ((Ro / r) + (Go / g) + (Bo /b));//linear average of the 3 channels + apply_sat(Ro, Go, Bo, fgh, gh);//always apply saturation + } + // rebuild tmpImage with limit 0.00001f to avoid crash after SE + tmpImage->r(i, j) = rtengine::max(0.00001f, Ro * 65535.f);//0.00001f to avoid crash + tmpImage->g(i, j) = rtengine::max(0.00001f, Go * 65535.f); + tmpImage->b(i, j) = rtengine::max(0.00001f, Bo * 65535.f); + } + } else if(met ==3 || met == 4 || met == 5) {//Luminance Saturation Hue HSL +#ifdef _OPENMP + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int i = 0; i < bfh; ++i) + for (int j = 0; j < bfw; ++j) { + float r = tmpImage->r(i, j); + float g = tmpImage->g(i, j); + float b = tmpImage->b(i, j); + float h, s, l; + Color::rgb2hsl(r, g, b, h, s, l); + if(met == 4) {//saturation + s = GHT(s, B, D, LP, SP, HP, c, strtype); + } else if (met == 3) {//luminance HSL + l = rtengine::max(l, noise); + l = GHT(l, B, D, LP, SP, HP, c, strtype); + } else if (met == 5) {//hue + h = GHT(h, B, D, LP, SP, HP, c, strtype); + } + float R, G, B; + Color::hsl2rgb(h, s, l, R, G, B); + tmpImage->r(i, j) = rtengine::max(0.00001f, R);//0.00001f to avoid crash + tmpImage->g(i, j) = rtengine::max(0.00001f, G); + tmpImage->b(i, j) = rtengine::max(0.00001f, B); + } + } else if(met == 2) {// Luminance chromaticity Lab mode + const std::unique_ptr labtemp(new LabImage(bfw, bfh)); + rgb2lab(*tmpImage, *labtemp, params->icm.workingProfile); + const float satreal = ghschro; + + DiagonalCurve color_satur({//curve for smoothing chroma ++ + DCT_NURBS, + 0, 0, + 0.2, 0.2f + satreal / 250.f, + 0.6, rtengine::min(1.f, 0.6f + satreal / 250.f), + 1, 1 + }); + + DiagonalCurve color_saturmoins({//curve for smoothing chroma -- + DCT_NURBS, + 0, 0, + 0.1f - satreal / 150.f, 0.1f, + rtengine::min(1.f, 0.7f - satreal / 300.f), 0.7, + 1, 1 + }); + +#ifdef _OPENMP + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int i = 0; i < bfh; ++i) + for (int j = 0; j < bfw; ++j) { + float lLab = labtemp->L[i][j]/32768.f; + float alab = labtemp->a[i][j]; + float blab = labtemp->b[i][j]; + //Chromaticity + float Chprov = std::sqrt(SQR(alab) + SQR(blab)); + float2 sincosval; + sincosval.y = Chprov == 0.0f ? 1.f : alab / Chprov; + sincosval.x = Chprov == 0.0f ? 0.f : blab / Chprov; + if(ghschro > 0.f){ + Chprov = static_cast(color_satur.getVal(LIM01(Chprov / 35000.f))); + } else { + Chprov = static_cast(color_saturmoins.getVal(LIM01(Chprov / 35000.f))); + } + float chl = LIM01(Chprov);//in case of very very strong chromaticity to be sure no clip + chl = GHT(chl, B, D, LP, SP, HP, c, strtype);//Chromaticity GHS + Chprov = chl * 35000.f; + alab = Chprov * sincosval.y; + blab = Chprov * sincosval.x; + //Luminance with new slope + lLab = gammalog(lLab, gamma1, ts1, g_a[3], g_a[4]);//slope factor + lLab = rtengine::max(lLab, noise); + lLab = GHT(lLab, B, D, LP, SP, HP, c, strtype);//Luminance GHS + lLab = igammalog(lLab, gamma1, ts1, g_a[2], g_a[4]);//inverse slope factor + + labtemp->L[i][j] = lLab * 32768.f; + labtemp->a[i][j] = alab;//restore Lab values + labtemp->b[i][j] = blab; + } + lab2rgb(*labtemp, *tmpImage, params->icm.workingProfile); + } + + if(smoth && D > 0.002f) {//to preserve settings WP and BP + //Highlight attenuation in function of HP - protect highlight + tone_eqsmooth(this, tmpImage.get(), lp, params->icm.workingProfile, sk, multiThread);//reduce Ev > 0 < 12 + } + if(MID != 0.f && D > 0.002f) {//to preserve settings WP and BP + //midtones with tone_equ + ImProcFunctions::tone_eqcam(this, tmpImage.get(), MID, params->icm.workingProfile, sk, multiThread); + } + + if(strtype == GHTStrType::INVERSE) {//inverse GHS +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + for (int i = 0; i < bfh; ++i) + for (int j = 0; j < bfw; ++j) { + tmpImage->r(i, j) = clipR(rtengine::max(0.00001f, tmpImage->r(i, j)));//0.0001f to avoid crash + tmpImage->g(i, j) = clipR(rtengine::max(0.00001f, tmpImage->g(i, j)));//clipR to avoid crash in inverse GHS + tmpImage->b(i, j) = clipR(rtengine::max(0.00001f, tmpImage->b(i, j))); + } + } else if (strtype == GHTStrType::NORMAL) {//GHS +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + for (int i = 0; i < bfh; ++i) + for (int j = 0; j < bfw; ++j) { + tmpImage->r(i, j) = rtengine::max(0.00001f, tmpImage->r(i, j));//0.00001f to avoid crash after SE with RGB functions + tmpImage->g(i, j) = rtengine::max(0.00001f, tmpImage->g(i, j)); + tmpImage->b(i, j) = rtengine::max(0.00001f, tmpImage->b(i, j)); + } + } + + + + rgb2lab(*tmpImage, *bufexpfin, params->icm.workingProfile); + + tmpImage.reset(); + //local contrast minimum + double kmod = 2.2; + if(met == 0) { + kmod = 1.6; + } + float rad = kmod * params->locallab.spots.at(sp).ghs_LC; + float stren = 15.f * (1.f + D);//take into account D stretch + if(D > 0.002f) {//to preserve settings WP and BP + loccont(bfw, bfh, bufexpfin.get(), rad, stren , sk); //local contrast in L (Lab) mode. + } + } + } + //gradient + int GH = transformed->H; + int GW = transformed->W; + + struct grad_params gp; + //here with grad=0 - standard. + if (lp.strSH != 0.f && (call == ca1 || call == ca2 || call == ca3) && execgradsh) {//test to plain image + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 2, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + + for (int ir = 0; ir < bfh; ir++) { + for (int jr = 0; jr < bfw; jr++) { + bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, cx*kskx + kbw*jr, cy*ksk + kbh*ir); + } + } + } else if(lp.strSH != 0.f && execgradsh && (call == ca4) && ((GW >= mDEN && GH >= mDEN))){//test to run in plain image - not used + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, GW, GH, oW, oH, tX, tY, tW, tH, 2, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int ir = 0; ir < GH; ir++) + for (int jr = 0; jr < GW; jr++) { + tmp1->L[ir][jr] = original->L[ir][jr]; + tmp1->a[ir][jr] = original->a[ir][jr]; + tmp1->b[ir][jr] = original->b[ir][jr]; + } +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int ir = 0; ir < GH; ir++) { + for (int jr = 0; jr < GW; jr++) { + tmp1->L[ir][jr] = ImProcFunctions::calcGradientFactor(gp, cy + jr, cx + ir); + } + } + } + //end gradient + + } if (lp.enaSHMask && lp.recothrs != 1.f) { @@ -17225,11 +18226,19 @@ void ImProcFunctions::Lab_Local( bufexpfin->b[x][y] = intp(repart, bufexporig->b[x][y], bufexpfin->b[x][y]); } } - + if (lp.recothrs >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), originalmaskSH.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + if(call == ca1 || call == ca2 || call == ca3) {//call == 2 to run in mode plain image + transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), originalmaskSH.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); + } else if (call == ca4 && execgradsh) {// mode plain image call = 1 + transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), originalmaskSH.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, tmp1.get(), grad, cx, cy, sk); + } } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + if(call == ca1 || call == ca2 || call == ca3) {//call == 2 to run in mode plain image + transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); + } else if (call == ca4 && execgradsh) {// mode plain image + transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, tmp1.get(), grad, cx, cy, sk); + } } if (lp.recur) { @@ -17299,12 +18308,12 @@ void ImProcFunctions::Lab_Local( int lumask = params->locallab.spots.at(sp).lumask; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, TW, TH, 0, 0, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskSH.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, TW, TH, oW, oH, tX, tY, tW, tH, 0, 0, 0, 0, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskSH.get(), original, reserved, inv, lp, 0.f, false, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskSHlocalcurve, localmaskSHutili, dummy, false, 1, 1, 5, 5, shortcu, false, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); @@ -17395,7 +18404,7 @@ void ImProcFunctions::Lab_Local( } } - transit_shapedetect2(sp, 0.f, 0.f, call, 3, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 3, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); if (lp.recur) { original->CopyFrom(transformed, multiThread); @@ -17576,12 +18585,12 @@ void ImProcFunctions::Lab_Local( int lumask = params->locallab.spots.at(sp).lumask; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufgb.get(), bufmaskoriglc.get(), originalmasklc.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufgb.get(), bufmaskoriglc.get(), originalmasklc.get(), original, reserved, inv, lp, 0.f, false, locccmaslcCurve, lcmaslcutili, locllmaslcCurve, llmaslcutili, lochhmaslcCurve, lhmaslcutili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmasklclocalcurve, localmasklcutili, dummy, false, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmasklcmet == 3) { @@ -17717,7 +18726,7 @@ void ImProcFunctions::Lab_Local( } } - wavcontrast4(lp, tmp1->L, tmp1->a, tmp1->b, contrast, radblur, radlevblur, tmp1->W, tmp1->H, level_bl, level_hl, level_br, level_hr, sk, numThreads, locwavCurve, locwavutili, wavcurve, loclevwavCurve, loclevwavutili, wavcurvelev, locconwavCurve, locconwavutili, wavcurvecon, loccompwavCurve, loccompwavutili, wavcurvecomp, loccomprewavCurve, loccomprewavutili, wavcurvecompre, locedgwavCurve, locedgwavutili, sigma, offs, maxlvl, sigmadc, deltad, chrol, chrobl, blurlc, blurena, levelena, comprena, compreena, compress, thres); + wavcontrast4(call, lp, tmp1->L, tmp1->a, tmp1->b, contrast, radblur, radlevblur, tmp1->W, tmp1->H, oW, oH, tX, tY, tW, tH, level_bl, level_hl, level_br, level_hr, sk, numThreads, locwavCurve, locwavutili, wavcurve, loclevwavCurve, loclevwavutili, wavcurvelev, locconwavCurve, locconwavutili, wavcurvecon, loccompwavCurve, loccompwavutili, wavcurvecomp, loccomprewavCurve, loccomprewavutili, wavcurvecompre, locedgwavCurve, locedgwavutili, sigma, offs, maxlvl, sigmadc, deltad, chrol, chrobl, blurlc, blurena, levelena, comprena, compreena, compress, thres, fw, fh, cx, cy, ksk, kskx, kbh, kbw); if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "wav") { bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; @@ -17962,9 +18971,9 @@ void ImProcFunctions::Lab_Local( } if (lp.recothrw >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 10, bufgb.get(), tmp1.get(), originalmasklc.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 10, bufgb.get(), tmp1.get(), originalmasklc.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 10, bufgb.get(), tmp1.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 10, bufgb.get(), tmp1.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } tmp1.reset(); @@ -18393,12 +19402,12 @@ void ImProcFunctions::Lab_Local( int lumask = params->locallab.spots.at(sp).lumask; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufexporig.get(), bufmaskblurexp.get(), originalmaskexp.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufexporig.get(), bufmaskblurexp.get(), originalmaskexp.get(), original, reserved, inv, lp, 0.f, false, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskexplocalcurve, localmaskexputili, dummy, false, 1, 1, 5, 5, shortcu, params->locallab.spots.at(sp).deltae, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, 0, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, 0, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskexpmet == 3) { @@ -18462,14 +19471,14 @@ void ImProcFunctions::Lab_Local( if (lp.strexp != 0.f) { - calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 1); + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 1, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); + bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, cx*kskx + kbw*jr, cy*ksk + kbh*ir); } } } @@ -18696,9 +19705,9 @@ void ImProcFunctions::Lab_Local( } if (lp.recothre >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 1, bufexporig.get(), bufexpfin.get(), originalmaskexp.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 1, bufexporig.get(), bufexpfin.get(), originalmaskexp.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 1, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 1, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } } @@ -18761,12 +19770,12 @@ void ImProcFunctions::Lab_Local( constexpr float anchorcd = 50.f; LocHHmaskCurve lochhhmasCurve; const int highl = 0; - maskcalccol(false, pde, TW, TH, 0, 0, sk, cx, cy, bufexporig.get(), bufmaskblurexp.get(), originalmaskexp.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, TW, TH, oW, oH, tX, tY, tW, tH, 0, 0, 0, 0, sk, cx, cy, bufexporig.get(), bufmaskblurexp.get(), originalmaskexp.get(), original, reserved, inv, lp, 0.f, false, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, lochhhmasCurve, false, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskexplocalcurve, localmaskexputili, dummy, false, 1, 1, 5, 5, shortcu, false, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, 0, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, 0, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskexpmetinv == 1) { @@ -18989,13 +19998,13 @@ void ImProcFunctions::Lab_Local( const float anchorcd = 50.f; const int highl = 0; bool astool = params->locallab.spots.at(sp).toolcol; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, reserved, inv, lp, strumask, astool, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, llochhhmasCurve, lhhmasutili, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmasklocalcurve, localmaskutili, loclmasCurvecolwav, lmasutilicolwav, level_bl, level_hl, level_br, level_hr, shortcu, delt, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftColorMask, lp.blurcolmask, lp.contcolmask, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftColorMask, lp.blurcolmask, lp.contcolmask, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskcolmet == 3) { @@ -19371,14 +20380,14 @@ void ImProcFunctions::Lab_Local( if (lp.strcol != 0.f) { struct grad_params gp; - calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 3); + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 3, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - const float corrFactor = ImProcFunctions::calcGradientFactor(gp, jr, ir); + const float corrFactor = ImProcFunctions::calcGradientFactor(gp, cx*kskx + kbw*jr, cy*ksk + kbh*ir); bufcolfin->L[ir][jr] *= corrFactor; } } @@ -19386,14 +20395,14 @@ void ImProcFunctions::Lab_Local( if (lp.strcolab != 0.f) { struct grad_params gpab; - calclocalGradientParams(lp, gpab, ystart, xstart, bfw, bfh, 4); + calclocalGradientParams(call, lp, gpab, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 4, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - const float corrFactor = ImProcFunctions::calcGradientFactor(gpab, jr, ir); + const float corrFactor = ImProcFunctions::calcGradientFactor(gpab, cx*kskx + kbw*jr, cy*ksk + kbh*ir); bufcolfin->a[ir][jr] *= corrFactor; bufcolfin->b[ir][jr] *= corrFactor; } @@ -19402,14 +20411,14 @@ void ImProcFunctions::Lab_Local( if (lp.strcolh != 0.f) { struct grad_params gph; - calclocalGradientParams(lp, gph, ystart, xstart, bfw, bfh, 6); + calclocalGradientParams(call, lp, gph, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 6, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - const float corrFactor = ImProcFunctions::calcGradientFactor(gph, jr, ir); + const float corrFactor = ImProcFunctions::calcGradientFactor(gph, cx*kskx + kbw*jr, cy*ksk + kbh*ir); const float aa = bufcolfin->a[ir][jr]; const float bb = bufcolfin->b[ir][jr]; const float chrm = std::sqrt(SQR(aa) + SQR(bb)); @@ -19889,35 +20898,35 @@ void ImProcFunctions::Lab_Local( } } - transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolreserv.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolreserv.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } if (!nottransit) { //gradient if (lp.strcol != 0.f) { struct grad_params gp; - calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 3); + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 3, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { - const float corrFactor = ImProcFunctions::calcGradientFactor(gp, jr, ir); + const float corrFactor = ImProcFunctions::calcGradientFactor(gp, cx*kskx + kbw*jr, cy*ksk + kbh*ir); bufcolfin->L[ir][jr] *= corrFactor; } } if (lp.strcolab != 0.f) { struct grad_params gpab; - calclocalGradientParams(lp, gpab, ystart, xstart, bfw, bfh, 5); + calclocalGradientParams(call, lp, gpab, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 5, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { - const float corrFactor = ImProcFunctions::calcGradientFactor(gpab, jr, ir); + const float corrFactor = ImProcFunctions::calcGradientFactor(gpab, cx*kskx + kbw*jr, cy*ksk + kbh*ir); bufcolfin->a[ir][jr] *= corrFactor; bufcolfin->b[ir][jr] *= corrFactor; } @@ -19925,14 +20934,14 @@ void ImProcFunctions::Lab_Local( if (lp.strcolh != 0.f) { struct grad_params gph; - calclocalGradientParams(lp, gph, ystart, xstart, bfw, bfh, 6); + calclocalGradientParams(call, lp, gph, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 6, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { - const float corrFactor = ImProcFunctions::calcGradientFactor(gph, jr, ir); + const float corrFactor = ImProcFunctions::calcGradientFactor(gph, cx*kskx + kbw*jr, cy*ksk + kbh*ir); const float aa = bufcolfin->a[ir][jr]; const float bb = bufcolfin->b[ir][jr]; const float chrm = std::sqrt(SQR(aa) + SQR(bb)); @@ -20031,9 +21040,9 @@ void ImProcFunctions::Lab_Local( float meansob = 0.f; if (lp.recothrc >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolorig.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolorig.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolorig.get(), bufcolfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolorig.get(), bufcolfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } } @@ -20121,13 +21130,13 @@ void ImProcFunctions::Lab_Local( constexpr float amountcd = 0.f; constexpr float anchorcd = 50.f; const int highl = 0; - maskcalccol(false, pde, TW, TH, 0, 0, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, TW, TH, oW, oH, tX, tY, tW, tH, 0, 0, 0, 0, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, reserved, inv, lp, strumask, params->locallab.spots.at(sp).toolcol, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, llochhhmasCurve, lhhmasutili, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmasklocalcurve, localmaskutili, loclmasCurvecolwav, lmasutilicolwav, level_bl, level_hl, level_br, level_hr, shortcu, false, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftColorMask, lp.blurcolmask, lp.contcolmask, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftColorMask, lp.blurcolmask, lp.contcolmask, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskcolmetinv == 1) { @@ -20249,13 +21258,13 @@ void ImProcFunctions::Lab_Local( const float anchorcd = 50.f; const int highl = 0; bool astool = params->locallab.spots.at(sp).toolmask; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, reserved, inv, lp, strumask, astool, locccmas_Curve, lcmas_utili, locllmas_Curve, llmas_utili, lochhmas_Curve, lhmas_utili, lochhhmas_Curve, lhhmas_utili, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendmab, shado, highl, amountcd, anchorcd, lmasklocal_curve, localmask_utili, loclmasCurve_wav, lmasutili_wav, level_bl, level_hl, level_br, level_hr, shortcu, delt, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftma, lp.blurma, lp.contma, 12, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftma, lp.blurma, lp.contma, 12, fab, fw, fh, ksk, kskx, kbh, kbw ); @@ -20313,7 +21322,7 @@ void ImProcFunctions::Lab_Local( float meansob = 0.f; - transit_shapedetect2(sp, 0.f, 0.f, call, 20, bufcolorigsav.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, nullptr, lp, origsav, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 20, bufcolorigsav.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, nullptr, lp, origsav, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); delete origsav; origsav = NULL; @@ -20470,13 +21479,13 @@ void ImProcFunctions::Lab_Local( const int shado = params->locallab.spots.at(sp).shadmaskcie; const int highl = params->locallab.spots.at(sp).highmaskcie; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufexporig.get(), bufmaskorigcie.get(), originalmaskcie.get(), original, reserved, inv, lp, + maskcalccol(call, false, pde, bfw, bfh, oW, oH, tX, tY, tW, tH, xstart, ystart, xend, yend, sk, cx, cy, bufexporig.get(), bufmaskorigcie.get(), originalmaskcie.get(), original, reserved, inv, lp, strumask, astool, locccmascieCurve, lcmascieutili, locllmascieCurve, llmascieutili, lochhmascieCurve, lhmascieutili, llochhhmascieCurve, lhhmascieutili, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskcielocalcurve, localmaskcieutili, loclmasCurveciewav, lmasutiliciewav, level_bl, level_hl, level_br, level_hr, shortcu, delt, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftcieMask, lp.blurciemask, lp.contciemask, -1, fab + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftcieMask, lp.blurciemask, lp.contciemask, -1, fab, fw, fh, ksk, kskx, kbh, kbw ); if (lp.showmaskciemet == 3) { @@ -20993,14 +22002,14 @@ void ImProcFunctions::Lab_Local( if (lp.strgradcie != 0.f) { struct grad_params gp; - calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 15); + calclocalGradientParams(call, lp, gp, ystart, xstart, yend, xend, bfw, bfh, oW, oH, tX, tY, tW, tH, 15, sk, fw, fh, cx, cy, ksk, kskx, kbh, kbw); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { - bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); + bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, cx*kskx + kbw*jr, cy*ksk + kbh*ir); } } } @@ -21099,9 +22108,9 @@ void ImProcFunctions::Lab_Local( } if (lp.recothrcie >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), originalmaskcie.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), originalmaskcie.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, nullptr, LocalLabGradientMode::STANDARD, cx, cy, sk); } if (lp.recur) { diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index c75a8c1ea..2fd1c2587 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -751,7 +751,6 @@ static void calcGradientParams (int oW, int oH, const GradientParams& gradient, double gradient_center_y = gradient.centerY / 200.0 + 0.5; double gradient_angle = gradient.degree / 180.0 * rtengine::RT_PI; //fprintf(stderr, "%f %f %f %f %f %d %d\n", gradient_stops, gradient_span, gradient_center_x, gradient_center_y, gradient_angle, w, h); - // make 0.0 <= gradient_angle < 2 * rtengine::RT_PI gradient_angle = fmod (gradient_angle, 2 * rtengine::RT_PI); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2eb4c30df..2abb30593 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3687,7 +3687,23 @@ LocallabParams::LocallabSpot::LocallabSpot() : visishadhigh(false), expshadhigh(false), complexshadhigh(0), - shMethod("tone"), + shMethod("ghs"), + ghsMethod("rgb"), + ghsMode("ghs"), + ghs_D(0.001), + ghs_slope(9.03296), + ghs_chro(0.0), + ghs_B(0.), + ghs_SP(0.015),//initialized with a low value to avoid zero + ghs_LP(0.), + ghs_HP(1.), + ghs_LC(30.), + ghs_MID(0.), + ghs_BLP(0.), + ghs_HLP(1.), + ghs_smooth(false), + ghs_inv(false), + multsh{0, 0, 0, 0, 0, 0}, highlights(0), h_tonalwidth(70), @@ -3841,8 +3857,11 @@ LocallabParams::LocallabSpot::LocallabSpot() : strvib(0.0), strvibab(0.0), strvibh(0.0), - angvib(0.0), - feathervib(25.0), + // angvib(0.0), + angvib(1.0), + // feathervib(25.0), + feathervib(1.0), + Lmaskvibcurve{ static_cast(DCT_NURBS), 0.0, @@ -3915,6 +3934,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : nlpat(2), nlrad(5), nlgam(3.), + nliter(1), sensiden(60), reparden(100.), detailthr(50), @@ -4978,16 +4998,6 @@ LocallabParams::LocallabSpot::LocallabSpot() : refi(0.), shiftxl(0.), shiftyl(0.), - labgridcieALow(0.51763),//Prophoto red = (0.7347+0.1) * 1.81818 - 1 - labgridcieBLow(-0.33582), - labgridcieAHigh(-0.75163),//Prophoto blue - labgridcieBHigh(-0.8180), - labgridcieGx(-0.528),//Prophoto green 0.1596 - labgridcieGy(0.7096),//0.84 - labgridcieWx(-0.18964),//D50 0.3457, 0.3585, - labgridcieWy(-0.16636),// - labgridcieMx(0.), - labgridcieMy(0.),// whitescie(20), blackscie(0), illMethod("d50"), @@ -5358,6 +5368,22 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && expshadhigh == other.expshadhigh && complexshadhigh == other.complexshadhigh && shMethod == other.shMethod + && ghsMethod == other.ghsMethod + && ghsMode == other.ghsMode + && ghs_D == other.ghs_D + && ghs_slope == other.ghs_slope + && ghs_chro == other.ghs_chro + && ghs_B == other.ghs_B + && ghs_SP == other.ghs_SP + && ghs_LP == other.ghs_LP + && ghs_HP == other.ghs_HP + && ghs_LC == other.ghs_LC + && ghs_MID == other.ghs_MID + && ghs_BLP == other.ghs_BLP + && ghs_HLP == other.ghs_HLP + && ghs_smooth == other.ghs_smooth + && ghs_inv == other.ghs_inv + && [this, &other]() -> bool { for (int i = 0; i < 6; ++i) { @@ -5495,6 +5521,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && nlpat == other.nlpat && nlrad == other.nlrad && nlgam == other.nlgam + && nliter == other.nliter && sensiden == other.sensiden && reparden == other.reparden && detailthr == other.detailthr @@ -7368,6 +7395,21 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->expshadhigh, "Locallab", "Expshadhigh_" + index_str, spot.expshadhigh, keyFile); saveToKeyfile(!pedited || spot_edited->complexshadhigh, "Locallab", "Complexshadhigh_" + index_str, spot.complexshadhigh, keyFile); saveToKeyfile(!pedited || spot_edited->shMethod, "Locallab", "ShMethod_" + index_str, spot.shMethod, keyFile); + saveToKeyfile(!pedited || spot_edited->ghsMethod, "Locallab", "GhsMethod_" + index_str, spot.ghsMethod, keyFile); + saveToKeyfile(!pedited || spot_edited->ghsMode, "Locallab", "GhsMode_" + index_str, spot.ghsMode, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_D, "Locallab", "Ghs_D_" + index_str, spot.ghs_D, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_slope, "Locallab", "Ghs_slope_" + index_str, spot.ghs_slope, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_chro, "Locallab", "Ghs_chro_" + index_str, spot.ghs_chro, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_B, "Locallab", "Ghs_B_" + index_str, spot.ghs_B, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_SP, "Locallab", "Ghs_SP_" + index_str, spot.ghs_SP, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_LP, "Locallab", "Ghs_LP_" + index_str, spot.ghs_LP, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_HP, "Locallab", "Ghs_HP_" + index_str, spot.ghs_HP, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_LC, "Locallab", "Ghs_LC_" + index_str, spot.ghs_LC, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_MID, "Locallab", "Ghs_MID_" + index_str, spot.ghs_MID, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_BLP, "Locallab", "Ghs_BLP_" + index_str, spot.ghs_BLP, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_HLP, "Locallab", "Ghs_HLP_" + index_str, spot.ghs_HLP, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_smooth, "Locallab", "Ghs_smooth_" + index_str, spot.ghs_smooth, keyFile); + saveToKeyfile(!pedited || spot_edited->ghs_inv, "Locallab", "Ghs_inv_" + index_str, spot.ghs_inv, keyFile); for (int j = 0; j < 6; j++) { saveToKeyfile(!pedited || spot_edited->multsh[j], "Locallab", "Multsh" + std::to_string(j) + "_" + index_str, spot.multsh[j], keyFile); @@ -7503,6 +7545,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->nlpat, "Locallab", "Nlpat_" + index_str, spot.nlpat, keyFile); saveToKeyfile(!pedited || spot_edited->nlrad, "Locallab", "Nlrad_" + index_str, spot.nlrad, keyFile); saveToKeyfile(!pedited || spot_edited->nlgam, "Locallab", "Nlgam_" + index_str, spot.nlgam, keyFile); + saveToKeyfile(!pedited || spot_edited->nliter, "Locallab", "Nliter_" + index_str, spot.nliter, keyFile); saveToKeyfile(!pedited || spot_edited->sensiden, "Locallab", "Sensiden_" + index_str, spot.sensiden, keyFile); saveToKeyfile(!pedited || spot_edited->reparden, "Locallab", "Reparden_" + index_str, spot.reparden, keyFile); saveToKeyfile(!pedited || spot_edited->detailthr, "Locallab", "Detailthr_" + index_str, spot.detailthr, keyFile); @@ -9752,6 +9795,21 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Complexshadhigh_" + index_str, spot.complexshadhigh, spotEdited.complexshadhigh); assignFromKeyfile(keyFile, "Locallab", "ShMethod_" + index_str, spot.shMethod, spotEdited.shMethod); + assignFromKeyfile(keyFile, "Locallab", "GhsMethod_" + index_str, spot.ghsMethod, spotEdited.ghsMethod); + assignFromKeyfile(keyFile, "Locallab", "GhsMode_" + index_str, spot.ghsMode, spotEdited.ghsMode); + assignFromKeyfile(keyFile, "Locallab", "Ghs_D_" + index_str, spot.ghs_D, spotEdited.ghs_D); + assignFromKeyfile(keyFile, "Locallab", "Ghs_slope_" + index_str, spot.ghs_slope, spotEdited.ghs_slope); + assignFromKeyfile(keyFile, "Locallab", "Ghs_chro_" + index_str, spot.ghs_chro, spotEdited.ghs_chro); + assignFromKeyfile(keyFile, "Locallab", "Ghs_B_" + index_str, spot.ghs_B, spotEdited.ghs_B); + assignFromKeyfile(keyFile, "Locallab", "Ghs_SP_" + index_str, spot.ghs_SP, spotEdited.ghs_SP); + assignFromKeyfile(keyFile, "Locallab", "Ghs_LP_" + index_str, spot.ghs_LP, spotEdited.ghs_LP); + assignFromKeyfile(keyFile, "Locallab", "Ghs_HP_" + index_str, spot.ghs_HP, spotEdited.ghs_HP); + assignFromKeyfile(keyFile, "Locallab", "Ghs_LC_" + index_str, spot.ghs_LC, spotEdited.ghs_LC); + assignFromKeyfile(keyFile, "Locallab", "Ghs_MID_" + index_str, spot.ghs_MID, spotEdited.ghs_MID); + assignFromKeyfile(keyFile, "Locallab", "Ghs_BLP_" + index_str, spot.ghs_BLP, spotEdited.ghs_BLP); + assignFromKeyfile(keyFile, "Locallab", "Ghs_HLP_" + index_str, spot.ghs_HLP, spotEdited.ghs_HLP); + assignFromKeyfile(keyFile, "Locallab", "Ghs_smooth_" + index_str, spot.ghs_smooth, spotEdited.ghs_smooth); + assignFromKeyfile(keyFile, "Locallab", "Ghs_inv_" + index_str, spot.ghs_inv, spotEdited.ghs_inv); for (int j = 0; j < 6; j ++) { assignFromKeyfile(keyFile, "Locallab", "Multsh" + std::to_string(j) + "_" + index_str, spot.multsh[j], spotEdited.multsh[j]); @@ -9938,6 +9996,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Nlpat_" + index_str, spot.nlpat, spotEdited.nlpat); assignFromKeyfile(keyFile, "Locallab", "Nlrad_" + index_str, spot.nlrad, spotEdited.nlrad); assignFromKeyfile(keyFile, "Locallab", "Nlgam_" + index_str, spot.nlgam, spotEdited.nlgam); + assignFromKeyfile(keyFile, "Locallab", "Nliter_" + index_str, spot.nliter, spotEdited.nliter); assignFromKeyfile(keyFile, "Locallab", "Sensiden_" + index_str, spot.sensiden, spotEdited.sensiden); assignFromKeyfile(keyFile, "Locallab", "Reparden_" + index_str, spot.reparden, spotEdited.reparden); assignFromKeyfile(keyFile, "Locallab", "Detailthr_" + index_str, spot.detailthr, spotEdited.detailthr); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index f76afffd9..f34083fcf 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1256,6 +1256,22 @@ struct LocallabParams { bool expshadhigh; int complexshadhigh; Glib::ustring shMethod; // std, tone + Glib::ustring ghsMethod; // rgb, lum, sat + Glib::ustring ghsMode; // lin, ghs + double ghs_D; + double ghs_slope; + double ghs_chro; + double ghs_B; + double ghs_SP; + double ghs_LP; + double ghs_HP; + double ghs_LC; + double ghs_MID; + double ghs_BLP; + double ghs_HLP; + bool ghs_smooth; + bool ghs_inv; + int multsh[6]; int highlights; int h_tonalwidth; @@ -1385,6 +1401,7 @@ struct LocallabParams { int nlpat; int nlrad; double nlgam; + int nliter; int sensiden; double reparden; int detailthr; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 586ad5cec..497538d5f 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -854,7 +854,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { AUTOEXP, // Evlocallabangmaskexp AUTOEXP, // Evlocallabstrexp AUTOEXP, // Evlocallabangexp - AUTOEXP, // EvlocallabstrSH + AUTOEXP | M_AUTOEXP, // EvlocallabstrSH AUTOEXP, // EvlocallabangSH AUTOEXP, // Evlocallabstrcol AUTOEXP, // Evlocallabangcol diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index d9e4ed5f9..56e52a60a 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -477,6 +477,12 @@ public: bool linkrgblc; }; + + struct locallabshGHSbw {//To draw GHS S curve + int ghsbw[2]; + double ghsbwvalue[2]; + }; + //select spot settings struct locallabsetLC { int mainf; @@ -506,6 +512,7 @@ public: virtual void minmaxChanged(const std::vector &minmax, int selspot) = 0; virtual void denChanged(const std::vector &denlc, int selspot) = 0; virtual void cieChanged(const std::vector &cielc, int selspot) = 0; + virtual void ghsbwChanged(const std::vector &shghsbw, int selspot) = 0; virtual void maiChanged(const std::vector &csetlc, int selspot) = 0; virtual void sigChanged(const std::vector &ciesig, int selspot) = 0; virtual void ciebefChanged(const std::vector &ciebef, int selspot) = 0; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 79eb1c80b..5d8631738 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1125,6 +1125,7 @@ private: LUTf lmasklocalcurve(65536, LUT_CLIP_OFF); LUTf lmaskexplocalcurve(65536, LUT_CLIP_OFF); LUTf lmaskSHlocalcurve(65536, LUT_CLIP_OFF); + // LUTf ghslocalcurve(65536, LUT_CLIP_OFF); LUTf lmaskviblocalcurve(65536, LUT_CLIP_OFF); LUTf lmasktmlocalcurve(65536, LUT_CLIP_OFF); LUTf lmaskretilocalcurve(65536, LUT_CLIP_OFF); @@ -1222,6 +1223,7 @@ private: const bool localmaskutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve, 1); const bool localmaskexputili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskexpcurve, lmaskexplocalcurve, 1); const bool localmaskSHutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).LmaskSHcurve, lmaskSHlocalcurve, 1); + // const bool localghsutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).ghscurve, ghslocalcurve, 1); const bool localmaskvibutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskvibcurve, lmaskviblocalcurve, 1); const bool localmasktmutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmasktmcurve, lmasktmlocalcurve, 1); const bool localmaskretiutili = CurveFactory::diagonalCurve2Lut(params.locallab.spots.at(sp).Lmaskreticurve, lmaskretilocalcurve, 1); @@ -1294,10 +1296,17 @@ private: float Lnresi = 0.f; float Lhighresi46 = 0.f; float Lnresi46 = 0.f; + int ghsbpwp[2]; + ghsbpwp[0] = 0; + ghsbpwp[1] = 0; + float ghsbpwpvalue[2]; + ghsbpwpvalue[0] = 0.f; + ghsbpwpvalue[1] = 1.f; + float slopeg = 1.f; bool linkrgb = true; // No Locallab mask is shown in exported picture - ipf.Lab_Local(2, sp, shbuffer, labView, labView, reservView.get(), savenormtmView.get(), savenormretiView.get(), lastorigView.get(), fw, fh, 0, 0, fw, fh, 1, locRETgainCurve, locRETtransCurve, + ipf.Lab_Local(2, sp, shbuffer, labView, labView, reservView.get(), savenormtmView.get(), savenormretiView.get(), lastorigView.get(), fw, fh, 0, 0, fw, fh, fw, fh, fw, fh, 1, locRETgainCurve, locRETtransCurve, lllocalcurve, locallutili, cllocalcurve, localclutili, lclocalcurve, locallcutili, @@ -1306,6 +1315,7 @@ private: lmasklocalcurve, localmaskutili, lmaskexplocalcurve, localmaskexputili, lmaskSHlocalcurve, localmaskSHutili, + // ghslocalcurve, localghsutili, lmaskviblocalcurve, localmaskvibutili, lmasktmlocalcurve, localmasktmutili, lmaskretilocalcurve, localmaskretiutili, @@ -1351,8 +1361,8 @@ private: huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, - highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46, slopeg, linkrgb - ); + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46, slopeg, linkrgb, + ghsbpwp, ghsbpwpvalue); if (sp + 1u < params.locallab.spots.size()) { // do not copy for last spot as it is not needed anymore diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 88e874fb6..585d900eb 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -647,7 +647,7 @@ void ColorToning::read (const ProcParams* pp, const ParamsEdited* pedited) lastLumamode = pp->colorToning.lumamode; - labgrid->setParams(pp->colorToning.labgridALow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBLow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridAHigh / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBHigh / ColorToningParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0,false); + labgrid->setParams(pp->colorToning.labgridALow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBLow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridAHigh / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBHigh / ColorToningParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0, false); if (pedited && !pedited->colorToning.method) { method->set_active (7); diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 6bc328c22..c301fb3df 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -121,6 +121,7 @@ ControlSpotPanel::ControlSpotPanel(): EvLocallabavoidgamutMethod = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GAMUTMUNSEL"); EvLocallabavoidnegative = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_AVOIDNEGATIVE"); const bool showtooltip = options.showtooltip; + // pack_start(*hishow_); Gtk::Box* const ctboxprevmethod = Gtk::manage(new Gtk::Box()); @@ -390,8 +391,6 @@ ControlSpotPanel::ControlSpotPanel(): artifBox->pack_start(*balan_); artifBox->pack_start(*balanh_); artifBox->pack_start(*colorde_); -// artifBox->pack_start(*preview_); -// artifBox->pack_start(*colorscope_); expShapeDetect_->add(*artifBox, false); pack_start(*expShapeDetect_, false, false); // ToolParamBlock* const artifBox2 = Gtk::manage(new ToolParamBlock()); @@ -868,10 +867,13 @@ void ControlSpotPanel::load_ControlSpot_param() feather_->setValue((double)row[spots_.feather]); struc_->setValue((double)row[spots_.struc]); thresh_->setValue((double)row[spots_.thresh]); - iter_->setValue((double)row[spots_.iter]); + + iter_->setValue((double)row[spots_.iter]); balan_->setValue((double)row[spots_.balan]); balanh_->setValue((double)row[spots_.balanh]); colorde_->setValue((double)row[spots_.colorde]); + + colorscope_->setValue((double)row[spots_.colorscope]); avoidrad_->setValue((double)row[spots_.avoidrad]); hishow_->set_active(row[spots_.hishow]); @@ -2910,12 +2912,12 @@ void ControlSpotPanel::deleteControlSpot(const int index) } //new function linked to Global and options -void ControlSpotPanel::updateguiset(int spottype, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie) +void ControlSpotPanel::updateguiset(int spottype, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool isci) { { //with this function we can 1) activate Settings SpotMethod // also if need GUI for mask , todo... idle_register.add( - [this, spottype, iscolor, issh , isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, iscie]() -> bool { + [this, spottype, iscolor, issh , isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, isci]() -> bool { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected // Update GUI fullimage or main @@ -2924,7 +2926,7 @@ void ControlSpotPanel::updateguiset(int spottype, bool iscolor, bool issh, bool spotMethodChanged(); } - if((iscolor || issh || isvib || isexpos || istom || iscont || islog || ismas || iscie) + if((iscolor || issh || isvib || isexpos || istom || iscont || islog || ismas || isci) && !issharp && !issoft && !isret && !isblur & !iscbdl) { preview_->hide(); } else if (issoft || isblur || isret || issharp || iscbdl) { diff --git a/rtgui/controlspotpanel.h b/rtgui/controlspotpanel.h index 7ebc2648b..c4d7cca2b 100644 --- a/rtgui/controlspotpanel.h +++ b/rtgui/controlspotpanel.h @@ -226,7 +226,7 @@ public: /** * upadte function to work with Preferences and spotMethod */ - void updateguiset(int spottype, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie); + void updateguiset(int spottype, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool isci); void updateguiscopeset(int scope); private: diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 260a1aaab..ecd48082e 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -89,7 +89,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu ipDialog = Gtk::manage(new MyFileChooserButton(M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); ipDialog->set_tooltip_text(M("TP_ICM_INPUTCUSTOM_TOOLTIP")); bindCurrentFolder(*ipDialog, options.lastIccDir); - labgridcie = Gtk::manage(new LabGrid(EvICMLabGridciexy, M("TP_ICM_LABGRID_CIEXY"), true, true, true)); + labgridcie = Gtk::manage(new LabGrid(EvICMLabGridciexy, M("TP_ICM_LABGRID_CIEXY"), true, true, false, true)); // ------------------------------- Input profile @@ -828,7 +828,7 @@ void ICMPanel::iprimChanged (float r_x, float r_y, float b_x, float b_y, float g [this]() -> bool { disableListener(); - labgridcie->setParams(nextrx, nextry, nextbx, nextby, nextgx, nextgy, nextwx, nextwy, nextmx, nextmy, false); + labgridcie->setParams(nextrx, nextry, nextbx, nextby, nextgx, nextgy, nextwx, nextwy, nextmx, nextmy, false); enableListener(); return false; } @@ -1467,6 +1467,8 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) pp->icm.workingProfile = wProfNames->get_active_text(); pp->icm.dcpIlluminant = rtengine::max(dcpIll->get_active_row_number(), 0); + + labgridcie->getParams(pp->icm.labgridcieALow, pp->icm.labgridcieBLow, pp->icm.labgridcieAHigh, pp->icm.labgridcieBHigh, pp->icm.labgridcieGx, pp->icm.labgridcieGy, pp->icm.labgridcieWx, pp->icm.labgridcieWy, pp->icm.labgridcieMx, pp->icm.labgridcieMy); if (oProfNames->get_active_text() == M("TP_ICM_NOICM")) { @@ -1596,6 +1598,8 @@ void ICMPanel::setDefaults(const ProcParams* defParams, const ParamsEdited* pedi shiftx->setDefault(defParams->icm.shiftx); shifty->setDefault(defParams->icm.shifty); preser->setDefault(defParams->icm.preser); + + labgridcie->setDefault(defParams->icm.labgridcieALow, defParams->icm.labgridcieBLow , defParams->icm.labgridcieAHigh, defParams->icm.labgridcieBHigh, defParams->icm.labgridcieGx, defParams->icm.labgridcieGy, defParams->icm.labgridcieWx, defParams->icm.labgridcieWy, defParams->icm.labgridcieMx, defParams->icm.labgridcieMy); if (pedited) { diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index 135ecedfe..36e558a84 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -4,7 +4,7 @@ * * Copyright (c) 2017 Alberto Griggio * - * Copyright (c) 2021 Jacques Desmis for CIE xy graph + * Copyright (c) 2021 / 2024 Jacques Desmis for CIE xy graph and GHS curve * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,6 +52,11 @@ using rtengine::Color; // LabGridArea //----------------------------------------------------------------------------- +bool LabGridArea::FunctionParams::is_valid() const +{ + return x_min < x_max && y_min < y_max; +} + bool LabGridArea::notifyListener() { if (listener) { @@ -60,9 +65,9 @@ bool LabGridArea::notifyListener() { return int(v * 1000) / 1000.f; }; - if (! ciexy_enabled){ + if (! ciexy_enabled && !ghs_enabled){ listener->panelChanged(evt, Glib::ustring::compose(evtMsg, round(high_a), round(high_b), round(low_a), round(low_b))); - } else { + } else if (ciexy_enabled) { float high_a1 = 0.55f * (high_a + 1.f) - 0.1f; float high_b1 = 0.55f * (high_b + 1.f) - 0.1f; float low_a1 = 0.55f * (low_a + 1.f) - 0.1f; @@ -76,17 +81,19 @@ bool LabGridArea::notifyListener() } -LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy, bool mous): +LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy, bool ghs, bool mous): Gtk::DrawingArea(), evt(evt), evtMsg(msg), litPoint(NONE), - low_a(0.f), high_a(0.f), low_b(0.f), high_b(0.f), gre_x(0.f), gre_y(0.f), whi_x(0.f), whi_y(0.f), me_x(0.f), me_y(0.f),//these variables are used as xy in Ciexy - no change labels + low_a(0.f), high_a(0.f), low_b(0.f), high_b(0.f), gre_x(0.f), gre_y(0.f), whi_x(0.f), whi_y(0.f), me_x(0.f), me_y(0.f), + defaultLow_a(0.f), defaultHigh_a(0.f), defaultLow_b(0.f), defaultHigh_b(0.f), defaultgre_x(0.f), defaultgre_y(0.f), defaultwhi_x(0.f), defaultwhi_y(0.f), defaultme_x(0.f), defaultme_y(0.f), listener(nullptr), edited(false), isDragged(false), low_enabled(enable_low), ciexy_enabled(ciexy), + ghs_enabled(ghs), mous_enabled(mous) @@ -98,6 +105,7 @@ LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool } void LabGridArea::getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy, double &mx, double &my) const + { la = low_a; ha = high_a; @@ -109,11 +117,11 @@ void LabGridArea::getParams(double &la, double &lb, double &ha, double &hb, doub wy = whi_y; mx = me_x; my = me_y; - // printf("la=%f ha=%f lb=%f hb=%f gx=%f gy=%f\n", la, ha, lb, hb, gx, gy); } void LabGridArea::setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify) + { const double lo = -1.0; const double hi = 1.0; @@ -127,14 +135,21 @@ void LabGridArea::setParams(double la, double lb, double ha, double hb, double g whi_y = rtengine::LIM(wy, lo, hi); me_x = rtengine::LIM(mx, lo, hi); me_y = rtengine::LIM(my, lo, hi); - + queue_draw(); if (notify) { notifyListener(); } } +void LabGridArea::setFunctionParams(const FunctionParams ¶ms) +{ + function_params = params; + queue_draw(); +} + void LabGridArea::setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my) + { defaultLow_a = la; defaultLow_b = lb; @@ -154,7 +169,6 @@ void LabGridArea::reset(bool toInitial) if (toInitial) { setParams(defaultLow_a, defaultLow_b, defaultHigh_a, defaultHigh_b, defaultgre_x, defaultgre_y, defaultwhi_x, defaultwhi_y, defaultme_x, defaultme_y, true); } else { - // printf("RESET \n"); setParams(0., 0., 0., 0., 0., 0., 0., 0., 0., 0., true); } } @@ -224,7 +238,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) cr->translate(0., static_cast(height)); cr->scale(1., -1.); - if (! ciexy_enabled) {//draw cells for Labgrid + if (! ciexy_enabled && !ghs_enabled) {//draw cells for general Labgrid const int cells = 8; const float step = 12000.f / static_cast(cells/2); const double cellW = static_cast(width) / static_cast(cells); @@ -257,7 +271,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) cellYMin = cellYMax; cellYMax = std::floor(cellH * static_cast(j+2) + 0.01); } - } else {//cells for CIE xy + } else if (ciexy_enabled) {//cells for CIE xy in SE and Abstract profile const int cells = 600; const float step = 1.f / static_cast(cells); const double cellW = static_cast(width) / static_cast(cells); @@ -326,6 +340,11 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) cellYMin = cellYMax; cellYMax = std::floor(cellH * static_cast(j+2) + 0.001); } + } else if (ghs_enabled) {//cells for GHS and simulation GHS + constexpr double value = 0.7; + cr->set_source_rgb(value, value, value); + cr->rectangle( 0., 0., width, height); + cr->fill(); } // Drawing the connection line @@ -342,20 +361,68 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) double mex = .5 * (static_cast(width) + static_cast(width) * me_x); double mey = .5 * (static_cast(height) + static_cast(height) * me_y); cr->set_line_width(1.5); + if (ciexy_enabled) { mex = .5 * (width + width * me_x); mey = .5 * (height + height * me_y); + } cr->set_source_rgb(0.6, 0.6, 0.6); - cr->move_to(loa, lob); - cr->line_to(hia, hib); + if (!ghs_enabled) { + cr->move_to(loa, lob); + cr->line_to(hia, hib); + } if (ciexy_enabled) { cr->move_to(loa, lob); cr->line_to(grx, gry); cr->move_to(grx, gry); cr->line_to(hia, hib); + } else if (ghs_enabled) { + if (function_params.is_valid()) { + constexpr double line_width = 3.; + cr->set_line_width(line_width); + cr->set_source_rgb(0.2, 0.2, 0.2); + + const int curve_segment_count = std::max(1, function_params.resolution_function(width)); + + std::vector curve(curve_segment_count + 1); + + // Calculate y-values. + const double x_range = function_params.x_max - function_params.x_min; + const double y_range = function_params.y_max - function_params.y_min; + const double y_scale = height / y_range; + for (int i = 0; i <= curve_segment_count; ++i) { + const double x = function_params.x_min + x_range / curve_segment_count * i; + curve[i] = rtengine::LIM(y_scale * (function_params.function(x) - function_params.y_min), 0.0, height); + } + + // Plot curve. + const double dx = static_cast(width) / curve_segment_count; + for (int i = 0; i < curve_segment_count; ++i) { + const double x0 = dx * i; + const double x1 = x0 + dx; + const double y0 = curve[i]; + const double y1 = curve[i + 1]; + cr->move_to(x0, y0); + cr->line_to(x1, y1); + } + } } cr->stroke(); + if(ghs_enabled) {//only 10 * 10 squares + cr->set_line_width(0.2); + cr->set_source_rgb(0.1, 0.1, 0.1); + //draw horiz and vertical lines + for(int i = 0; i < 10; i++) { + cr->move_to(0.1 * static_cast(i * width), 0.); + cr->line_to(0.1 * static_cast(i * width), static_cast(height)); + } + for(int i = 0; i < 10; i++) { + cr->move_to(0., 0.1 * static_cast(i * height)); + cr->line_to(static_cast(width), 0.1 * static_cast(i * height)); + } - if (ciexy_enabled) { + cr->stroke(); + + } else if (ciexy_enabled) {//for CIExy cr->set_line_width(0.2); cr->set_source_rgb(0.1, 0.1, 0.1); //draw horiz and vertical lines @@ -397,33 +464,33 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) cr->stroke(); } - + if(!ghs_enabled) {//no points with GHS // Drawing points - if (low_enabled) { - cr->set_source_rgb(0.1, 0.1, 0.1);//black for red in Ciexy - if (litPoint == LOW) { - cr->arc(loa, lob, 5., 0., 2. * rtengine::RT_PI); - } else { - cr->arc(loa, lob, 3., 0., 2. * rtengine::RT_PI); + if (low_enabled) { + cr->set_source_rgb(0.1, 0.1, 0.1);//black for red in Ciexy + if (litPoint == LOW) { + cr->arc(loa, lob, 5., 0., 2. * rtengine::RT_PI); + } else { + cr->arc(loa, lob, 3., 0., 2. * rtengine::RT_PI); + } + cr->fill(); } - cr->fill(); - } - if (ciexy_enabled) { - cr->set_source_rgb(0.5, 0.5, 0.5);//gray for green - if (litPoint == GRE) { - cr->arc(grx, gry, 5., 0., 2. * rtengine::RT_PI); - } else { - cr->arc(grx, gry, 3., 0., 2. * rtengine::RT_PI); + if (ciexy_enabled) { + cr->set_source_rgb(0.5, 0.5, 0.5);//gray for green + if (litPoint == GRE) { + cr->arc(grx, gry, 5., 0., 2. * rtengine::RT_PI); + } else { + cr->arc(grx, gry, 3., 0., 2. * rtengine::RT_PI); + } + cr->fill(); } - cr->fill(); - } - if (ciexy_enabled) {//White Point - cr->set_source_rgb(1., 1., 1.);//White - cr->arc(whx, why, 3., 0., 2. * rtengine::RT_PI); - cr->fill(); - } + if (ciexy_enabled) {//White Point + cr->set_source_rgb(1., 1., 1.);//White + cr->arc(whx, why, 3., 0., 2. * rtengine::RT_PI); + cr->fill(); + } if (ciexy_enabled) {//Dominant cr->set_source_rgb(0.3, 0.4, 0.3); @@ -431,13 +498,14 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) cr->fill(); } - cr->set_source_rgb(0.9, 0.9, 0.9);//white for blue en Ciexy - if (litPoint == HIGH) { - cr->arc(hia, hib, 5., 0., 2. * rtengine::RT_PI); - } else { - cr->arc(hia, hib, 3., 0., 2. * rtengine::RT_PI); - } - cr->fill(); + cr->set_source_rgb(0.9, 0.9, 0.9);//white for blue en Ciexy + if (litPoint == HIGH) { + cr->arc(hia, hib, 5., 0., 2. * rtengine::RT_PI); + } else { + cr->arc(hia, hib, 3., 0., 2. * rtengine::RT_PI); + } + cr->fill(); +} return false; } @@ -446,7 +514,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) bool LabGridArea::on_button_press_event(GdkEventButton *event) { if (event->button == 1 && mous_enabled) { - if (!ciexy_enabled) { + if (!ciexy_enabled && !ghs_enabled) { if (event->type == GDK_2BUTTON_PRESS) { switch (litPoint) { case NONE: @@ -547,7 +615,7 @@ bool LabGridArea::on_motion_notify_event(GdkEventMotion *event) litPoint = LOW; } else if (disthi < thrs * thrs && disthi <= distlo) { litPoint = HIGH; - } else if (ciexy_enabled && distgxy < thrs * thrs && distgxy <= distlo) { + } else if (ciexy_enabled && !ghs_enabled && distgxy < thrs * thrs && distgxy <= distlo) { litPoint = GRE; } if ((oldLitPoint == NONE && litPoint != NONE) || (oldLitPoint != NONE && litPoint == NONE)) { @@ -595,6 +663,11 @@ bool LabGridArea::ciexyEnabled() const return ciexy_enabled; } +bool LabGridArea::ghsEnabled() const +{ + return ghs_enabled; +} + void LabGridArea::setLowEnabled(bool yes) { if (low_enabled != yes) { @@ -611,6 +684,14 @@ void LabGridArea::setciexyEnabled(bool yes) } } +void LabGridArea::setghsEnabled(bool yes) +{ + if (ghs_enabled != yes) { + ghs_enabled = yes; + queue_draw(); + } +} + void LabGridArea::setmousEnabled(bool yes) { if (mous_enabled != yes) { @@ -624,12 +705,12 @@ void LabGridArea::setmousEnabled(bool yes) // LabGrid //----------------------------------------------------------------------------- -LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy, bool mous): - grid(evt, msg, enable_low, ciexy, mous) +LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy, bool ghs, bool mous): + grid(evt, msg, enable_low, ciexy, ghs, mous) { Gtk::Button *reset = Gtk::manage(new Gtk::Button()); reset->set_tooltip_markup(M("ADJUSTER_RESET_TO_DEFAULT")); - if(!ciexy) {//disabled for Cie xy + if(!ciexy || !ghs) {//disabled for Cie xy and GHS reset->add(*Gtk::manage(new RTImage("undo-small", Gtk::ICON_SIZE_BUTTON))); } reset->signal_button_release_event().connect(sigc::mem_fun(*this, &LabGrid::resetPressed)); @@ -641,7 +722,9 @@ LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_ reset->set_size_request(-1, 20); pack_start(grid, true, true, true); - pack_start(*reset, false, false); + if(!ghs) {//disable reset when GHS + pack_start(*reset, false, false); + } show_all_children(); } diff --git a/rtgui/labgrid.h b/rtgui/labgrid.h index 9756af626..f6d5907c3 100644 --- a/rtgui/labgrid.h +++ b/rtgui/labgrid.h @@ -3,7 +3,7 @@ * This file is part of RawTherapee. * * Copyright (c) 2017 Alberto Griggio - * + * adapted for Rawtherapee J.Desmis december 2024 * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -39,11 +39,55 @@ #pragma once #include + +#include "rtengine/improcfun.h" + #include "eventmapper.h" #include "toolpanel.h" class LabGridArea final : public Gtk::DrawingArea { +public: + struct FunctionParams { + using Function = std::function; + using ResolutionFunction = std::function; + + /** x-value of the left side. */ + double x_min; + /** x-value of the right side. */ + double x_max; + /** y-value of the left side. */ + double y_min; + /** y-value of the right side. */ + double y_max; + /** + * The function itself, which takes an x-value and returns the y-value. + */ + Function function; + /** + * A function returning the resolution of the plot. + * + * It takes the width of the plot, in pixels, and returns the number of + * line segments that should be used to plot the function. + */ + ResolutionFunction resolution_function{[](int width) { return width; }}; + + FunctionParams() = default; + FunctionParams(double x_min, double x_max, double y_min, double y_max, + const Function &function, + const ResolutionFunction & resolution_function) : + x_min(x_min), + x_max(x_max), + y_min(y_min), + y_max(y_max), + function(function), + resolution_function(resolution_function) + { + } + + bool is_valid() const; + }; + private: rtengine::ProcEvent evt; Glib::ustring evtMsg; @@ -60,6 +104,8 @@ private: double whi_y; double me_x; double me_y; + FunctionParams function_params; + double defaultLow_a; double defaultHigh_a; double defaultLow_b; @@ -79,16 +125,18 @@ private: bool low_enabled; bool ciexy_enabled; + bool ghs_enabled; bool mous_enabled; bool notifyListener(); void getLitPoint(); public: - LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false, bool mous=false); + LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false, bool ghs=false, bool mous=false); void getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy, double &mx, double &my) const; - void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify); + void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify); + void setFunctionParams(const FunctionParams ¶ms); void setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my); void setEdited(bool yes); bool getEdited() const; @@ -99,9 +147,11 @@ public: void setLowEnabled(bool yes); bool ciexyEnabled() const; void setciexyEnabled(bool yes); + bool ghsEnabled() const; + void setghsEnabled(bool yes); bool mousEnabled() const; void setmousEnabled(bool yes); - + bool on_draw(const ::Cairo::RefPtr &cr) override; void on_style_updated () override; bool on_button_press_event(GdkEventButton *event) override; @@ -120,11 +170,18 @@ private: bool resetPressed(GdkEventButton *event); public: - LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false, bool mous=true); + LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false, bool ghs=false, bool mous=true); - void getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy, double &mx, double &my) const { return grid.getParams(la, lb, ha, hb, gx, gy, wx, wy, mx, my); } - void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify) { grid.setParams(la, lb, ha, hb, gx, gy, wx, wy, mx, my, notify); } - void setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my) { grid.setDefault(la, lb, ha, hb, gx, gy, wx, wy, mx, my); } + void getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy, double &mx, double &my) + const { return grid.getParams(la, lb, ha, hb, gx, gy, wx, wy, mx, my); } + void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify) + { grid.setParams(la, lb, ha, hb, gx, gy, wx, wy, mx, my, notify); } + void setFunctionParams(const LabGridArea::FunctionParams ¶ms) + { + grid.setFunctionParams(params); + } + void setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my) + { grid.setDefault(la, lb, ha, hb, gx, gy, wx, wy, mx, my); } void setEdited(bool yes) { grid.setEdited(yes); } bool getEdited() const { return grid.getEdited(); } void reset(bool toInitial) { grid.reset(toInitial); } @@ -133,8 +190,9 @@ public: void setLowEnabled(bool yes) { grid.setLowEnabled(yes); } bool ciexyEnabled() const { return grid.ciexyEnabled(); } void setciexyEnabled(bool yes) { grid.setciexyEnabled(yes); } + bool ghsEnabled() const { return grid.ghsEnabled(); } + void setghsEnabled(bool yes) { grid.setghsEnabled(yes); } bool mousEnabled() const { return grid.mousEnabled(); } void setmousEnabled(bool yes) { grid.setmousEnabled(yes); } }; - diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 2fe7dfb53..d533727a0 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -152,7 +152,6 @@ Locallab::Locallab(): // Tool list widget toollist(Gtk::manage(new LocallabToolList())) - // expcie(Gtk::manage(new Locallabcie())), // Other widgets //resetshowButton(Gtk::manage(new Gtk::Button(M("TP_LOCALLAB_RESETSHOW")))) { @@ -247,6 +246,7 @@ void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdit // Update Locallab activation state setEnabled(pp->locallab.enabled); + // const int showsettings = options.complexity; // Transmit Locallab activation state to Locallab tools for (auto tool : locallabTools) { @@ -266,6 +266,7 @@ void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdit ControlSpotPanel::SpotRow r; for (int i = 0; i < (int)pp->locallab.spots.size(); i++) { + r.name = pp->locallab.spots.at(i).name; r.isvisible = pp->locallab.spots.at(i).isvisible; @@ -1143,7 +1144,7 @@ void Locallab::minmaxChanged(const std::vector &minmax, int const double cdmin = retiMinMax.at(selspot).cdmin; const double mini = retiMinMax.at(selspot).mini; const double maxi = retiMinMax.at(selspot).maxi; - const double Tmean = retiMinMax.at(selspot).Tmean; + const double Tmean = retiMinMax.at(selspot).Tmean; const double Tsigma = retiMinMax.at(selspot).Tsigma; const double Tmin = retiMinMax.at(selspot).Tmin; const double Tmax = retiMinMax.at(selspot).Tmax; @@ -1163,7 +1164,7 @@ void Locallab::denChanged(const std::vector &denlc, int selsp const double nres = denoiselc.at(selspot).nres; const double highres46 = denoiselc.at(selspot).highres46; const double nres46 = denoiselc.at(selspot).nres46; - const double Lhighres = denoiselc.at(selspot).Lhighres; + const double Lhighres = denoiselc.at(selspot).Lhighres; const double Lnres = denoiselc.at(selspot).Lnres; const double Lhighres46 = denoiselc.at(selspot).Lhighres46; const double Lnres46 = denoiselc.at(selspot).Lnres46; @@ -1208,72 +1209,7 @@ void Locallab::scopeChangedset(int scope, int selspot, bool enab) } } -/* -//main new fonction global to hide show and activated or not some functions - inverse, scope... -void Locallab::mainChanged(int spottype, int selspot, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie ) -{ - - if(iscolor) { - expcolor.updateguicolor(spottype); - } - - if(issh) { - expshadhigh.updateguishad(spottype); - } - - if(isvib) { - expvibrance.updateguivib(spottype); - } - - if(isexpos) { - expexpose.updateguiexpos(spottype); - } - - if(issoft) { - expsoft.updateguisoft(spottype); - } - - if(isblur) { - expblur.updateguiblur(spottype); - } - - if(istom) { - exptonemap.updateguitone(spottype); - } - - if(isret) { - expreti.updateguireti(spottype); - } - - if(issharp) { - expsharp.updateguisharp(spottype); - } - - if(iscont) { - expcontrast.updateguicont(spottype); - } - - if(iscbdl) { - expcbdl.updateguicbdl(spottype); - } - - if(islog) { - explog.updateguilog(spottype); - } - - if(ismas) { - expmask.updateguimask(spottype); - } - - if(iscie) { - expcie.updateguicie(spottype); - } - - expsettings->updateguiset(spottype, iscolor, issh, isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, iscie); - -} -*/ void Locallab::sigChanged(const std::vector &ciesig, int selspot) { cie_sig = ciesig; @@ -1329,7 +1265,7 @@ void Locallab::maiChanged(const std::vector &setlc, int selspot) const bool iscbdl = set_lc.at(selspot).iscbd; const bool islog = set_lc.at(selspot).islo; const bool ismas = set_lc.at(selspot).isma; - const bool iscie = set_lc.at(selspot).isci; + const bool isci = set_lc.at(selspot).isci; if(iscolor) { expcolor.updateguicolor(spottype); @@ -1383,18 +1319,35 @@ void Locallab::maiChanged(const std::vector &setlc, int selspot) expmask.updateguimask(spottype); } - if(iscie) { + if(isci) { expcie.updateguicie(spottype); } - expsettings->updateguiset(spottype, iscolor, issh, isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, iscie); + expsettings->updateguiset(spottype, iscolor, issh, isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, isci); } } +void Locallab::ghsbwChanged(const std::vector &shghsbw, int selspot) +{ + sh_ghsbw = shghsbw; + int bw[2] = {0, 1}; + double bwvalue[2] = {0., 1.}; + + if (selspot < (int) sh_ghsbw.size()) { + for(int i=0; i < 2; i++) { + bw[i] = sh_ghsbw.at(selspot).ghsbw[i]; + bwvalue[i] = sh_ghsbw.at(selspot).ghsbwvalue[i]; + } + + expshadhigh.updateghsbw(bw[0], bw[1], bwvalue[0], bwvalue[1]); + } + +} void Locallab::cieChanged(const std::vector &cielc, int selspot) { // Saving transmitted min/max data cie_lc = cielc; + //Update Locallab Denoise tool lum chro if (selspot < (int) cie_lc.size()) { @@ -1402,7 +1355,7 @@ void Locallab::cieChanged(const std::vector &cielc, int selspot) const double r2 = cie_lc.at(selspot).redylc; const double g1 = cie_lc.at(selspot).grexlc; const double g2 = cie_lc.at(selspot).greylc; - const double b1 = cie_lc.at(selspot).bluxlc; + const double b1 = cie_lc.at(selspot).bluxlc; const double b2 = cie_lc.at(selspot).bluylc; const double w1 = cie_lc.at(selspot).wxlc; const double w2 = cie_lc.at(selspot).wylc; diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 0add444ac..1a1ebd606 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -129,11 +129,12 @@ private: // Locallab tools mask background management data std::vector denoiselc; - std::vector cie_bef; std::vector cie_lc; + std::vector sh_ghsbw; + std::vector set_lc; std::vector cie_sig; @@ -161,7 +162,7 @@ public: void minmaxChanged(const std::vector &minmax, int selspot) override; // new functions for global - normal use -// void mainChanged(int spottype, int selspot, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie)override; +// void mainChanged(int spottype, int selspot, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool isci)override; void scopeChangedcol(int scope, int selspot, bool enab)override; void scopeChangedsh(int scope, int selspot, bool enab)override; void scopeChangedvib(int scope, int selspot, bool enab)override; @@ -176,6 +177,9 @@ public: // Locallab CIE tool primaries function void cieChanged(const std::vector &cielc, int selspot) override; + // Locallab SH GHS tool Black point & White point GHS function + void ghsbwChanged(const std::vector &shghsbw, int selspot) override; + // Locallab Log Encoding and Cam16 autocompute function void ciebefChanged(const std::vector &ciebef, int selspot) override; diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 522614742..77cf265f6 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -21,6 +21,7 @@ fft * #include "locallabtools.h" #include "options.h" +#include "rtengine/improcfun.h" #include "rtengine/procparams.h" #include "locallab.h" #include "thresholdadjuster.h" @@ -36,6 +37,40 @@ fft * #define MINEXP -1.5 #define MAXEXP 1.5 +namespace +{ + +void update_ghs_curve( + double b, + double d, + double lp, + double sp, + double hp, + bool inverse, + LabGrid &lab_grid) +{ + const rtengine::ImProcFunctions::GHTStrType str_type = + inverse + ? rtengine::ImProcFunctions::GHTStrType::INVERSE + : rtengine::ImProcFunctions::GHTStrType::NORMAL; + const rtengine::ght_compute_params c = rtengine::ImProcFunctions::GHT_setup( + b, + d, + lp, + sp, + hp, + str_type); + const LabGridArea::FunctionParams::Function function = [=](double x) -> double { + return rtengine::ImProcFunctions::GHT(x, b, d, lp, sp, hp, c, str_type); + }; + const LabGridArea::FunctionParams::ResolutionFunction resolution_function = [](int width) -> int { + return std::min(width, 400); + }; + lab_grid.setFunctionParams(LabGridArea::FunctionParams(0.0, 1.0, 0.0, 1.0, function, resolution_function)); +} + +} // namespace + using namespace rtengine; using namespace procparams; @@ -1094,7 +1129,7 @@ sigc::connection *LocallabColor::getPreviewDeltaEButtonConnection() { return &previewcolConn; } - + void LocallabColor::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -1259,7 +1294,7 @@ void LocallabColor::read(const rtengine::procparams::ProcParams* pp, const Param { // Disable all listeners disableListener(); - + nbmaskcol = 0; // Update GUI to selected spot value const int index = pp->locallab.selspot; @@ -1394,7 +1429,7 @@ void LocallabColor::read(const rtengine::procparams::ProcParams* pp, const Param labgridmerg->setParams(0, 0, spot.labgridAHighmerg / LocallabParams::LABGRIDL_CORR_MAX, spot.labgridBHighmerg / LocallabParams::LABGRIDL_CORR_MAX, - 0, 0, 0, 0, 0, 0, false); + 0, 0, 0, 0, 0, 0, false); merlucol->setValue(spot.merlucol); enaColorMask->set_active(spot.enaColorMask); CCmaskshape->setCurve(spot.CCmaskcurve); @@ -2150,9 +2185,9 @@ void LocallabColor::convertParamToSimple() // Set hidden specific GUI widgets in Simple mode to default spot values softradiuscol->setValue(defSpot.softradiuscol); - strcol->setValue(defSpot.strcol); - angcol->setValue(defSpot.angcol); - feathercol->setValue(defSpot.feathercol); + // strcol->setValue(defSpot.strcol); + // angcol->setValue(defSpot.angcol); + // feathercol->setValue(defSpot.feathercol); gamc->setValue(defSpot.gamc); if (defSpot.qualitycurveMethod == "none") { @@ -2201,7 +2236,6 @@ void LocallabColor::updateGUIToMode(const modeType new_type) structcol->hide(); blurcolde->hide(); softradiuscol->hide(); - expgradcol->hide(); expcurvcol->hide(); expmaskcol1->hide(); expmaskcol->hide(); @@ -2249,7 +2283,6 @@ void LocallabColor::updateGUIToMode(const modeType new_type) } if (!invers->get_active()) { // Keep widget hidden when invers is toggled - expgradcol->show(); expmaskcol1->show(); exprecov->show(); gamc->hide(); @@ -2269,7 +2302,6 @@ void LocallabColor::updateGUIToMode(const modeType new_type) if (!invers->get_active()) { // Keep widget hidden when invers is toggled softradiuscol->show(); - expgradcol->show(); exprecov->show(); gamc->show(); } @@ -2579,7 +2611,6 @@ void LocallabColor::updateColorGUI1() if (mode == Expert || mode == Normal) { // Keep widget hidden in Simple mode softradiuscol->show(); - expgradcol->show(); exprecov->show(); expmaskcol1->show(); } @@ -3130,6 +3161,7 @@ void LocallabExposure::updateAdviceTooltips(const bool showTooltips) structexp->set_tooltip_text(M("TP_LOCALLAB_STRUCT_TOOLTIP")); expchroma->set_tooltip_text(M("TP_LOCALLAB_EXPCHROMA_TOOLTIP")); shapeexpos->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP")); + expgradexp->set_tooltip_text(M("TP_LOCALLAB_EXPGRADCOL_TOOLTIP")); strexp->set_tooltip_text(M("TP_LOCALLAB_GRADGEN_TOOLTIP")); expmaskexp->set_tooltip_markup(M("TP_LOCALLAB_MASK_TOOLTIP")); CCmaskexpshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); @@ -3180,6 +3212,8 @@ void LocallabExposure::updateAdviceTooltips(const bool showTooltips) slomaskexp->set_tooltip_text(""); lapmaskexp->set_tooltip_text(""); gamex->set_tooltip_text(""); + expgradexp->set_tooltip_text(""); + } } @@ -3227,7 +3261,7 @@ void LocallabExposure::read(const rtengine::procparams::ProcParams* pp, const Pa { // Disable all listeners disableListener(); - + nbmaskexp = 0; // Update GUI to selected spot value const int index = pp->locallab.selspot; @@ -3833,9 +3867,9 @@ void LocallabExposure::convertParamToSimple() fatanchor->setValue(defSpot.fatanchor); norm->set_active(false); // Set hidden specific GUI widgets in Simple mode to default spot values - strexp->setValue(defSpot.strexp); - angexp->setValue(defSpot.angexp); - featherexp->setValue(defSpot.featherexp); + //strexp->setValue(defSpot.strexp); + //angexp->setValue(defSpot.angexp); + //featherexp->setValue(defSpot.featherexp); softradiusexp->setValue(defSpot.softradiusexp); enaExpMask->set_active(defSpot.enaExpMask); enaExpMaskaft->set_active(defSpot.enaExpMaskaft); @@ -3870,7 +3904,6 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) maskusablee->hide(); maskunusablee->hide(); decaye->hide(); - expmaskexp->hide(); norm->hide(); fatlevel->hide(); fatanchor->hide(); @@ -3906,14 +3939,13 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) exppde->hide(); if (!inversex->get_active()) { // Keep widget hidden when invers is toggled - expgradexp->show(); + // expgradexp->show(); softradiusexp->show(); exprecove->show(); gamex->hide(); blurexpde->show(); } - expmaskexp->show(); decaye->hide(); break; @@ -3933,7 +3965,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) gamex->show(); if (!inversex->get_active()) { // Keep widget hidden when invers is toggled - expgradexp->show(); + //expgradexp->show(); softradiusexp->show(); exprecove->show(); gamex->show(); @@ -3950,7 +3982,6 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) } exppde->show(); - expmaskexp->show(); lapmaskexp->show(); gammaskexp->show(); slomaskexp->show(); @@ -4180,7 +4211,8 @@ void LocallabExposure::updateExposureGUI3() exppde->hide(); structexp->hide(); blurexpde->hide(); - + expgradexp->hide(); + // Manage specific case where expMethod is different from 0 if (expMethod->get_active_row_number() > 0) { expMethodConn.block(true); @@ -4208,7 +4240,7 @@ void LocallabExposure::updateExposureGUI3() if (mode == Normal) { // Keep widgets hidden in Simple mode softradiusexp->show(); - expgradexp->show(); + //expgradexp->show(); exprecove->show(); blurexpde->show(); exppde->hide(); @@ -4216,7 +4248,7 @@ void LocallabExposure::updateExposureGUI3() } if (mode == Expert) { // Keep widgets hidden in Simple mode softradiusexp->show(); - expgradexp->show(); + //expgradexp->show(); exprecove->show(); structexp->show(); blurexpde->show(); @@ -4282,10 +4314,32 @@ LocallabShadow::LocallabShadow(): gamFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GAMFRA")))), gamSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMSH"), 0.25, 15.0, 0.01, 2.4))), sloSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOSH"), 0.0, 500.0, 0.01, 12.92))), + ghsMethod(Gtk::manage(new MyComboBoxText())), + gridFrameghs(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GHS_GHSDIAG")))),// + labgridghs(Gtk::manage(new LabGrid(EvlocallabGridciexy, M("TP_LOCALLAB_GHS_GHSDIAG"), true, false, true, false))), + ghsFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GHSFRA")))), + ghs_D(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_D"), 0., 20.0, 0.001, 0.001))), + Lab_Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GHSLABFRA")))), + ghs_slope(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_SLOPE"), 1.0, 100.0, 0.01, 9.03296))), + ghs_chro(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_CHRO"), -30., 100.0, 0.001, 0.))), + ghs_B(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_B"), -5.0, 15.0, 0.001, 0.0))), + ghs_SP(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_SP"), 0.0, 1.0, 0.00001, 0.015))), + ghs_LP(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_LP"), 0.0, 1.0, 0.00001, 0.0))), + ghs_HP(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_HP"), 0.0, 1.0, 0.00001, 1.0))), + LC_Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GHS_LC_FRAME")))), + ghs_LC(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_LC"), 0.0, 100.0, 0.1, 30.0))), + ghs_MID(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_MID"), -100.0, 100.0, 0.1, 0.0))), + BP_Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GHS_BLACKPOINT_FRAME")))), + ghs_BLP(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_BLP"), -0.2, 1.0, 0.0001, 0.0))), + ghs_HLP(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GHS_HLP"), 0.2002, 5.0, 0.0001, 1.))), + ghsbpwpLabels(Gtk::manage(new Gtk::Label("---"))), + ghsbpwpvalueLabels(Gtk::manage(new Gtk::Label("---"))), + ghs_smooth(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_GHS_SMOOTH")))), + ghs_inv(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_GHS_INV")))), expgradsh(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_EXPGRAD")))), strSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -4., 4., 0.05, 0.))), angSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), - featherSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), + featherSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))),//10. inverssh(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))), expmasksh(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWS")))), showmaskSHMethod(Gtk::manage(new MyComboBoxText())), @@ -4312,7 +4366,21 @@ LocallabShadow::LocallabShadow(): auto m = ProcEventMapper::getInstance(); Evlocallabpreviewsh = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWSH"); EvlocallabfeatherSH = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERSH"); - + EvlocallabghsMethod = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHSMETHOD"); + Evlocallabghs_D = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_D"); + Evlocallabghs_slope = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_SLOPE"); + Evlocallabghs_chro = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_CHRO"); + Evlocallabghs_B = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_B"); + Evlocallabghs_SP = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_SP"); + Evlocallabghs_LP = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_LP"); + Evlocallabghs_HP = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_HP"); + Evlocallabghs_LC = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_LC"); + Evlocallabghs_MID = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_MID"); + Evlocallabghs_HLP = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_HLP"); + Evlocallabghs_BLP = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_BLP"); + Evlocallabghs_smooth = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_SMOOTH"); + Evlocallabghs_inv = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GHS_INV"); + EvlocallabGridghs = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_LABGRIDGHS"); set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -4320,9 +4388,21 @@ LocallabShadow::LocallabShadow(): // Parameter Shadow highlight specific widgets shMethod->append(M("TP_LOCALLAB_SH1")); shMethod->append(M("TP_LOCALLAB_SH2")); - shMethod->set_active(0); + shMethod->append(M("TP_LOCALLAB_SH3")); + shMethod->set_active(3); shMethodConn = shMethod->signal_changed().connect(sigc::mem_fun(*this, &LocallabShadow::shMethodChanged)); + + ghsMethod->append(M("TP_LOCALLAB_GHSRGBLUM")); + ghsMethod->append(M("TP_LOCALLAB_GHSRGBSTD")); + ghsMethod->append(M("TP_LOCALLAB_GHSLAB")); + ghsMethod->append(M("TP_LOCALLAB_GHSLUM")); + ghsMethod->append(M("TP_LOCALLAB_GHSSAT")); + ghsMethod->append(M("TP_LOCALLAB_GHSHUE")); + ghsMethod->set_active(0); + ghsMethodConn = ghsMethod->signal_changed().connect(sigc::mem_fun(*this, &LocallabShadow::ghsMethodChanged)); + ghsMethod->set_tooltip_text(M("TP_LOCALLAB_GHS_METHOD_TOOLTIP")); + for (const auto multiplier : multipliersh) { multiplier->setAdjusterListener(this); } @@ -4357,6 +4437,30 @@ LocallabShadow::LocallabShadow(): sloSH->setAdjusterListener(this); + ghs_D->setAdjusterListener(this); + ghs_slope->setAdjusterListener(this); + ghs_chro->setAdjusterListener(this); + ghs_B->setAdjusterListener(this); + ghs_SP->setAdjusterListener(this); + ghs_LP->setAdjusterListener(this); + ghs_HP->setAdjusterListener(this); + ghs_LC->setAdjusterListener(this); + ghs_MID->setAdjusterListener(this); + ghs_BLP->setAdjusterListener(this); + ghs_HLP->setAdjusterListener(this); + setExpandAlignProperties(ghsbpwpLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + setExpandAlignProperties(ghsbpwpvalueLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + ghs_D->setLogScale(10, 0); + //ghs_B->setLogScale(10, -5); + ghs_slope->setLogScale(10, 1); + ghs_chro->setLogScale(10, -30); + + ghs_SP->setLogScale(10, 0); + ghs_BLP->setLogScale(10, -0.2); + ghs_smoothConn = ghs_smooth->signal_toggled().connect(sigc::mem_fun(*this, &LocallabShadow::ghs_smoothChanged)); + ghs_invConn = ghs_inv->signal_toggled().connect(sigc::mem_fun(*this, &LocallabShadow::ghs_invChanged)); + + setExpandAlignProperties(expgradsh, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); strSH->setAdjusterListener(this); @@ -4434,6 +4538,10 @@ LocallabShadow::LocallabShadow(): fatamountSH->setAdjusterListener(this); fatanchorSH->setAdjusterListener(this); + gridFrameghs->set_label_align(0.025, 0.5); + ToolParamBlock* const gridBox = Gtk::manage(new ToolParamBlock()); + gridBox->pack_start(*labgridghs); + gridFrameghs->add(*gridBox); // Add Shadow highlight specific widgets to GUI pack_start(*reparsh); @@ -4442,6 +4550,41 @@ LocallabShadow::LocallabShadow(): pack_start(*inverssh); pack_start(*shMethod); + pack_start(*ghsMethod); + ghsFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const ghsBox = Gtk::manage(new ToolParamBlock()); + ghsBox->pack_start(*gridFrameghs); + ghsBox->pack_start(*ghs_D); + Lab_Frame->set_label_align(0.025, 0.5); + ToolParamBlock* const LabBox = Gtk::manage(new ToolParamBlock()); + LabBox->pack_start(*ghs_slope); + LabBox->pack_start(*ghs_chro); + Lab_Frame->add(*LabBox); + ghsBox->pack_start(*Lab_Frame); + ghsBox->pack_start(*ghs_B); + ghsBox->pack_start(*ghs_SP); + ghsBox->pack_start(*ghs_LP); + ghsBox->pack_start(*ghs_HP); + + LC_Frame->set_label_align(0.025, 0.5); + ToolParamBlock* const LCBox = Gtk::manage(new ToolParamBlock()); + LCBox->pack_start(*ghs_LC); + LCBox->pack_start(*ghs_MID); + LC_Frame->add(*LCBox); + ghsBox->pack_start(*LC_Frame); + BP_Frame->set_label_align(0.025, 0.5); + ToolParamBlock* const BPBox = Gtk::manage(new ToolParamBlock()); + BPBox->pack_start(*ghs_BLP); + BPBox->pack_start(*ghs_HLP); + BPBox->pack_start(*ghsbpwpLabels); + BPBox->pack_start(*ghsbpwpvalueLabels); + BPBox->pack_start(*ghs_smooth); + BP_Frame->add(*BPBox); + ghsBox->pack_start(*BP_Frame); + ghsBox->pack_start(*ghs_inv); + ghsFrame->add(*ghsBox); + pack_start(*ghsFrame); + for (const auto multiplier : multipliersh) { pack_start(*multiplier); @@ -4472,13 +4615,13 @@ LocallabShadow::LocallabShadow(): gammBox->pack_start(*sloSH); gamFrame->add(*gammBox); pack_start(*gamFrame); + ToolParamBlock* const gradSHBox = Gtk::manage(new ToolParamBlock()); gradSHBox->pack_start(*strSH); gradSHBox->pack_start(*angSH); gradSHBox->pack_start(*featherSH); expgradsh->add(*gradSHBox, false); - pack_start(*expgradsh); -// pack_start(*inverssh); + pack_start(*expgradsh, false, false); ToolParamBlock* const maskSHBox = Gtk::manage(new ToolParamBlock()); maskSHBox->pack_start(*showmaskSHMethod, Gtk::PACK_SHRINK, 4); maskSHBox->pack_start(*showmaskSHMethodinv, Gtk::PACK_SHRINK, 4); @@ -4572,6 +4715,11 @@ void LocallabShadow::updateguishad(int spottype) } else { sensihs->show(); inverssh->show(); + if (shMethod->get_active_row_number() == 2) { + inverssh->hide(); + inverssh->set_active(false); + } + exprecovs->show(); expmasksh->show(); if(!inverssh->get_active()) { @@ -4628,6 +4776,8 @@ void LocallabShadow::updateAdviceTooltips(const bool showTooltips) recothress->set_tooltip_text(M("TP_LOCALLAB_RECOTHRES02_TOOLTIP")); gamSH->set_tooltip_text(M("TP_LOCALLAB_SHTRC_TOOLTIP")); reparsh->set_tooltip_text(M("TP_LOCALLAB_REPARSH_TOOLTIP")); + expgradsh->set_tooltip_text(M("TP_LOCALLAB_EXPGRADCOL_TOOLTIP")); + sloSH->set_tooltip_text(M("TP_LOCALLAB_SHTRC_TOOLTIP")); strSH->set_tooltip_text(M("TP_LOCALLAB_GRADGEN_TOOLTIP")); exprecovs->set_tooltip_markup(M("TP_LOCALLAB_MASKRESH_TOOLTIP")); @@ -4645,6 +4795,7 @@ void LocallabShadow::updateAdviceTooltips(const bool showTooltips) chromaskSH->set_tooltip_text(M("TP_LOCALLAB_CHROMASK_TOOLTIP")); slomaskSH->set_tooltip_text(M("TP_LOCALLAB_SLOMASK_TOOLTIP")); lapmaskSH->set_tooltip_text(M("TP_LOCALLAB_LAPRAD1_TOOLTIP")); + /* highlights->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); h_tonalwidth->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); @@ -4660,7 +4811,22 @@ void LocallabShadow::updateAdviceTooltips(const bool showTooltips) decays->set_tooltip_text(M("TP_LOCALLAB_MASKDECAY_TOOLTIP")); lowthress->set_tooltip_text(M("TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP")); higthress->set_tooltip_text(M("TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP")); - + ghs_D->set_tooltip_text(M("TP_LOCALLAB_GHS_D_TOOLTIP")); + ghs_slope->set_tooltip_text(M("TP_LOCALLAB_GHS_SLOPE_TOOLTIP")); + ghs_chro->set_tooltip_text(M("TP_LOCALLAB_GHS_CHRO_TOOLTIP")); + ghs_B->set_tooltip_text(M("TP_LOCALLAB_GHS_B_TOOLTIP")); + ghs_SP->set_tooltip_text(M("TP_LOCALLAB_GHS_SP_TOOLTIP")); + ghs_LP->set_tooltip_text(M("TP_LOCALLAB_GHS_LP_TOOLTIP")); + ghs_HP->set_tooltip_text(M("TP_LOCALLAB_GHS_HP_TOOLTIP")); + ghs_LC->set_tooltip_text(M("TP_LOCALLAB_GHS_LC_TOOLTIP")); + ghs_MID->set_tooltip_text(M("TP_LOCALLAB_GHS_MID_TOOLTIP")); + ghs_BLP->set_tooltip_text(M("TP_LOCALLAB_GHS_BLP_TOOLTIP")); + ghs_HLP->set_tooltip_text(M("TP_LOCALLAB_GHS_HLP_TOOLTIP")); + ghs_smooth->set_tooltip_text(M("TP_LOCALLAB_GHS_SMOOTH_TOOLTIP")); + ghs_inv->set_tooltip_text(M("TP_LOCALLAB_GHS_INV_TOOLTIP")); + BP_Frame->set_tooltip_text(M("TP_LOCALLAB_GHS_BPFRAME_TOOLTIP")); + ghsFrame->set_tooltip_text(M("TP_LOCALLAB_GHS_METHOD_TOOLTIP")); + gridFrameghs->set_tooltip_text(M("TP_LOCALLAB_GHS_SIMUL_TOOLTIP")); } else { exp->set_tooltip_text(""); @@ -4695,7 +4861,23 @@ void LocallabShadow::updateAdviceTooltips(const bool showTooltips) decays->set_tooltip_text(""); lowthress->set_tooltip_text(""); higthress->set_tooltip_text(""); - + ghs_D->set_tooltip_text(""); + ghs_slope->set_tooltip_text(""); + ghs_chro->set_tooltip_text(""); + ghs_B->set_tooltip_text(""); + ghs_SP->set_tooltip_text(""); + ghs_LP->set_tooltip_text(""); + ghs_HP->set_tooltip_text(""); + ghs_LC->set_tooltip_text(""); + ghs_MID->set_tooltip_text(""); + ghs_BLP->set_tooltip_text(""); + ghs_HLP->set_tooltip_text(""); + ghs_smooth->set_tooltip_text(""); + ghs_inv->set_tooltip_text(""); + BP_Frame->set_tooltip_text(""); + ghsFrame->set_tooltip_text(""); + gridFrameghs->set_tooltip_text(""); + expgradsh->set_tooltip_text(""); } } @@ -4711,7 +4893,10 @@ void LocallabShadow::disableListener() LocallabTool::disableListener(); shMethodConn.block(true); + ghsMethodConn.block(true); inversshConn.block(true); + ghs_smoothConn.block(true); + ghs_invConn.block(true); showmaskSHMethodConn.block(true); showmaskSHMethodConninv.block(true); enaSHMaskConn.block(true); @@ -4722,6 +4907,9 @@ void LocallabShadow::enableListener() LocallabTool::enableListener(); shMethodConn.block(false); + ghsMethodConn.block(false); + ghs_smoothConn.block(false); + ghs_invConn.block(false); inversshConn.block(false); showmaskSHMethodConn.block(false); showmaskSHMethodConninv.block(false); @@ -4732,7 +4920,7 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para { // Disable all listeners disableListener(); - + nbmasksh = 0; // Update GUI to selected spot value const int index = pp->locallab.selspot; @@ -4747,8 +4935,23 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para shMethod->set_active(0); } else if (spot.shMethod == "tone") { shMethod->set_active(1); + } else if (spot.shMethod == "ghs") { + shMethod->set_active(2); } + if (spot.ghsMethod == "rgb") { + ghsMethod->set_active(0); + } else if (spot.ghsMethod == "rgbstd") { + ghsMethod->set_active(1); + } else if (spot.ghsMethod == "llab") { + ghsMethod->set_active(2); + } else if (spot.ghsMethod == "lum") { + ghsMethod->set_active(3); + } else if (spot.ghsMethod == "sat") { + ghsMethod->set_active(4); + } else if (spot.ghsMethod == "hue") { + ghsMethod->set_active(5); + } for (int i = 0; i < 6; i++) { multipliersh[i]->setValue((double)spot.multsh[i]); } @@ -4757,6 +4960,34 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para higthress->setValue((double)spot.higthress); decays->setValue((double)spot.decays); + ghs_D->setValue((double)spot.ghs_D); + ghs_slope->setValue((double)spot.ghs_slope); + ghs_chro->setValue((double)spot.ghs_chro); + ghs_B->setValue((double)spot.ghs_B); + ghs_SP->setValue((double)spot.ghs_SP); + ghs_LP->setValue((double)spot.ghs_LP); + ghs_HP->setValue((double)spot.ghs_HP); + ghs_LC->setValue((double)spot.ghs_LC); + ghs_MID->setValue((double)spot.ghs_MID); + ghs_BLP->setValue((double)spot.ghs_BLP); + ghs_HLP->setValue((double)spot.ghs_HLP); + + if(ghs_D->getValue() > 0.002 || ghs_D->getValue() == 0.f) { + ghs_BLP->set_sensitive(false); + ghs_HLP->set_sensitive(false); + ghs_LC->set_sensitive(true); + ghs_MID->set_sensitive(true); + } else { + ghs_BLP->set_sensitive(true); + ghs_HLP->set_sensitive(true); + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + if(ghs_D->getValue() == 0.f) { + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + detailSH->setValue((double)spot.detailSH); tePivot->setValue(spot.tePivot); reparsh->setValue(spot.reparsh); @@ -4773,6 +5004,8 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para angSH->setValue(spot.angSH); featherSH->setValue(spot.featherSH); inverssh->set_active(spot.inverssh); + ghs_smooth->set_active(spot.ghs_smooth); + ghs_inv->set_active(spot.ghs_inv); enaSHMask->set_active(spot.enaSHMask); CCmaskSHshape->setCurve(spot.CCmaskSHcurve); LLmaskSHshape->setCurve(spot.LLmaskSHcurve); @@ -4786,8 +5019,17 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para LmaskSHshape->setCurve(spot.LmaskSHcurve); fatamountSH->setValue(spot.fatamountSH); fatanchorSH->setValue(spot.fatanchorSH); + } - + ghsMethodChanged(); + update_ghs_curve( + ghs_B->getValue(), + ghs_D->getValue(), + ghs_LP->getValue(), + ghs_SP->getValue(), + ghs_HP->getValue(), + ghs_inv->get_active(), + *labgridghs); // Enable all listeners enableListener(); @@ -4795,10 +5037,11 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para updateGUIToMode(static_cast(complexity->get_active_row_number())); // Update shadow highlight GUI according to inverssh button state - updateShadowGUI1(); + updateShadowGUImask(); - // Update shadow highlight GUI according to shMethod combobox state - updateShadowGUI2(); + // Update shadow highlight GUI according to shMethod and ghsmethod combobox state + updateShadowGUIshmet(); + updateShadowGUIsym(); // Note: No need to manage pedited as batch mode is deactivated for Locallab } @@ -4818,12 +5061,40 @@ void LocallabShadow::write(rtengine::procparams::ProcParams* pp, ParamsEdited* p spot.shMethod = "std"; } else if (shMethod->get_active_row_number() == 1) { spot.shMethod = "tone"; + } else if (shMethod->get_active_row_number() == 2) { + spot.shMethod = "ghs"; + } + + if (ghsMethod->get_active_row_number() == 0) { + spot.ghsMethod = "rgb"; + } else if (ghsMethod->get_active_row_number() == 1) { + spot.ghsMethod = "rgbstd"; + } else if (ghsMethod->get_active_row_number() == 2) { + spot.ghsMethod = "llab"; + } else if (ghsMethod->get_active_row_number() == 3) { + spot.ghsMethod = "lum"; + } else if (ghsMethod->get_active_row_number() == 4) { + spot.ghsMethod = "sat"; + } else if (ghsMethod->get_active_row_number() == 5) { + spot.ghsMethod = "hue"; } for (int i = 0; i < 6; i++) { spot.multsh[i] = multipliersh[i]->getIntValue(); } + spot.ghs_D = ghs_D->getValue(); + spot.ghs_slope = ghs_slope->getValue(); + spot.ghs_chro = ghs_chro->getValue(); + spot.ghs_B = ghs_B->getValue(); + spot.ghs_SP = ghs_SP->getValue(); + spot.ghs_LP = ghs_LP->getValue(); + spot.ghs_HP = ghs_HP->getValue(); + spot.ghs_LC = ghs_LC->getValue(); + spot.ghs_MID = ghs_MID->getValue(); + spot.ghs_BLP = ghs_BLP->getValue(); + spot.ghs_HLP = ghs_HLP->getValue(); + spot.detailSH = detailSH->getIntValue(); spot.tePivot = tePivot->getValue(); spot.reparsh = reparsh->getValue(); @@ -4840,6 +5111,8 @@ void LocallabShadow::write(rtengine::procparams::ProcParams* pp, ParamsEdited* p spot.angSH = angSH->getValue(); spot.featherSH = featherSH->getValue(); spot.inverssh = inverssh->get_active(); + spot.ghs_smooth = ghs_smooth->get_active(); + spot.ghs_inv = ghs_inv->get_active(); spot.enaSHMask = enaSHMask->get_active(); spot.LLmaskSHcurve = LLmaskSHshape->getCurve(); spot.CCmaskSHcurve = CCmaskSHshape->getCurve(); @@ -4874,6 +5147,18 @@ void LocallabShadow::setDefaults(const rtengine::procparams::ProcParams* defPara multipliersh[i]->setDefault(defSpot.multsh[i]); } + ghs_D->setDefault(defSpot.ghs_D); + ghs_slope->setDefault(defSpot.ghs_slope); + ghs_chro->setDefault(defSpot.ghs_chro); + ghs_B->setDefault(defSpot.ghs_B); + ghs_SP->setDefault(defSpot.ghs_SP); + ghs_LP->setDefault(defSpot.ghs_LP); + ghs_HP->setDefault(defSpot.ghs_HP); + ghs_LC->setDefault(defSpot.ghs_LC); + ghs_MID->setDefault(defSpot.ghs_MID); + ghs_BLP->setDefault(defSpot.ghs_BLP); + ghs_HLP->setDefault(defSpot.ghs_HLP); + detailSH->setDefault((double)defSpot.detailSH); tePivot->setDefault(defSpot.tePivot); reparsh->setDefault(defSpot.reparsh); @@ -4901,6 +5186,7 @@ void LocallabShadow::setDefaults(const rtengine::procparams::ProcParams* defPara lowthress->setDefault((double)defSpot.lowthress); higthress->setDefault((double)defSpot.higthress); decays->setDefault((double)defSpot.decays); + } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -4908,6 +5194,8 @@ void LocallabShadow::setDefaults(const rtengine::procparams::ProcParams* defPara void LocallabShadow::adjusterChanged(Adjuster* a, double newval) { + updateShadowGUIsym(); + if (isLocActivated && exp->getEnabled()) { if (a == multipliersh[0] || a == multipliersh[1] || a == multipliersh[2] || a == multipliersh[3] || a == multipliersh[4] || a == multipliersh[5]) { if (listener) { @@ -4922,6 +5210,99 @@ void LocallabShadow::adjusterChanged(Adjuster* a, double newval) } } + if (a == ghs_D) { + if(ghs_D->getValue() > 0.002 || ghs_D->getValue() == 0.f) {//hide sliders WP and HP si D too big + ghs_BLP->set_sensitive(false); + ghs_HLP->set_sensitive(false); + ghs_LC->set_sensitive(true); + ghs_MID->set_sensitive(true); + } else { + ghs_BLP->set_sensitive(true); + ghs_HLP->set_sensitive(true); + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + if(ghs_D->getValue() == 0.f) { + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + + if (listener) { + listener->panelChanged(Evlocallabghs_D, + ghs_D->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_slope) { + if (listener) { + listener->panelChanged(Evlocallabghs_slope, + ghs_slope->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_chro) { + if (listener) { + listener->panelChanged(Evlocallabghs_chro, + ghs_chro->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_B) { + if (listener) { + listener->panelChanged(Evlocallabghs_B, + ghs_B->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_SP) { + if (listener) { + listener->panelChanged(Evlocallabghs_SP, + ghs_SP->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_LP) { + if (listener) { + listener->panelChanged(Evlocallabghs_LP, + ghs_LP->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_HP) { + if (listener) { + listener->panelChanged(Evlocallabghs_HP, + ghs_HP->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_LC) { + if (listener) { + listener->panelChanged(Evlocallabghs_LC, + ghs_LC->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_MID) { + if (listener) { + listener->panelChanged(Evlocallabghs_MID, + ghs_MID->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_BLP) { + if (listener) { + listener->panelChanged(Evlocallabghs_BLP, + ghs_BLP->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == ghs_HLP) { + if (listener) { + listener->panelChanged(Evlocallabghs_HLP, + ghs_HLP->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == detailSH) { if (listener) { listener->panelChanged(EvlocallabdetailSH, @@ -5113,9 +5494,50 @@ void LocallabShadow::adjusterChanged(Adjuster* a, double newval) fatanchorSH->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); } } + + if (a == ghs_D || + a == ghs_B || + a == ghs_SP || + a == ghs_LP || + a == ghs_HP) { + update_ghs_curve( + ghs_B->getValue(), + ghs_D->getValue(), + ghs_LP->getValue(), + ghs_SP->getValue(), + ghs_HP->getValue(), + ghs_inv->get_active(), + *labgridghs); + } } } + +void LocallabShadow::updateghsbw(int bp, int wp, double minbp, double maxwp) //update informations for Black point and White point +{ + idle_register.add( + [this, bp, wp, minbp, maxwp]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + ghsbpwpLabels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_GHSBPWP"), + Glib::ustring::format(std::fixed, std::setprecision(0), bp), + Glib::ustring::format(std::fixed, std::setprecision(0), wp)) + ); + + ghsbpwpvalueLabels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_GHSBPWPVALUE"), + Glib::ustring::format(std::fixed, std::setprecision(2), minbp), + Glib::ustring::format(std::fixed, std::setprecision(2), maxwp)) + ); + + enableListener(); + return false; + } + ); + +} + void LocallabShadow::curveChanged(CurveEditor* ce) { if (isLocActivated && exp->getEnabled()) { @@ -5167,10 +5589,10 @@ void LocallabShadow::enabledChanged() void LocallabShadow::convertParamToNormal() { const LocallabParams::LocallabSpot defSpot; + // const int mode = complexity->get_active_row_number(); // Disable all listeners disableListener(); - // Set hidden GUI widgets in Normal mode to default spot values blurSHde->setValue((double)defSpot.blurSHde); lapmaskSH->setValue(defSpot.lapmaskSH); @@ -5179,6 +5601,8 @@ void LocallabShadow::convertParamToNormal() fatamountSH->setValue(defSpot.fatamountSH); fatanchorSH->setValue(defSpot.fatanchorSH); decays->setValue(defSpot.decays); + ghs_slope->setValue(defSpot.ghs_slope); + updateShadowGUIsym(); // Enable all listeners enableListener(); @@ -5190,13 +5614,14 @@ void LocallabShadow::convertParamToSimple() // Disable all listeners disableListener(); - // Set hidden specific GUI widgets in Simple mode to default spot values + ghsMethod->set_active(0); + gamSH->setValue(defSpot.gamSH); sloSH->setValue(defSpot.sloSH); - strSH->setValue(defSpot.strSH); - angSH->setValue(defSpot.angSH); - featherSH->setValue(defSpot.featherSH); + // angSH->setValue(defSpot.angSH); + // featherSH->setValue(defSpot.featherSH); + // strSH->setValue(defSpot.strSH); showmaskSHMethod->set_active(0); showmaskSHMethodinv->set_active(0); enaSHMask->set_active(defSpot.enaSHMask); @@ -5219,18 +5644,21 @@ void LocallabShadow::convertParamToSimple() void LocallabShadow::updateGUIToMode(const modeType new_type) { + const LocallabParams::LocallabSpot defSpot; + switch (new_type) { case Simple: // Expert and Normal mode widgets are hidden in Simple mode blurSHde->hide(); gamFrame->hide(); - expgradsh->hide(); expmasksh->hide(); exprecovs->hide(); maskusables->hide(); maskunusables->hide(); decays->hide(); - + ghsMethod->hide(); + ghs_slope->hide(); + Lab_Frame->hide(); break; case Normal: @@ -5243,10 +5671,15 @@ void LocallabShadow::updateGUIToMode(const modeType new_type) exprecovs->show(); // Specific Simple mode widgets are shown in Normal mode - if (shMethod->get_active_row_number() != 0) { // Keep widget hidden when shMethod is equal to 0 + if (shMethod->get_active_row_number() == 1) { // Keep widget hidden when shMethod is equal to 0 gamFrame->show(); } + if (shMethod->get_active_row_number() != 1 ) { // Keep widget hidden when shMethod is equal to 0 + gamFrame->hide(); + } + + if (enaSHMask->get_active()) { maskusables->show(); maskunusables->hide(); @@ -5257,12 +5690,16 @@ void LocallabShadow::updateGUIToMode(const modeType new_type) } if (!inverssh->get_active()) { // Keep widget hidden when inverssh is toggled - expgradsh->show(); exprecovs->show(); } - expmasksh->show(); decays->hide(); + ghsMethod->show(); + Lab_Frame->hide(); + if (ghsMethod->get_active_row_number() == 2 && shMethod->get_active_row_number() == 2) { + Lab_Frame->show(); + } + ghs_slope->hide(); break; @@ -5270,12 +5707,16 @@ void LocallabShadow::updateGUIToMode(const modeType new_type) // Show widgets hidden in Normal and Simple mode blurSHde->show(); - if (shMethod->get_active_row_number() != 0) { // Keep widget hidden when shMethod is equal to 0 + if (shMethod->get_active_row_number() == 1) { // Keep widget hidden when shMethod is equal to 0 gamFrame->show(); } + if (shMethod->get_active_row_number() != 1 ) { // Keep widget hidden when shMethod is equal to 0 + gamFrame->hide(); + } + + if (!inverssh->get_active()) { // Keep widget hidden when inverssh is toggled - expgradsh->show(); exprecovs->show(); } if (enaSHMask->get_active()) { @@ -5294,6 +5735,15 @@ void LocallabShadow::updateGUIToMode(const modeType new_type) gammaskSH->show(); slomaskSH->show(); fatSHFrame->show(); + ghsMethod->show(); + Lab_Frame->hide(); + + if (ghsMethod->get_active_row_number() == 2 && shMethod->get_active_row_number() == 2) { + Lab_Frame->show(); + + } + ghs_slope->show(); + } } @@ -5308,7 +5758,6 @@ void LocallabShadow::updateMaskBackground(const double normChromar, const double LLmaskSHshape->updateLocallabBackground(normLumar); HHmaskSHshape->updateLocallabBackground(normHuer); LmaskSHshape->updateLocallabBackground(normLumar); - return false; } ); @@ -5317,8 +5766,8 @@ void LocallabShadow::updateMaskBackground(const double normChromar, const double void LocallabShadow::shMethodChanged() { - // Update shadow highlight GUI according to shMethod combobox state - updateShadowGUI2(); + // Update shadow highlight GUI according to shmethod combobox state + updateShadowGUIshmet(); if (isLocActivated && exp->getEnabled()) { if (listener) { @@ -5328,12 +5777,46 @@ void LocallabShadow::shMethodChanged() } } +void LocallabShadow::ghsMethodChanged() +{ + const int mode = complexity->get_active_row_number(); + + // Update shadow highlight GUI according to ghsMethod combobox state + updateShadowGUIshmet(); + if (ghsMethod->get_active_row_number() == 2) { + Lab_Frame->show(); + ghs_slope->hide(); + + if (mode == Expert) { + ghs_slope->show(); + } + ghs_chro->show(); + } else { + Lab_Frame->hide(); + ghs_slope->hide(); + ghs_chro->hide(); + Lab_Frame->hide(); + + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + listener->panelChanged(EvlocallabghsMethod, + ghsMethod->get_active_text() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } +} + void LocallabShadow::inversshChanged() { const bool maskPreviewActivated = isMaskViewActive(); + if (shMethod->get_active_row_number() == 2) {//GHS + inverssh->hide(); + inverssh->set_active(false); + } // Update shadow highlight GUI according to inverssh button state - updateShadowGUI1(); + updateShadowGUImask(); if (maskPreviewActivated) { // This event is called to transmit reset mask state @@ -5355,6 +5838,71 @@ void LocallabShadow::inversshChanged() } } +void LocallabShadow::ghs_smoothChanged() +{ + const bool maskPreviewActivated = isMaskViewActive(); + + // Update shadow highlight GUI according to inverssh button state + updateShadowGUImask(); + + if (maskPreviewActivated) { + // This event is called to transmit reset mask state + if (listener) { + listener->panelChanged(EvlocallabshowmaskMethod, ""); + } + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (ghs_smooth->get_active()) { + listener->panelChanged(Evlocallabghs_smooth, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabghs_smooth, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + + +void LocallabShadow::ghs_invChanged() +{ + const bool maskPreviewActivated = isMaskViewActive(); + + // Update shadow highlight GUI according to inverssh button state + updateShadowGUImask(); + + if (maskPreviewActivated) { + // This event is called to transmit reset mask state + if (listener) { + listener->panelChanged(EvlocallabshowmaskMethod, ""); + } + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (ghs_inv->get_active()) { + listener->panelChanged(Evlocallabghs_inv, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabghs_inv, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } + + update_ghs_curve( + ghs_B->getValue(), + ghs_D->getValue(), + ghs_LP->getValue(), + ghs_SP->getValue(), + ghs_HP->getValue(), + ghs_inv->get_active(), + *labgridghs); +} + + void LocallabShadow::showmaskSHMethodChanged() { // If mask preview is activated, deactivate other Shadow highlight mask preview @@ -5417,9 +5965,14 @@ void LocallabShadow::enaSHMaskChanged() } } -void LocallabShadow::updateShadowGUI1() +void LocallabShadow::updateShadowGUImask() { const int mode = complexity->get_active_row_number(); + const LocallabParams::LocallabSpot defSpot; + if (shMethod->get_active_row_number() == 2) { + inverssh->hide(); + inverssh->set_active(false); + } // Update shadow highlight GUI according to inverssh button state if (inverssh->get_active()) { @@ -5433,9 +5986,35 @@ void LocallabShadow::updateShadowGUI1() exprecovs->hide(); reparsh->hide(); } else { + ghsMethod->hide(); + ghs_slope->hide(); + Lab_Frame->hide(); + if(ghs_D->getValue() > 0.002 || ghs_D->getValue() == 0.f) { + ghs_BLP->set_sensitive(false); + ghs_HLP->set_sensitive(false); + ghs_LC->set_sensitive(true); + ghs_MID->set_sensitive(true); + } else { + ghs_BLP->set_sensitive(true); + ghs_HLP->set_sensitive(true); + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + if(ghs_D->getValue() == 0.f) { + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + if (mode == Expert || mode == Normal) { // Keep widget hidden in Simple mode - expgradsh->show(); exprecovs->show(); + ghsMethod->show(); + } + if (ghsMethod->get_active_row_number() == 2 && shMethod->get_active_row_number() == 2) { + Lab_Frame->show(); + } + + if (mode == Expert) { + ghs_slope->show(); } reparsh->show(); @@ -5448,7 +6027,33 @@ void LocallabShadow::updateShadowGUI1() } } -void LocallabShadow::updateShadowGUI2() +void LocallabShadow::updateShadowGUIsym() +{ + // Update adjuster range to avoid black screen according to Symmetry ghs_SP + + + double tempLP = ghs_LP->getValue();//Low values Protect shadows + const double tempSP = rtengine::LIM(ghs_SP->getValue(), 0.0001, 0.9999);//avoid 0 and 1 no real sens for symmetry must be enough for most cases + double tempHP = ghs_HP->getValue();//high values Protect highlight + double secur = 0.001;//keep range security to avoid crash and wrong GUI - no or small incidence on usage + double HPL = rtengine::LIM(tempSP - secur, 0.0001, 0.9999); + double BPH = rtengine::LIM(tempSP + secur, 0.0001, 0.9999); + ghs_LP->setLimits(0., HPL, 0.00001, 0.0);// + ghs_HP->setLimits(BPH, 1.0, 0.00001, 0.0); + //avoid crash at limits + if(tempHP - tempSP <= 0.) { + tempHP = tempSP + 0.0001; + } + if(tempSP - tempLP <= 0.) { + tempLP = tempSP - 0.0001; + } + ghs_LP->setValue(tempLP); + ghs_HP->setValue(tempHP); + +} + + +void LocallabShadow::updateShadowGUIshmet() { const int mode = complexity->get_active_row_number(); @@ -5466,6 +6071,8 @@ void LocallabShadow::updateShadowGUI2() shadows->show(); s_tonalwidth->show(); sh_radius->show(); + ghsFrame->hide(); + ghsMethod->hide(); } else if (shMethod->get_active_row_number() == 1) { for (const auto multiplier : multipliersh) { multiplier->show(); @@ -5482,6 +6089,52 @@ void LocallabShadow::updateShadowGUI2() shadows->hide(); s_tonalwidth->hide(); sh_radius->hide(); + ghsFrame->hide(); + ghsMethod->hide(); + } else if (shMethod->get_active_row_number() == 2) { + for (const auto multiplier : multipliersh) { + multiplier->hide(); + } + gamFrame->hide(); + detailSH->hide(); + tePivot->hide(); + highlights->hide(); + h_tonalwidth->hide(); + shadows->hide(); + s_tonalwidth->hide(); + sh_radius->hide(); + ghsFrame->show(); + inverssh->hide(); + inverssh->set_active(false); + ghsMethod->hide(); + ghs_slope->hide(); + Lab_Frame->hide(); + if(ghs_D->getValue() > 0.002 || ghs_D->getValue() == 0.f) { + ghs_BLP->set_sensitive(false); + ghs_HLP->set_sensitive(false); + ghs_LC->set_sensitive(true); + ghs_MID->set_sensitive(true); + } else { + ghs_BLP->set_sensitive(true); + ghs_HLP->set_sensitive(true); + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + if(ghs_D->getValue() == 0.f) { + ghs_LC->set_sensitive(false); + ghs_MID->set_sensitive(false); + } + + if (mode == Expert || mode == Normal) { // Keep widget hidden in Simple mode + ghsMethod->show(); + if (ghsMethod->get_active_row_number() == 2) { + Lab_Frame->show(); + } + } + if (mode == Expert) { + ghs_slope->show(); + + } } } @@ -5762,6 +6415,8 @@ void LocallabVibrance::updateguivib(int spottype) enableListener(); + + return false; } @@ -5831,6 +6486,7 @@ void LocallabVibrance::updateAdviceTooltips(const bool showTooltips) slomaskvib->set_tooltip_text(M("TP_LOCALLAB_SLOMASK_TOOLTIP")); lapmaskvib->set_tooltip_text(M("TP_LOCALLAB_LAPRAD1_TOOLTIP")); vibgam->set_tooltip_text(M("TP_LOCALLAB_GAMCOL_TOOLTIP")); + expgradvib->set_tooltip_text(M("TP_LOCALLAB_EXPGRADCOL_TOOLTIP")); /* saturated->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); @@ -5885,6 +6541,7 @@ void LocallabVibrance::updateAdviceTooltips(const bool showTooltips) lowthresv->set_tooltip_text(""); higthresv->set_tooltip_text(""); vibgam->set_tooltip_text(""); + expgradvib->set_tooltip_text(""); } } @@ -5921,7 +6578,7 @@ void LocallabVibrance::read(const rtengine::procparams::ProcParams* pp, const Pa { // Disable all listeners disableListener(); - + nbmaskvib = 0; // Update GUI to selected spot value const int index = pp->locallab.selspot; @@ -6359,9 +7016,12 @@ void LocallabVibrance::convertParamToSimple() disableListener(); // Set hidden specific GUI widgets in Simple mode to default spot values - strvib->setValue(defSpot.strvib); - angvib->setValue(defSpot.angvib); - feathervib->setValue(defSpot.feathervib); + // strvib->setValue(defSpot.strvib); + // angvib->setValue(defSpot.angvib); + // feathervib->setValue(defSpot.feathervib); + strvibab->setValue(defSpot.strvibab); + strvibh->setValue(defSpot.strvibh); + showmaskvibMethod->set_active(0); enavibMask->set_active(defSpot.enavibMask); // CCmaskvibshape->setCurve(defSpot.CCmaskvibcurve); @@ -6393,12 +7053,13 @@ void LocallabVibrance::updateGUIToMode(const modeType new_type) avoidColorShift->hide(); pastSatTog->hide(); curveEditorGG->hide(); - expgradvib->hide(); expmaskvib->hide(); exprecovv->hide(); decayv->hide(); maskusablev->hide(); maskunusablev->hide(); + strvibab->hide(); + strvibh->hide(); break; @@ -6418,7 +7079,6 @@ void LocallabVibrance::updateGUIToMode(const modeType new_type) gammaskvib->hide(); slomaskvib->hide(); // Specific Simple mode widgets are shown in Normal mode - expgradvib->show(); expmaskvib->show(); exprecovv->show(); decayv->hide(); @@ -6443,7 +7103,6 @@ void LocallabVibrance::updateGUIToMode(const modeType new_type) avoidColorShift->show(); pastSatTog->show(); curveEditorGG->show(); - expgradvib->show(); strvibab->show(); strvibh->show(); expmaskvib->show(); @@ -7078,8 +7737,9 @@ LocallabBlur::LocallabBlur(): nlstr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLLUM"), 0, 100, 1, 0))), nldet(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLDET"), 0, 100, 1, 50))), nlpat(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLPAT"), 1, 5, 1, 2))), - nlrad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLRAD"), 3, 10, 1, 5))), + nlrad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLRAD"), 1, 10, 1, 3))), nlgam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLGAM"), 2., 5., 0.1, 3.))), + nliter(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLITER"), 1., 5., 1., 1.))), bilateral(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BILATERAL"), 0, 100, 1, 0))), sensiden(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), reparden(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGREPART"), 1.0, 100.0, 1., 100.0))), @@ -7112,6 +7772,9 @@ LocallabBlur::LocallabBlur(): quaHBox(Gtk::manage(new Gtk::Box())), csThresholdblur(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 0, 9, 0, 0, 6, 5, 0, false))) { + auto m = ProcEventMapper::getInstance(); + Evlocallabnliter = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_NLITER"); + set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -7279,6 +7942,7 @@ LocallabBlur::LocallabBlur(): nlpat->setAdjusterListener(this); nlrad->setAdjusterListener(this); nlgam->setAdjusterListener(this); + nliter->setAdjusterListener(this); sensiden->setAdjusterListener(this); reparden->setAdjusterListener(this); @@ -7426,6 +8090,7 @@ LocallabBlur::LocallabBlur(): nlbox->pack_start(*nlgam); nlbox->pack_start(*nlpat); nlbox->pack_start(*nlrad); + nlbox->pack_start(*nliter); expdenoisenl->add(*nlbox); wavBox->pack_start(*expdenoisenl); @@ -7623,6 +8288,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) nlpat->set_tooltip_text(M("TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP")); nlrad->set_tooltip_text(M("TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP")); nlgam->set_tooltip_text(M("TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP")); + nliter->set_tooltip_text(M("TP_LOCALLAB_NLDENOISENLITER_TOOLTIP")); noiselumc->set_tooltip_text(M("TP_LOCALLAB_NOISECHROC_TOOLTIP")); expmaskbl->set_tooltip_markup(M("TP_LOCALLAB_MASK_TOOLTIP")); showmaskblMethodtyp->set_tooltip_markup(M("TP_LOCALLAB_SHOWMASKTYP_TOOLTIP")); @@ -7691,6 +8357,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) nlpat->set_tooltip_text(""); nlrad->set_tooltip_text(""); nlgam->set_tooltip_text(""); + nliter->set_tooltip_text(""); blurMethod->set_tooltip_markup(""); expdenoise->set_tooltip_markup(""); wavshapeden->setTooltip(""); @@ -7749,6 +8416,7 @@ void LocallabBlur::neutral_pressed () nlpat->setValue(defSpot.nlpat); nlrad->setValue(defSpot.nlrad); nlgam->setValue(defSpot.nlgam); + nliter->setValue(defSpot.nliter); sensiden->setValue(defSpot.sensiden); quamethod->set_active (0); wavshapeden->setCurve(defSpot.locwavcurveden); @@ -7964,6 +8632,7 @@ void LocallabBlur::read(const rtengine::procparams::ProcParams* pp, const Params nlpat->setValue((double)spot.nlpat); nlrad->setValue((double)spot.nlrad); nlgam->setValue((double)spot.nlgam); + nliter->setValue((double)spot.nliter); sensiden->setValue((double)spot.sensiden); if (spot.showmaskblMethodtyp == "blur") { @@ -8112,6 +8781,7 @@ void LocallabBlur::write(rtengine::procparams::ProcParams* pp, ParamsEdited* ped spot.nldet = nldet->getIntValue(); spot.nlpat = nlpat->getIntValue(); spot.nlrad = nlrad->getIntValue(); + spot.nliter = nliter->getIntValue(); spot.nlgam = nlgam->getValue(); if (showmaskblMethodtyp->get_active_row_number() == 0) { @@ -8194,6 +8864,7 @@ void LocallabBlur::setDefaults(const rtengine::procparams::ProcParams* defParams nldet->setDefault((double)defSpot.nldet); nlpat->setDefault((double)defSpot.nlpat); nlrad->setDefault((double)defSpot.nlrad); + nliter->setDefault((double)defSpot.nliter); nlgam->setDefault(defSpot.nlgam); sensiden->setDefault((double)defSpot.sensiden); strumaskbl->setDefault(defSpot.strumaskbl); @@ -8490,6 +9161,13 @@ void LocallabBlur::adjusterChanged(Adjuster* a, double newval) } } + if (a == nliter) { + if (listener) { + listener->panelChanged(Evlocallabnliter, + nliter->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == nldet) { if (listener) { listener->panelChanged(Evlocallabnldet, diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index a2d2c5447..5667aecdc 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -123,6 +123,7 @@ protected: rtengine::ProcEvent Evlocallabbluxl; rtengine::ProcEvent Evlocallabbluyl; rtengine::ProcEvent EvlocallabGridciexy; + rtengine::ProcEvent EvlocallabGridghs; rtengine::ProcEvent Evlocallabgamutcie; rtengine::ProcEvent Evlocallabbwcie; rtengine::ProcEvent Evlocallabexpprecam; @@ -387,7 +388,7 @@ public: bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; - + int nbmaskcol; Gtk::ToggleButton *getPreviewDeltaEButton() const override; sigc::connection *getPreviewDeltaEButtonConnection() override; @@ -522,6 +523,7 @@ public: bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + int nbmaskexp; Gtk::ToggleButton *getPreviewDeltaEButton() const override; sigc::connection *getPreviewDeltaEButtonConnection() override; @@ -594,6 +596,33 @@ private: Gtk::Frame* const gamFrame; Adjuster* const gamSH; Adjuster* const sloSH; + + MyComboBoxText* const ghsMethod; + Gtk::Frame* const gridFrameghs; + LabGrid* const labgridghs; + + Gtk::Frame* const ghsFrame; + Adjuster* const ghs_D; + Gtk::Frame* const Lab_Frame; + Adjuster* const ghs_slope; + Adjuster* const ghs_chro; + Adjuster* const ghs_B; + Adjuster* const ghs_SP; + Adjuster* const ghs_LP; + Adjuster* const ghs_HP; + Gtk::Frame* const LC_Frame; + Adjuster* const ghs_LC; + Adjuster* const ghs_MID; + + Gtk::Frame* const BP_Frame; + Adjuster* const ghs_BLP; + Adjuster* const ghs_HLP; + Gtk::Label* const ghsbpwpLabels; + Gtk::Label* const ghsbpwpvalueLabels; + + Gtk::CheckButton* const ghs_smooth; + Gtk::CheckButton* const ghs_inv; + MyExpander* const expgradsh; Adjuster* const strSH; Adjuster* const angSH; @@ -620,8 +649,22 @@ private: Adjuster* const fatanchorSH; rtengine::ProcEvent EvlocallabTePivot; + rtengine::ProcEvent EvlocallabghsMethod; + rtengine::ProcEvent Evlocallabghs_D; + rtengine::ProcEvent Evlocallabghs_slope; + rtengine::ProcEvent Evlocallabghs_chro; + rtengine::ProcEvent Evlocallabghs_B; + rtengine::ProcEvent Evlocallabghs_SP; + rtengine::ProcEvent Evlocallabghs_LP; + rtengine::ProcEvent Evlocallabghs_HP; + rtengine::ProcEvent Evlocallabghs_LC; + rtengine::ProcEvent Evlocallabghs_MID; + rtengine::ProcEvent Evlocallabghs_BLP; + rtengine::ProcEvent Evlocallabghs_HLP; + rtengine::ProcEvent Evlocallabghs_smooth; + rtengine::ProcEvent Evlocallabghs_inv; - sigc::connection shMethodConn, previewshConn, inversshConn, showmaskSHMethodConn, showmaskSHMethodConninv, enaSHMaskConn; + sigc::connection shMethodConn, ghsMethodConn, previewshConn, inversshConn, ghs_smoothConn, ghs_invConn, showmaskSHMethodConn, showmaskSHMethodConninv, enaSHMaskConn; public: LocallabShadow(); @@ -637,7 +680,9 @@ public: void updateAdviceTooltips(const bool showTooltips) override; void updateguishad(int spottype); void updateguiscopesahd(int scope); - + int nbmasksh; + + void updateghsbw(int bp, int wp, double minbp, double maxwp); void setDefaultExpanderVisibility() override; void disableListener() override; void enableListener() override; @@ -657,13 +702,18 @@ private: void updateMaskBackground(const double normChromar, const double normLumar, const double normHuer, const double normHuerjz) override; void shMethodChanged(); + void ghsMethodChanged(); void inversshChanged(); + void ghs_smoothChanged(); + void ghs_invChanged(); void showmaskSHMethodChanged(); void showmaskSHMethodChangedinv(); void enaSHMaskChanged(); - void updateShadowGUI1(); - void updateShadowGUI2(); + void updateShadowGUImask(); + void updateShadowGUIshmet(); + void updateShadowGUIsym(); + }; /* ==== LocallabVibrance ==== */ @@ -726,6 +776,7 @@ public: bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + int nbmaskvib; Gtk::ToggleButton *getPreviewDeltaEButton() const override; sigc::connection *getPreviewDeltaEButtonConnection() override; @@ -907,9 +958,12 @@ private: Adjuster* const nlpat; Adjuster* const nlrad; Adjuster* const nlgam; + Adjuster* const nliter; Adjuster* const bilateral; Adjuster* const sensiden; - + + rtengine::ProcEvent Evlocallabnliter; + Adjuster* const reparden; Gtk::Button* neutral; MyExpander* const expmaskbl; @@ -1279,6 +1333,7 @@ private: Adjuster* const clarisoft; Gtk::CheckButton* const origlc; MyExpander* const expcontrastpyr; + Gtk::Frame* const gradwavFrame; Gtk::CheckButton* const wavgradl; Adjuster* const sigmalc2; Adjuster* const strwav; @@ -1358,6 +1413,7 @@ public: bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + int nbmaskcont; Gtk::ToggleButton *getPreviewDeltaEButton() const override; sigc::connection *getPreviewDeltaEButtonConnection() override; @@ -1578,7 +1634,7 @@ public: void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; void updateguilog(int spottype); void previewlogChanged(); - + int nbmasklog; Gtk::ToggleButton *getPreviewDeltaEButton() const override; sigc::connection *getPreviewDeltaEButtonConnection() override; @@ -2003,7 +2059,7 @@ public: bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; - + int nbmaskcie; Gtk::ToggleButton *getPreviewDeltaEButton() const override; sigc::connection *getPreviewDeltaEButtonConnection() override; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 75305c99b..6c8cabe99 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -2544,6 +2544,7 @@ LocallabContrast::LocallabContrast(): clarisoft(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.5, 1.))), origlc(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ORIGLC")))), expcontrastpyr(Gtk::manage(new MyExpander(false, Gtk::manage(new Gtk::Box())))), + gradwavFrame(Gtk::manage(new Gtk::Frame())), wavgradl(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_GRALWFRA")))), sigmalc2(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMAWAV"), 0.2, 2.5, 0.01, 1.))), strwav(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -4.0, 4.0, 0.05, 0.))), @@ -2966,7 +2967,6 @@ LocallabContrast::LocallabContrast(): clariFrame->add(*clariBox); pack_start(*clariFrame); ToolParamBlock* const blurcontBox = Gtk::manage(new ToolParamBlock()); - Gtk::Frame* const gradwavFrame = Gtk::manage(new Gtk::Frame()); gradwavFrame->set_label_align(0.025, 0.5); gradwavFrame->set_label_widget(*wavgradl); ToolParamBlock* const gradwavBox = Gtk::manage(new ToolParamBlock()); @@ -3384,7 +3384,7 @@ void LocallabContrast::read(const rtengine::procparams::ProcParams* pp, const Pa { // Disable all listeners disableListener(); - + nbmaskcont = 0; // Update GUI to selected spot value const int index = pp->locallab.selspot; @@ -6118,7 +6118,7 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE { // Disable all listeners disableListener(); - + nbmasklog = 0; // Update GUI to selected spot value const int index = pp->locallab.selspot; @@ -8162,7 +8162,7 @@ Locallabcie::Locallabcie(): refi(Gtk::manage(new Adjuster(M("TC_PRIM_REFI"), -0.5, 1., 0.0001, 0.))), gridFramecie(Gtk::manage(new Gtk::Frame(M("TP_ICM_WORKING_CIEDIAG")))), - labgridcie(Gtk::manage(new LabGrid(EvlocallabGridciexy, M("TP_ICM_LABGRID_CIEXY"), true, true, false))), + labgridcie(Gtk::manage(new LabGrid(EvlocallabGridciexy, M("TP_ICM_LABGRID_CIEXY"), true, true, false, false))), colorFramecie(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_COLORFRAME")))), catBox(Gtk::manage(new Gtk::Box())), @@ -9402,6 +9402,7 @@ void Locallabcie::updateguicie(int spottype) } + void Locallabcie::previewcieChanged() { @@ -9491,6 +9492,8 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) mask2cieCurveEditorG->set_tooltip_text(M("TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP")); Lmaskcieshape->setTooltip(M("TP_LOCALLAB_LMASK_LL_TOOLTIP")); exprecovcie->set_tooltip_markup(M("TP_LOCALLAB_MASKRESH_TOOLTIP")); + expgradcie->set_tooltip_text(M("TP_LOCALLAB_EXPGRADCOL_TOOLTIP")); + strumaskcie->set_tooltip_text(M("TP_LOCALLAB_STRUSTRMASK_TOOLTIP")); fftcieMask->set_tooltip_text(M("TP_LOCALLAB_FFTMASK_TOOLTIP")); contcie->set_tooltip_text(M("TP_LOCALLAB_CONTTHMASK_TOOLTIP")); @@ -9712,7 +9715,7 @@ void Locallabcie::showmaskcieMethodChanged() // If mask preview is activated, deactivate all other tool mask preview if (locToolListener) { - locToolListener->resetOtherMaskView(this); + // locToolListener->resetOtherMaskView(this); } if (exp->getEnabled()) { @@ -9853,7 +9856,7 @@ void Locallabcie::fftcieMaskChanged() void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { disableListener(); - + nbmaskcie = 0; // Update GUI to selected spot value const int index = pp->locallab.selspot; Glib::ustring prof = pp->icm.workingProfile; @@ -10325,7 +10328,8 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.labgridcieWx, spot.labgridcieWy, spot.labgridcieMx, - spot.labgridcieMy); + spot.labgridcieMy + ); spot.Autograycie = Autograycie->get_active(); spot.sigybjz12 = sigybjz12->get_active(); @@ -10716,7 +10720,7 @@ void Locallabcie::updateiPrimloc(const float r_x, const float r_y, const float g bluxl->setValue(b_x); bluyl->setValue(b_y); labgridcie->setParams(nextrx, nextry, nextbx, nextby, nextgx, nextgy, nextwx, nextwy, nextmx, nextmy, false); - /* +/* if(lkg) { slopesmor->setValue(slg); slopesmob->setValue(slg); @@ -10724,7 +10728,7 @@ void Locallabcie::updateiPrimloc(const float r_x, const float r_y, const float g adjusterChanged(slopesmob, 0.); } - */ +*/ enableListener(); return false; } @@ -11377,7 +11381,6 @@ void Locallabcie::modecamChanged() } else if (mode != Simple){ exprecovcie->show(); - expgradcie->show(); expmaskcie->show(); qjmodcam(); @@ -11423,7 +11426,6 @@ void Locallabcie::modecamChanged() expcam16->hide(); expcamviewing->hide(); catadcie->hide(); - expgradcie->hide(); expcam16->hide(); lapmaskcie->hide(); lapmaskcie->setValue(defSpot.lapmaskcie); @@ -11431,7 +11433,6 @@ void Locallabcie::modecamChanged() } else if (mode != Simple){ exprecovcie->show(); - expgradcie->show(); expmaskcie->show(); } } else { @@ -11460,7 +11461,6 @@ void Locallabcie::modecamChanged() bevwevFrame->show(); catadcie->hide(); expcamviewing->hide(); - expgradcie->hide(); expcam16->hide(); lapmaskcie->hide(); lapmaskcie->setValue(defSpot.lapmaskcie); @@ -11487,7 +11487,6 @@ void Locallabcie::modecamChanged() expcamviewing->show(); if (mode != Simple){ exprecovcie->show(); - expgradcie->show(); expmaskcie->show(); } @@ -11525,14 +11524,12 @@ void Locallabcie::modecieChanged() const int mode = complexity->get_active_row_number(); exprecovcie->show(); expmaskcie->show(); - expgradcie->show(); if (modecie->get_active_row_number() > 0 && mode == Expert) { sensicie->hide(); reparcie->hide(); exprecovcie->show(); expmaskcie->show(); - expgradcie->hide(); } else { sensicie->show(); @@ -11541,7 +11538,6 @@ void Locallabcie::modecieChanged() if (mode == Expert) { exprecovcie->show(); expmaskcie->show(); - expgradcie->show(); } } @@ -11821,7 +11817,6 @@ void Locallabcie::guijzczhz() expmaskcie->hide(); expprecam->hide(); exprecovcie->hide(); - expgradcie->hide(); lapmaskcie->hide(); } @@ -11938,7 +11933,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sourceGraycie->show(); expcamscene->show(); exprecovcie->hide(); - expgradcie->hide(); maskusablecie->hide(); maskunusablecie->hide(); decaycie->hide(); @@ -11974,7 +11968,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) primillFrame->hide(); expmaskcie->hide(); exprecovcie->hide(); - expgradcie->hide(); sigmoidjzFrame12->hide(); sigmoidjzFrame->hide(); sigmoidFrame12->hide(); @@ -12086,7 +12079,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) lightsigqcie->hide(); expmaskcie->hide(); exprecovcie->hide(); - expgradcie->hide(); break; @@ -12156,7 +12148,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sourceGraycie->show(); expcamscene->show(); exprecovcie->show(); - expgradcie->show(); expmaskcie->show(); decaycie->hide(); lapmaskcie->hide(); @@ -12282,7 +12273,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) qjmodjz(); } else { exprecovcie->show(); - expgradcie->show(); expmaskcie->show(); } @@ -12290,7 +12280,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if (modecie->get_active_row_number() > 0) { exprecovcie->hide(); expmaskcie->hide(); - expgradcie->hide(); } contsigqcie->hide(); @@ -12355,7 +12344,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sourceGraycie->show(); expcamscene->show(); exprecovcie->show(); - expgradcie->show(); decaycie->show(); lapmaskcie->show(); gammaskcie->show(); @@ -12484,7 +12472,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sigmoidjzFrame12->show(); sigmoidFrame12->hide(); expprecam->hide(); - expgradcie->hide(); expcam16->hide(); exprecovcie->show(); expmaskcie->show(); @@ -12617,12 +12604,10 @@ void Locallabcie::updateGUIToMode(const modeType new_type) catadcie->hide(); expcamviewing->hide(); exprecovcie->show(); - expgradcie->show(); expmaskcie->show(); maskusablecie->show(); maskunusablecie->show(); expprecam->hide(); - expgradcie->hide(); expcam16->hide(); lapmaskcie->hide(); lapmaskcie->setValue(defSpot.lapmaskcie); @@ -12642,7 +12627,6 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if (modecie->get_active_row_number() > 0) { exprecovcie->hide(); expmaskcie->hide(); - expgradcie->hide(); } contsigqcie->hide(); @@ -12657,7 +12641,6 @@ void Locallabcie::updatecieGUI() const int mode = complexity->get_active_row_number(); expmaskcie->show(); exprecovcie->show(); - expgradcie->show(); contsigqcie->hide(); lightsigqcie->hide(); @@ -12671,13 +12654,11 @@ void Locallabcie::updatecieGUI() sensicie->hide(); reparcie->hide(); exprecovcie->hide(); - expgradcie->hide(); expmaskcie->hide(); } else { sensicie->show(); reparcie->show(); exprecovcie->show(); - expgradcie->show(); expmaskcie->show(); } @@ -12694,7 +12675,6 @@ void Locallabcie::updatecieGUI() expmaskcie->hide(); exprecovcie->hide(); primillFrame->hide(); - expgradcie->hide(); } else if (mode == Normal) { primillFrame->hide(); @@ -12861,7 +12841,6 @@ void Locallabcie::updatecieGUI() if (modecie->get_active_row_number() > 0) { exprecovcie->hide(); - expgradcie->hide(); expmaskcie->hide(); } @@ -12881,7 +12860,6 @@ void Locallabcie::updatecieGUI() catadcie->hide(); expprecam->hide(); expcamviewing->hide(); - expgradcie->hide(); expcam16->hide(); exprecovcie->show(); expmaskcie->show(); @@ -12917,9 +12895,9 @@ void Locallabcie::convertParamToSimple() showmaskcieMethod->set_active(0); enacieMask->set_active(defSpot.enacieMask); enacieMaskall->set_active(defSpot.enacieMaskall); - strgradcie->setValue(defSpot.strgradcie); - anggradcie->setValue(defSpot.anggradcie); - feathercie->setValue(defSpot.feathercie); + //strgradcie->setValue(defSpot.strgradcie); + //anggradcie->setValue(defSpot.anggradcie); + //feathercie->setValue(defSpot.feathercie); refi->setValue(defSpot.refi); modecie->set_active(0); primMethod->set_active(0);//Prophoto @@ -13130,7 +13108,8 @@ void Locallabcie::setDefaults(const rtengine::procparams::ProcParams* defParams, defSpot.labgridcieWx, defSpot.labgridcieWy, defSpot.labgridcieMx, - defSpot.labgridcieMy); + defSpot.labgridcieMy + ); } } @@ -13938,7 +13917,7 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) if (listener) { listener->panelChanged(Evlocallabstrgradcie, strgradcie->getTextValue() + spName); - } + } } if (a == anggradcie) { diff --git a/rtgui/options.cc b/rtgui/options.cc index acca54c23..46d5f4edb 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -185,6 +185,10 @@ void Options::updatePaths() lastlocalCurvesDir = preferredPath; } + if (lastlocalCurvesDirghs.empty() || !Glib::file_test(lastlocalCurvesDirghs, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastlocalCurvesDirghs, Glib::FILE_TEST_IS_DIR)) { + lastlocalCurvesDirghs = preferredPath; + } + if (lastPFCurvesDir.empty() || !Glib::file_test(lastPFCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test(lastPFCurvesDir, Glib::FILE_TEST_IS_DIR)) { lastPFCurvesDir = preferredPath; } @@ -692,6 +696,7 @@ void Options::setDefaults() lastDenoiseCurvesDir = ""; lastWaveletCurvesDir = ""; lastlocalCurvesDir = ""; + lastlocalCurvesDirghs = ""; lastPFCurvesDir = ""; lastHsvCurvesDir = ""; lastToneCurvesDir = ""; @@ -2314,6 +2319,7 @@ void Options::readFromFile(Glib::ustring fname) safeDirGet(keyFile, "Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); safeDirGet(keyFile, "Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); safeDirGet(keyFile, "Dialogs", "LastlocalCurvesDir", lastlocalCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastlocalCurvesDirghs", lastlocalCurvesDirghs); safeDirGet(keyFile, "Dialogs", "LastPFCurvesDir", lastPFCurvesDir); safeDirGet(keyFile, "Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); @@ -2813,6 +2819,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); keyFile.set_string("Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); keyFile.set_string("Dialogs", "LastlocalCurvesDir", lastlocalCurvesDir); + keyFile.set_string("Dialogs", "LastlocalCurvesDirghs", lastlocalCurvesDirghs); keyFile.set_string("Dialogs", "LastPFCurvesDir", lastPFCurvesDir); keyFile.set_string("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); keyFile.set_string("Dialogs", "LastBWCurvesDir", lastBWCurvesDir); diff --git a/rtgui/options.h b/rtgui/options.h index 3ee7349b0..0abed72df 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -488,6 +488,7 @@ public: Glib::ustring lastWaveletCurvesDir; Glib::ustring lastIcmCurvesDir; Glib::ustring lastlocalCurvesDir; + Glib::ustring lastlocalCurvesDirghs; Glib::ustring lastPFCurvesDir; Glib::ustring lastHsvCurvesDir; Glib::ustring lastToneCurvesDir; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 9b9345846..a5e5ae12e 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1455,6 +1455,21 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).expshadhigh = locallab.spots.at(j).expshadhigh && pSpot.expshadhigh == otherSpot.expshadhigh; locallab.spots.at(j).complexshadhigh = locallab.spots.at(j).complexshadhigh && pSpot.complexshadhigh == otherSpot.complexshadhigh; locallab.spots.at(j).shMethod = locallab.spots.at(j).shMethod && pSpot.shMethod == otherSpot.shMethod; + locallab.spots.at(j).ghsMethod = locallab.spots.at(j).ghsMethod && pSpot.ghsMethod == otherSpot.ghsMethod; + locallab.spots.at(j).ghsMode = locallab.spots.at(j).ghsMode && pSpot.ghsMode == otherSpot.ghsMode; + locallab.spots.at(j).ghs_D = locallab.spots.at(j).ghs_D && pSpot.ghs_D == otherSpot.ghs_D; + locallab.spots.at(j).ghs_slope = locallab.spots.at(j).ghs_slope && pSpot.ghs_slope == otherSpot.ghs_slope; + locallab.spots.at(j).ghs_chro = locallab.spots.at(j).ghs_chro && pSpot.ghs_chro == otherSpot.ghs_chro; + locallab.spots.at(j).ghs_B = locallab.spots.at(j).ghs_B && pSpot.ghs_B == otherSpot.ghs_B; + locallab.spots.at(j).ghs_SP = locallab.spots.at(j).ghs_SP && pSpot.ghs_SP == otherSpot.ghs_SP; + locallab.spots.at(j).ghs_LP = locallab.spots.at(j).ghs_LP && pSpot.ghs_LP == otherSpot.ghs_LP; + locallab.spots.at(j).ghs_HP = locallab.spots.at(j).ghs_HP && pSpot.ghs_HP == otherSpot.ghs_HP; + locallab.spots.at(j).ghs_LC = locallab.spots.at(j).ghs_LC && pSpot.ghs_LC == otherSpot.ghs_LC; + locallab.spots.at(j).ghs_MID = locallab.spots.at(j).ghs_MID && pSpot.ghs_MID == otherSpot.ghs_MID; + locallab.spots.at(j).ghs_BLP = locallab.spots.at(j).ghs_BLP && pSpot.ghs_BLP == otherSpot.ghs_BLP; + locallab.spots.at(j).ghs_HLP = locallab.spots.at(j).ghs_HLP && pSpot.ghs_HLP == otherSpot.ghs_HLP; + locallab.spots.at(j).ghs_smooth = locallab.spots.at(j).ghs_smooth && pSpot.ghs_smooth == otherSpot.ghs_smooth; + locallab.spots.at(j).ghs_inv = locallab.spots.at(j).ghs_inv && pSpot.ghs_inv == otherSpot.ghs_inv; for (int k = 0; k < 6; k++) { locallab.spots.at(j).multsh[k] = locallab.spots.at(j).multsh[k] && pSpot.multsh[k] == otherSpot.multsh[k]; @@ -1588,6 +1603,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).nlpat = locallab.spots.at(j).nlpat && pSpot.nlpat == otherSpot.nlpat; locallab.spots.at(j).nlrad = locallab.spots.at(j).nlrad && pSpot.nlrad == otherSpot.nlrad; locallab.spots.at(j).nlgam = locallab.spots.at(j).nlgam && pSpot.nlgam == otherSpot.nlgam; + locallab.spots.at(j).nliter = locallab.spots.at(j).nliter && pSpot.nliter == otherSpot.nliter; locallab.spots.at(j).sensiden = locallab.spots.at(j).sensiden && pSpot.sensiden == otherSpot.sensiden; locallab.spots.at(j).reparden = locallab.spots.at(j).reparden && pSpot.reparden == otherSpot.reparden; locallab.spots.at(j).detailthr = locallab.spots.at(j).detailthr && pSpot.detailthr == otherSpot.detailthr; @@ -4514,6 +4530,67 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).shMethod = mods.locallab.spots.at(i).shMethod; } + if (locallab.spots.at(i).ghsMethod) { + toEdit.locallab.spots.at(i).ghsMethod = mods.locallab.spots.at(i).ghsMethod; + } + + if (locallab.spots.at(i).ghsMode) { + toEdit.locallab.spots.at(i).ghsMode = mods.locallab.spots.at(i).ghsMode; + } + + if (locallab.spots.at(i).ghs_D) { + toEdit.locallab.spots.at(i).ghs_D = mods.locallab.spots.at(i).ghs_D; + } + + if (locallab.spots.at(i).ghs_slope) { + toEdit.locallab.spots.at(i).ghs_slope = mods.locallab.spots.at(i).ghs_slope; + } + + if (locallab.spots.at(i).ghs_chro) { + toEdit.locallab.spots.at(i).ghs_chro = mods.locallab.spots.at(i).ghs_chro; + } + + if (locallab.spots.at(i).ghs_B) { + toEdit.locallab.spots.at(i).ghs_B = mods.locallab.spots.at(i).ghs_B; + } + + if (locallab.spots.at(i).ghs_SP) { + toEdit.locallab.spots.at(i).ghs_SP = mods.locallab.spots.at(i).ghs_SP; + } + + if (locallab.spots.at(i).ghs_LP) { + toEdit.locallab.spots.at(i).ghs_LP = mods.locallab.spots.at(i).ghs_LP; + } + + if (locallab.spots.at(i).ghs_HP) { + toEdit.locallab.spots.at(i).ghs_HP = mods.locallab.spots.at(i).ghs_HP; + } + + if (locallab.spots.at(i).ghs_LC) { + toEdit.locallab.spots.at(i).ghs_LC = mods.locallab.spots.at(i).ghs_LC; + } + + if (locallab.spots.at(i).ghs_MID) { + toEdit.locallab.spots.at(i).ghs_MID = mods.locallab.spots.at(i).ghs_MID; + } + + if (locallab.spots.at(i).ghs_BLP) { + toEdit.locallab.spots.at(i).ghs_BLP = mods.locallab.spots.at(i).ghs_BLP; + } + + if (locallab.spots.at(i).ghs_HLP) { + toEdit.locallab.spots.at(i).ghs_HLP = mods.locallab.spots.at(i).ghs_HLP; + } + + if (locallab.spots.at(i).ghs_smooth) { + toEdit.locallab.spots.at(i).ghs_smooth = mods.locallab.spots.at(i).ghs_smooth; + } + + if (locallab.spots.at(i).ghs_inv) { + toEdit.locallab.spots.at(i).ghs_inv = mods.locallab.spots.at(i).ghs_inv; + } + + for (int j = 0; j < 6; j++) { if (locallab.spots.at(i).multsh[j]) { toEdit.locallab.spots.at(i).multsh[j] = mods.locallab.spots.at(i).multsh[j]; @@ -5023,6 +5100,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).nlgam = mods.locallab.spots.at(i).nlgam; } + if (locallab.spots.at(i).nliter) { + toEdit.locallab.spots.at(i).nliter = mods.locallab.spots.at(i).nliter; + } + if (locallab.spots.at(i).sensiden) { toEdit.locallab.spots.at(i).sensiden = mods.locallab.spots.at(i).sensiden; } @@ -8481,6 +8562,22 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : expshadhigh(v), complexshadhigh(v), shMethod(v), + ghsMethod(v), + ghsMode(v), + ghs_D(v), + ghs_slope(v), + ghs_chro(v), + ghs_B(v), + ghs_SP(v), + ghs_LP(v), + ghs_HP(v), + ghs_LC(v), + ghs_MID(v), + ghs_BLP(v), + ghs_HLP(v), + ghs_smooth(v), + ghs_inv(v), + multsh{v, v, v, v, v, v, v}, highlights(v), h_tonalwidth(v), @@ -8610,6 +8707,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : nlpat(v), nlrad(v), nlgam(v), + nliter(v), sensiden(v), reparden(v), detailthr(v), @@ -9267,6 +9365,21 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) expshadhigh = v; complexshadhigh = v; shMethod = v; + ghsMethod = v; + ghsMode = v; + ghs_D = v; + ghs_slope = v; + ghs_chro = v; + ghs_B = v; + ghs_SP = v; + ghs_LP = v; + ghs_HP = v; + ghs_LC = v; + ghs_MID = v; + ghs_BLP = v; + ghs_HLP = v; + ghs_smooth = v; + ghs_inv = v; for (int i = 0; i < 6; i++) { multsh[i] = v; @@ -9400,6 +9513,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) nlpat = v; nlrad = v; nlgam = v; + nliter = v; sensiden = v; reparden = v; detailthr = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 142e3f05a..a8c767fcd 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -596,6 +596,22 @@ public: bool expshadhigh; bool complexshadhigh; bool shMethod; + bool ghsMethod; + bool ghsMode; + bool ghs_D; + bool ghs_slope; + bool ghs_chro; + bool ghs_B; + bool ghs_SP; + bool ghs_LP; + bool ghs_HP; + bool ghs_LC; + bool ghs_MID; + bool ghs_BLP; + bool ghs_HLP; + bool ghs_smooth; + bool ghs_inv; + bool multsh[7]; bool highlights; bool h_tonalwidth; @@ -725,6 +741,7 @@ public: bool nlpat; bool nlrad; bool nlgam; + bool nliter; bool sensiden; bool reparden; bool detailthr; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index cf081d886..f1be5d17d 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -1752,7 +1752,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) strend->setValue(pp->wavelet.strend); detend->setValue(pp->wavelet.detend); thrend->setValue(pp->wavelet.thrend); - labgrid->setParams(pp->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0, false); + labgrid->setParams(pp->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, + 0, 0, 0, 0, 0, 0, false); sigm->setValue(pp->wavelet.sigm); levden->setValue(pp->wavelet.levden); @@ -2215,7 +2216,8 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.chromco = chromco->getValue(); double zerox = 0.; double zeroy = 0.; - labgrid->getParams(pp->wavelet.labgridALow, pp->wavelet.labgridBLow, pp->wavelet.labgridAHigh, pp->wavelet.labgridBHigh, zerox, zeroy, zerox, zeroy, zerox, zeroy); + labgrid->getParams(pp->wavelet.labgridALow, pp->wavelet.labgridBLow, pp->wavelet.labgridAHigh, pp->wavelet.labgridBHigh, + zerox, zeroy, zerox, zeroy, zerox, zeroy); pp->wavelet.labgridALow *= WaveletParams::LABGRID_CORR_MAX; pp->wavelet.labgridAHigh *= WaveletParams::LABGRID_CORR_MAX; pp->wavelet.labgridBLow *= WaveletParams::LABGRID_CORR_MAX; @@ -2677,7 +2679,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balchrom->setDefault(defParams->wavelet.balchrom); chromfi->setDefault(defParams->wavelet.chromfi); chromco->setDefault(defParams->wavelet.chromco); - labgrid->setDefault(defParams->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0); + labgrid->setDefault(defParams->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, + 0, 0, 0, 0, 0, 0); greenlow->setDefault(defParams->wavelet.greenlow); bluelow->setDefault(defParams->wavelet.bluelow);