Merge from dev

This commit is contained in:
Lawrence Lee 2020-08-08 22:02:29 -07:00
commit 2f06f56d9c
31 changed files with 866 additions and 329 deletions

View File

@ -15,6 +15,7 @@ Development contributors, in last name alphabetical order:
Maciek Dworak Maciek Dworak
Michael Ezra Michael Ezra
Flössie Flössie
Rüdiger Franke
Jean-Christophe Frisch Jean-Christophe Frisch
Ilias Giarimis Ilias Giarimis
Alberto Griggio Alberto Griggio

View File

@ -45,7 +45,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION
endif() endif()
# Warning for GCC 10, which causes problems #5749: # Warning for GCC 10, which causes problems #5749:
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "10.0") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "10.1")
message(STATUS "WARNING: gcc ${CMAKE_CXX_COMPILER_VERSION} is known to miscompile RawTherapee when using -ftree-loop-vectorize, forcing the option to be off") message(STATUS "WARNING: gcc ${CMAKE_CXX_COMPILER_VERSION} is known to miscompile RawTherapee when using -ftree-loop-vectorize, forcing the option to be off")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-tree-loop-vectorize") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-tree-loop-vectorize")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-loop-vectorize") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-loop-vectorize")

View File

@ -2653,6 +2653,8 @@ TP_WAVELET_CHR_TOOLTIP;Ajuste le chroma en fonction des "niveaux de contraste" e
TP_WAVELET_CHSL;Curseurs TP_WAVELET_CHSL;Curseurs
TP_WAVELET_CHTYPE;Méthode de chrominance TP_WAVELET_CHTYPE;Méthode de chrominance
TP_WAVELET_COLORT;Opacité Rouge-Vert TP_WAVELET_COLORT;Opacité Rouge-Vert
TP_WAVELET_COMPLEX_TOOLTIP;Standard: lapplication dispose du nécessaire pour assurer les opérations courantes, linterface graphique est simplifiée.\nAvancé: toutes les fonctionnalités sont présentes, certaines nécessitent un apprentissage important
TP_WAVELET_COMPEXPERT;Avancé
TP_WAVELET_COMPCONT;Contraste TP_WAVELET_COMPCONT;Contraste
TP_WAVELET_COMPGAMMA;Compression gamma TP_WAVELET_COMPGAMMA;Compression gamma
TP_WAVELET_COMPGAMMA_TOOLTIP;Ajuster le gamma de l'image résiduelle vous permet d'équiilibrer les données de l'histogramme. TP_WAVELET_COMPGAMMA_TOOLTIP;Ajuster le gamma de l'image résiduelle vous permet d'équiilibrer les données de l'histogramme.

View File

@ -569,10 +569,10 @@ HISTORY_MSG_314;W - Gamut - Reduce artifacts
HISTORY_MSG_315;W - Residual - Contrast HISTORY_MSG_315;W - Residual - Contrast
HISTORY_MSG_316;W - Gamut - Skin tar/prot HISTORY_MSG_316;W - Gamut - Skin tar/prot
HISTORY_MSG_317;W - Gamut - Skin hue HISTORY_MSG_317;W - Gamut - Skin hue
HISTORY_MSG_318;W - Contrast - Fine levels HISTORY_MSG_318;W - Contrast - Finer levels
HISTORY_MSG_319;W - Contrast - Fine range HISTORY_MSG_319;W - Contrast - Finer range
HISTORY_MSG_320;W - Contrast - Coarse range HISTORY_MSG_320;W - Contrast - Coarser range
HISTORY_MSG_321;W - Contrast - Coarse levels HISTORY_MSG_321;W - Contrast - Coarser levels
HISTORY_MSG_322;W - Gamut - Avoid color shift HISTORY_MSG_322;W - Gamut - Avoid color shift
HISTORY_MSG_323;W - ES - Local contrast HISTORY_MSG_323;W - ES - Local contrast
HISTORY_MSG_324;W - Chroma - Pastel HISTORY_MSG_324;W - Chroma - Pastel
@ -636,14 +636,14 @@ HISTORY_MSG_381;PRS RLD - Radius
HISTORY_MSG_382;PRS RLD - Amount HISTORY_MSG_382;PRS RLD - Amount
HISTORY_MSG_383;PRS RLD - Damping HISTORY_MSG_383;PRS RLD - Damping
HISTORY_MSG_384;PRS RLD - Iterations HISTORY_MSG_384;PRS RLD - Iterations
HISTORY_MSG_385;W - Residual - Color Balance HISTORY_MSG_385;W - Residual - Color balance
HISTORY_MSG_386;W - Residual - CB green high HISTORY_MSG_386;W - Residual - CB green high
HISTORY_MSG_387;W - Residual - CB blue high HISTORY_MSG_387;W - Residual - CB blue high
HISTORY_MSG_388;W - Residual - CB green mid HISTORY_MSG_388;W - Residual - CB green mid
HISTORY_MSG_389;W - Residual - CB blue mid HISTORY_MSG_389;W - Residual - CB blue mid
HISTORY_MSG_390;W - Residual - CB green low HISTORY_MSG_390;W - Residual - CB green low
HISTORY_MSG_391;W - Residual - CB blue low HISTORY_MSG_391;W - Residual - CB blue low
HISTORY_MSG_392;W - Residual - Color Balance HISTORY_MSG_392;W - Residual - Color balance
HISTORY_MSG_393;DCP - Look table HISTORY_MSG_393;DCP - Look table
HISTORY_MSG_394;DCP - Baseline exposure HISTORY_MSG_394;DCP - Baseline exposure
HISTORY_MSG_395;DCP - Base table HISTORY_MSG_395;DCP - Base table
@ -1199,7 +1199,7 @@ HISTORY_MSG_956;Local - CH Curve
HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_BLSHAPE;Blur by level
HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_BLURCWAV;Blur chroma
HISTORY_MSG_BLURWAV;Blur luminance HISTORY_MSG_BLURWAV;Blur luminance
HISTORY_MSG_BLUWAV;Attenuation Response HISTORY_MSG_BLUWAV;Attenuation response
HISTORY_MSG_CAT02PRESET;Cat02 automatic preset HISTORY_MSG_CAT02PRESET;Cat02 automatic preset
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction
@ -1216,6 +1216,8 @@ HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power
HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturation HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturation
HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask
HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope
HISTORY_MSG_COMPLEX;Wavelet complexity
HISTORY_MSG_COMPLEXRETI;Retinex complexity
HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth
HISTORY_MSG_DEHAZE_ENABLED;Haze Removal HISTORY_MSG_DEHAZE_ENABLED;Haze Removal
HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only HISTORY_MSG_DEHAZE_LUMINANCE;Dehaze - Luminance only
@ -1223,7 +1225,7 @@ HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map
HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength
HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold
HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold
HISTORY_MSG_EDGEFFECT;Edge Attenuation Response HISTORY_MSG_EDGEFFECT;Edge Attenuation response
HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative
HISTORY_MSG_FILMNEGATIVE_FILMBASE;Film base color HISTORY_MSG_FILMNEGATIVE_FILMBASE;Film base color
HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values
@ -1270,10 +1272,10 @@ HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling
HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius
HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold
HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace
HISTORY_MSG_SIGMACOL;Chroma Attenuation Response HISTORY_MSG_SIGMACOL;Chroma Attenuation response
HISTORY_MSG_SIGMADIR;Dir Attenuation Response HISTORY_MSG_SIGMADIR;Dir Attenuation response
HISTORY_MSG_SIGMAFIN;Final contrast Attenuation Response HISTORY_MSG_SIGMAFIN;Final contrast Attenuation response
HISTORY_MSG_SIGMATON;Toning Attenuation Response HISTORY_MSG_SIGMATON;Toning Attenuation response
HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
HISTORY_MSG_TEMPOUT;CAM02 automatic temperature HISTORY_MSG_TEMPOUT;CAM02 automatic temperature
@ -1292,10 +1294,10 @@ HISTORY_MSG_WAVMERGEC;Merge C
HISTORY_MSG_WAVMERGEL;Merge L HISTORY_MSG_WAVMERGEL;Merge L
HISTORY_MSG_WAVOFFSET;Offset HISTORY_MSG_WAVOFFSET;Offset
HISTORY_MSG_WAVOLDSH;Old algorithm HISTORY_MSG_WAVOLDSH;Old algorithm
HISTORY_MSG_WAVRADIUS;Radius Shadows-Highlight HISTORY_MSG_WAVRADIUS;Radius shadows-highlights
HISTORY_MSG_WAVSCALE;Scale HISTORY_MSG_WAVSCALE;Scale
HISTORY_MSG_WAVSHOWMASK;Show wavelet mask HISTORY_MSG_WAVSHOWMASK;Show wavelet mask
HISTORY_MSG_WAVSIGMA;Attenuation Response HISTORY_MSG_WAVSIGMA;Attenuation response
HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRAD;Soft radius clarity
HISTORY_MSG_WAVSOFTRADEND;Soft radius final HISTORY_MSG_WAVSOFTRADEND;Soft radius final
HISTORY_MSG_WAVUSHAMET;Clarity method HISTORY_MSG_WAVUSHAMET;Clarity method
@ -3237,18 +3239,18 @@ TP_WAVELET_6;Level 6
TP_WAVELET_7;Level 7 TP_WAVELET_7;Level 7
TP_WAVELET_8;Level 8 TP_WAVELET_8;Level 8
TP_WAVELET_9;Level 9 TP_WAVELET_9;Level 9
TP_WAVELET_APPLYTO;Apply To TP_WAVELET_APPLYTO;Apply to
TP_WAVELET_AVOID;Avoid color shift TP_WAVELET_AVOID;Avoid color shift
TP_WAVELET_B0;Black TP_WAVELET_B0;Black
TP_WAVELET_B1;Grey TP_WAVELET_B1;Gray
TP_WAVELET_B2;Residual TP_WAVELET_B2;Residual
TP_WAVELET_BACKGROUND;Background TP_WAVELET_BACKGROUND;Background
TP_WAVELET_BACUR;Curve TP_WAVELET_BACUR;Curve
TP_WAVELET_BALANCE;Contrast balance d/v-h TP_WAVELET_BALANCE;Contrast balance d/v-h
TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified.
TP_WAVELET_BALCHRO;Chrominance balance TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the vertical, horizontal and diagonal wavelet directions: .\nActivating contrast, chroma or residual tone mapping amplifies the effect due to balance
TP_WAVELET_BALCHROM;Denoise Equalizer Blue-yellow Red-green
TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance.
TP_WAVELET_BALCHROM;Denoise equalizer blue-yellow red-green
TP_WAVELET_BALLUM;Denoise Equalizer White-Black TP_WAVELET_BALLUM;Denoise Equalizer White-Black
TP_WAVELET_BANONE;None TP_WAVELET_BANONE;None
TP_WAVELET_BASLI;Slider TP_WAVELET_BASLI;Slider
@ -3256,9 +3258,9 @@ TP_WAVELET_BATYPE;Contrast balance method
TP_WAVELET_BL;Blur levels TP_WAVELET_BL;Blur levels
TP_WAVELET_BLCURVE;Blur by levels TP_WAVELET_BLCURVE;Blur by levels
TP_WAVELET_BLURFRAME;Blur TP_WAVELET_BLURFRAME;Blur
TP_WAVELET_BLUWAV;Attenuation Response TP_WAVELET_BLUWAV;Attenuation response
TP_WAVELET_CBENAB;Toning and Color Balance TP_WAVELET_CBENAB;Toning and Color balance
TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted TP_WAVELET_CB_TOOLTIP;With high values you can create special effects, similar to those achieved with the Chroma Module, but focused on the residual image\nWith moderate values you can manually correct the white balance
TP_WAVELET_CCURVE;Local contrast TP_WAVELET_CCURVE;Local contrast
TP_WAVELET_CH1;Whole chroma range TP_WAVELET_CH1;Whole chroma range
TP_WAVELET_CH2;Saturated/pastel TP_WAVELET_CH2;Saturated/pastel
@ -3266,7 +3268,7 @@ TP_WAVELET_CH3;Link contrast levels
TP_WAVELET_CHCU;Curve TP_WAVELET_CHCU;Curve
TP_WAVELET_CHR;Chroma-contrast link strength TP_WAVELET_CHR;Chroma-contrast link strength
TP_WAVELET_CHRO;Saturated/pastel threshold TP_WAVELET_CHRO;Saturated/pastel threshold
TP_WAVELET_CHROFRAME;Denoise Chrominance TP_WAVELET_CHROFRAME;Denoise chrominance
TP_WAVELET_CHROMAFRAME;Chroma TP_WAVELET_CHROMAFRAME;Chroma
TP_WAVELET_CHROMCO;Chrominance Coarse TP_WAVELET_CHROMCO;Chrominance Coarse
TP_WAVELET_CHROMFI;Chrominance Fine TP_WAVELET_CHROMFI;Chrominance Fine
@ -3277,10 +3279,14 @@ TP_WAVELET_CHSL;Sliders
TP_WAVELET_CHTYPE;Chrominance method TP_WAVELET_CHTYPE;Chrominance method
TP_WAVELET_CLA;Clarity TP_WAVELET_CLA;Clarity
TP_WAVELET_CLARI;Sharp-mask and Clarity TP_WAVELET_CLARI;Sharp-mask and Clarity
TP_WAVELET_COLORT;Opacity Red-Green TP_WAVELET_COLORT;Opacity red-green
TP_WAVELET_COMPCONT;Contrast TP_WAVELET_COMPCONT;Contrast
TP_WAVELET_COMPGAMMA;Compression gamma TP_WAVELET_COMPGAMMA;Compression gamma
TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allows you to equilibrate the data and histogram. TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allows you to equilibrate the data and histogram.
TP_WAVELET_COMPLEXLAB;Complexity
TP_WAVELET_COMPLEX_TOOLTIP;Standard: shows a reduced set of tools suitable for most processing operations.\nAdvanced: shows the complete set of tools for advanced processing operations
TP_WAVELET_COMPNORMAL;Standard
TP_WAVELET_COMPEXPERT;Advanced
TP_WAVELET_COMPTM;Tone mapping TP_WAVELET_COMPTM;Tone mapping
TP_WAVELET_CONTEDIT;'After' contrast curve TP_WAVELET_CONTEDIT;'After' contrast curve
TP_WAVELET_CONTFRAME;Contrast - Compression TP_WAVELET_CONTFRAME;Contrast - Compression
@ -3289,16 +3295,16 @@ TP_WAVELET_CONTRA;Contrast
TP_WAVELET_CONTRASTEDIT;Finer - Coarser levels TP_WAVELET_CONTRASTEDIT;Finer - Coarser levels
TP_WAVELET_CONTRAST_MINUS;Contrast - TP_WAVELET_CONTRAST_MINUS;Contrast -
TP_WAVELET_CONTRAST_PLUS;Contrast + TP_WAVELET_CONTRAST_PLUS;Contrast +
TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. TP_WAVELET_CONTRA_TOOLTIP;Changes the residual image contrast.
TP_WAVELET_CTYPE;Chrominance control TP_WAVELET_CTYPE;Chrominance control
TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Disabled if zoom > about 300% TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Disabled if zoom > about 300%
TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (abscissa).\nLow abscissa values represent small local contrast (real values about 10..20).\n50% abscissa represents average local contrast (real value about 100..300).\n66% abscissa represents standard deviation of local contrast (real value about 300..800).\n100% abscissa represents maximum local contrast (real value about 3000..8000). TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (abscissa).\nLow abscissa values represent small local contrast (real values about 10..20).\n50% abscissa represents average local contrast (real value about 100..300).\n66% abscissa represents standard deviation of local contrast (real value about 300..800).\n100% abscissa represents maximum local contrast (real value about 3000..8000).
TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue)
TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function of hue.\nTake care not to overwrite changes made with the Gamut sub-tool's hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function of hue.\nTake care not to overwrite changes made with the Gamut sub-tool's hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero.
TP_WAVELET_CURVEEDITOR_CL;L TP_WAVELET_CURVEEDITOR_CL;L
TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast-luminance curve at the end of the wavelet processing.
TP_WAVELET_CURVEEDITOR_HH;HH TP_WAVELET_CURVEEDITOR_HH;HH
TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image hue as a function of hue.
TP_WAVELET_DALL;All directions TP_WAVELET_DALL;All directions
TP_WAVELET_DAUB;Edge performance TP_WAVELET_DAUB;Edge performance
TP_WAVELET_DAUB2;D2 - low TP_WAVELET_DAUB2;D2 - low
@ -3307,34 +3313,34 @@ TP_WAVELET_DAUB6;D6 - standard plus
TP_WAVELET_DAUB10;D10 - medium TP_WAVELET_DAUB10;D10 - medium
TP_WAVELET_DAUB14;D14 - high TP_WAVELET_DAUB14;D14 - high
TP_WAVELET_DAUBLOCAL;Wavelet Edge performance TP_WAVELET_DAUBLOCAL;Wavelet Edge performance
TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the first levels. However the quality is not strictly related to this coefficient and can vary depending on image and use.
TP_WAVELET_DIRFRAME;Directional contrast TP_WAVELET_DIRFRAME;Directional contrast
TP_WAVELET_DONE;Vertical TP_WAVELET_DONE;Vertical
TP_WAVELET_DTHR;Diagonal TP_WAVELET_DTHR;Diagonal
TP_WAVELET_DTWO;Horizontal TP_WAVELET_DTWO;Horizontal
TP_WAVELET_EDCU;Curve TP_WAVELET_EDCU;Curve
TP_WAVELET_EDEFFECT;Attenuation Response TP_WAVELET_EDEFFECT;Attenuation response
TP_WAVELET_EDEFFECT_TOOLTIP;This slider controls how wide the range of contrast values are that receive the maximum effect from the tool.\nMaximum value (2.5) disabled the tool TP_WAVELET_EDEFFECT_TOOLTIP;This slider selects the range of contrast values that will receive the full effect of any adjustment
TP_WAVELET_EDGCONT;Local contrast TP_WAVELET_EDGCONT;Local contrast
TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, top-left, top-right and bottom-right represent respectively local contrast for low values, mean, mean+stdev and maxima. TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, top-left, top-right and bottom-right represent respectively local contrast for low values, mean, mean+std. dev. and maxima.
TP_WAVELET_EDGE;Edge Sharpness TP_WAVELET_EDGE;Edge Sharpness
TP_WAVELET_EDGEAMPLI;Base amplification TP_WAVELET_EDGEAMPLI;Base amplification
TP_WAVELET_EDGEDETECT;Gradient sensitivity TP_WAVELET_EDGEDETECT;Gradient sensitivity
TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) TP_WAVELET_EDGEDETECTTHR;Threshold low (noise)
TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) TP_WAVELET_EDGEDETECTTHR2;Edge enhancement
TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This slider sets a threshold below which finer details won't be considered as an edge
TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise.
TP_WAVELET_EDGESENSI;Edge sensitivity TP_WAVELET_EDGESENSI;Edge sensitivity
TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged.
TP_WAVELET_EDGTHRESH;Detail TP_WAVELET_EDGTHRESH;Detail
TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centered on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centered on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts.
TP_WAVELET_EDRAD;Radius TP_WAVELET_EDRAD;Radius
TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. TP_WAVELET_EDRAD_TOOLTIP;This adjustment controls the local enhancement. A value of zero still has an effect
TP_WAVELET_EDSL;Threshold Sliders TP_WAVELET_EDSL;Threshold sliders
TP_WAVELET_EDTYPE;Local contrast method TP_WAVELET_EDTYPE;Local contrast method
TP_WAVELET_EDVAL;Strength TP_WAVELET_EDVAL;Strength
TP_WAVELET_FINAL;Final Touchup TP_WAVELET_FINAL;Final Touchup
TP_WAVELET_FINCFRAME;Final Local Contrast TP_WAVELET_FINCFRAME;Final local contrast
TP_WAVELET_FINCOAR_TOOLTIP;The left (positive) part of the curve acts on the finer levels (increase).\nThe 2 points on the abscissa represent the respective action limits of finer and coarser levels 5 and 6 (default).\nThe right (negative) part of the curve acts on the coarser levels (increase).\nAvoid moving the left part of the curve with negative values. Avoid moving the right part of the curve with positives values TP_WAVELET_FINCOAR_TOOLTIP;The left (positive) part of the curve acts on the finer levels (increase).\nThe 2 points on the abscissa represent the respective action limits of finer and coarser levels 5 and 6 (default).\nThe right (negative) part of the curve acts on the coarser levels (increase).\nAvoid moving the left part of the curve with negative values. Avoid moving the right part of the curve with positives values
TP_WAVELET_FINEST;Finest TP_WAVELET_FINEST;Finest
TP_WAVELET_HIGHLIGHT;Finer levels luminance range TP_WAVELET_HIGHLIGHT;Finer levels luminance range
@ -3342,7 +3348,7 @@ TP_WAVELET_HS1;Whole luminance range
TP_WAVELET_HS2;Selective luminance range TP_WAVELET_HS2;Selective luminance range
TP_WAVELET_HUESKIN;Skin hue TP_WAVELET_HUESKIN;Skin hue
TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the <b>white balance is incorrect</b>. TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the <b>white balance is incorrect</b>.
TP_WAVELET_HUESKY;Sky hue TP_WAVELET_HUESKY;Hue range
TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the <b>white balance is incorrect</b>. TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the <b>white balance is incorrect</b>.
TP_WAVELET_ITER;Delta balance levels TP_WAVELET_ITER;Delta balance levels
TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels.
@ -3350,18 +3356,18 @@ TP_WAVELET_LABEL;Wavelet Levels
TP_WAVELET_LARGEST;Coarsest TP_WAVELET_LARGEST;Coarsest
TP_WAVELET_LEVCH;Chroma TP_WAVELET_LEVCH;Chroma
TP_WAVELET_LEVDIR_ALL;All levels, in all directions TP_WAVELET_LEVDIR_ALL;All levels, in all directions
TP_WAVELET_LEVDIR_INF;Finer details levels, with selected level TP_WAVELET_LEVDIR_INF;Finer detail levels, including selected level
TP_WAVELET_LEVDIR_ONE;One level TP_WAVELET_LEVDIR_ONE;One level
TP_WAVELET_LEVDIR_SUP;Coarser details levels, without selected level TP_WAVELET_LEVDIR_SUP;Coarser detail levels, excluding selected level
TP_WAVELET_LEVELS;Wavelet levels TP_WAVELET_LEVELS;Wavelet levels
TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. TP_WAVELET_LEVELS_TOOLTIP;Choose the number of wavelet decomposition levels for the image.\nMore levels require more RAM and require a longer processing time.
TP_WAVELET_LEVF;Contrast TP_WAVELET_LEVF;Contrast
TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1
TP_WAVELET_LEVONE;Level 2 TP_WAVELET_LEVONE;Level 2
TP_WAVELET_LEVTHRE;Level 4 TP_WAVELET_LEVTHRE;Level 4
TP_WAVELET_LEVTWO;Level 3 TP_WAVELET_LEVTWO;Level 3
TP_WAVELET_LEVZERO;Level 1 TP_WAVELET_LEVZERO;Level 1
TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength TP_WAVELET_LINKEDG;Link to Edge Sharpness Strength
TP_WAVELET_LIPST;Enhanced algoritm TP_WAVELET_LIPST;Enhanced algoritm
TP_WAVELET_LOWLIGHT;Coarser levels luminance range TP_WAVELET_LOWLIGHT;Coarser levels luminance range
TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise
@ -3369,7 +3375,7 @@ TP_WAVELET_MEDGREINF;First level
TP_WAVELET_MEDI;Reduce artifacts in blue sky TP_WAVELET_MEDI;Reduce artifacts in blue sky
TP_WAVELET_MEDILEV;Edge detection TP_WAVELET_MEDILEV;Edge detection
TP_WAVELET_MEDILEV_TOOLTIP;When you enable Edge Detection, it is recommanded:\n- to disabled low contrast levels to avoid artifacts,\n- to use high values of gradient sensitivity.\n\nYou can modulate the strength with 'refine' from Denoise and Refine. TP_WAVELET_MEDILEV_TOOLTIP;When you enable Edge Detection, it is recommanded:\n- to disabled low contrast levels to avoid artifacts,\n- to use high values of gradient sensitivity.\n\nYou can modulate the strength with 'refine' from Denoise and Refine.
TP_WAVELET_MERGEC;Merge Chroma TP_WAVELET_MERGEC;Merge chroma
TP_WAVELET_MERGEL;Merge Luma TP_WAVELET_MERGEL;Merge Luma
TP_WAVELET_NEUTRAL;Neutral TP_WAVELET_NEUTRAL;Neutral
TP_WAVELET_NOIS;Denoise TP_WAVELET_NOIS;Denoise
@ -3380,24 +3386,24 @@ TP_WAVELET_NPLOW;Low
TP_WAVELET_NPNONE;None TP_WAVELET_NPNONE;None
TP_WAVELET_NPTYPE;Neighboring pixels TP_WAVELET_NPTYPE;Neighboring pixels
TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight of its neighbors. If less difference, edges are reinforced. TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight of its neighbors. If less difference, edges are reinforced.
TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\nHigh values here will amplify the contrast change of the highlights, whereas low values will amplify the contrast change of the shadows.\nAlong with a low Attenuation Response value you will able to select the contrasts that will be enhanced. TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between low contrast and high contrast details.\nHigh values will amplify contrast changes to the higher contrast details, whereas low values will amplify contrast changes to low contrast details.\nBy using a low Attenuation response value you can select which contrast values will be enhanced.
TP_WAVELET_OLDSH;Algorithm using negatives values TP_WAVELET_OLDSH;Algorithm using negatives values
TP_WAVELET_OPACITY;Opacity Blue-Yellow TP_WAVELET_OPACITY;Opacity blue-yellow
TP_WAVELET_OPACITYW;Contrast balance d/v-h curve TP_WAVELET_OPACITYW;Contrast balance d/v-h curve
TP_WAVELET_OPACITYWL;Local contrast TP_WAVELET_OPACITYWL;Local contrast
TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right.
TP_WAVELET_PASTEL;Pastel chroma TP_WAVELET_PASTEL;Pastel chroma
TP_WAVELET_PROC;Process TP_WAVELET_PROC;Process
TP_WAVELET_PROTAB;Protection TP_WAVELET_PROTAB;Protection
TP_WAVELET_RADIUS;Radius Shadows - Highlight TP_WAVELET_RADIUS;Radius shadows - highlight
TP_WAVELET_RANGEAB;Range a and b % TP_WAVELET_RANGEAB;Range a and b %
TP_WAVELET_RE1;Reinforced TP_WAVELET_RE1;Reinforced
TP_WAVELET_RE2;Unchanged TP_WAVELET_RE2;Unchanged
TP_WAVELET_RE3;Reduced TP_WAVELET_RE3;Reduced
TP_WAVELET_RESBLUR;Blur Luminance TP_WAVELET_RESBLUR;Blur luminance
TP_WAVELET_RESBLURC;Blur Chroma TP_WAVELET_RESBLURC;Blur chroma
TP_WAVELET_RESBLUR_TOOLTIP;Disabled if zoom > about 500% TP_WAVELET_RESBLUR_TOOLTIP;Disabled if zoom > about 500%
TP_WAVELET_RESCHRO;Intensity TP_WAVELET_RESCHRO;Strength
TP_WAVELET_RESCON;Shadows TP_WAVELET_RESCON;Shadows
TP_WAVELET_RESCONH;Highlights TP_WAVELET_RESCONH;Highlights
TP_WAVELET_RESID;Residual Image TP_WAVELET_RESID;Residual Image
@ -3406,15 +3412,15 @@ TP_WAVELET_SETTINGS;Wavelet Settings
TP_WAVELET_SHA;Sharp mask TP_WAVELET_SHA;Sharp mask
TP_WAVELET_SHFRAME;Shadows/Highlights TP_WAVELET_SHFRAME;Shadows/Highlights
TP_WAVELET_SHOWMASK;Show wavelet 'mask' TP_WAVELET_SHOWMASK;Show wavelet 'mask'
TP_WAVELET_SIGMA;Attenuation Response TP_WAVELET_SIGMA;Attenuation response
TP_WAVELET_SIGMAFIN;Attenuation Response TP_WAVELET_SIGMAFIN;Attenuation response
TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n .The lower it is, the more the effect will be pinpointed towards a narrow range of contrast values TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n .The lower it is, the more the effect will be pinpointed towards a narrow range of contrast values
TP_WAVELET_SKIN;Skin targetting/protection TP_WAVELET_SKIN;Skin targetting/protection
TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected.
TP_WAVELET_SKY;Sky targetting/protection TP_WAVELET_SKY;Hue targetting/protection
TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. TP_WAVELET_SKY_TOOLTIP;Allows you to target or protect a range of hues.\nAt -100 selected hues are targetted.\nAt 0 all hues are treated equally.\nAt +100 selected hues are protected while all other hues are targetted.
TP_WAVELET_SOFTRAD;Soft Radius TP_WAVELET_SOFTRAD;Soft radius
TP_WAVELET_STREN;Strength TP_WAVELET_STREN;Refine
TP_WAVELET_STRENGTH;Strength TP_WAVELET_STRENGTH;Strength
TP_WAVELET_SUPE;Extra TP_WAVELET_SUPE;Extra
TP_WAVELET_THR;Shadows threshold TP_WAVELET_THR;Shadows threshold
@ -3422,7 +3428,7 @@ TP_WAVELET_THRESHOLD;Finer levels
TP_WAVELET_THRESHOLD2;Coarser levels TP_WAVELET_THRESHOLD2;Coarser levels
TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels from the chosen value to the selected number of wavelet levels will be affected by the Shadow luminance range. TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels from the chosen value to the selected number of wavelet levels will be affected by the Shadow luminance range.
TP_WAVELET_THRESHOLD_TOOLTIP;Only levels below and including the chosen value will be affected by the Highlight luminance range. TP_WAVELET_THRESHOLD_TOOLTIP;Only levels below and including the chosen value will be affected by the Highlight luminance range.
TP_WAVELET_THRESWAV;Balance Threshold TP_WAVELET_THRESWAV;Balance threshold
TP_WAVELET_THRH;Highlights threshold TP_WAVELET_THRH;Highlights threshold
TP_WAVELET_TILESBIG;Tiles TP_WAVELET_TILESBIG;Tiles
TP_WAVELET_TILESFULL;Full image TP_WAVELET_TILESFULL;Full image
@ -3435,11 +3441,11 @@ TP_WAVELET_TMSTRENGTH;Compression strength
TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image.
TP_WAVELET_TMTYPE;Compression method TP_WAVELET_TMTYPE;Compression method
TP_WAVELET_TON;Toning TP_WAVELET_TON;Toning
TP_WAVELET_TONFRAME;Excluded Colors TP_WAVELET_TONFRAME;Excluded colors
TP_WAVELET_USH;None TP_WAVELET_USH;None
TP_WAVELET_USHARP;Clarity method TP_WAVELET_USHARP;Clarity method
TP_WAVELET_USHARP_TOOLTIP;Origin : the source file is the file before Wavelet.\nWavelet : the source file is the file including wavelet threatment TP_WAVELET_USHARP_TOOLTIP;Origin : the source file is the file before Wavelet.\nWavelet : the source file is the file including wavelet threatment
TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, wavelet settings will be automatically positioned :\nBackground=black, Process=below, level=3...you can change level between 1 and 4.\n\nIf you select Clarity, wavelet settings will be automatically positioned :\nBackground=residual, Process=above, level=7..you can change level between 5 and 10 and wavelet levels. TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, you can choose any level (in Settings) from 1 to 4 for processing.\nIf you select Clarity, you can choose any level (in Settings) between 5 and Extra.
TP_WAVELET_WAVLOWTHR;Low contrast threshold TP_WAVELET_WAVLOWTHR;Low contrast threshold
TP_WAVELET_WAVOFFSET;Offset TP_WAVELET_WAVOFFSET;Offset
TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTO;Auto

View File

@ -123,7 +123,7 @@ float* RawImageSource::CA_correct_RT(
double cared, double cared,
double cablue, double cablue,
bool avoidColourshift, bool avoidColourshift,
const array2D<float> &rawData, array2D<float> &rawData,
double* fitParamsTransfer, double* fitParamsTransfer,
bool fitParamsIn, bool fitParamsIn,
bool fitParamsOut, bool fitParamsOut,
@ -1291,7 +1291,7 @@ float* RawImageSource::CA_correct_RT(
for (int i = 0; i < H - 2 * cb; ++i) { for (int i = 0; i < H - 2 * cb; ++i) {
const int firstCol = fc(cfa, i, 0) & 1; const int firstCol = fc(cfa, i, 0) & 1;
const int colour = fc(cfa, i, firstCol); const int colour = fc(cfa, i, firstCol);
const array2D<float>* nonGreen = colour == 0 ? redFactor : blueFactor; array2D<float>* nonGreen = colour == 0 ? redFactor : blueFactor;
int j = firstCol; int j = firstCol;
#ifdef __SSE2__ #ifdef __SSE2__
for (; j < W - 7 - 2 * cb; j += 8) { for (; j < W - 7 - 2 * cb; j += 8) {
@ -1325,7 +1325,7 @@ float* RawImageSource::CA_correct_RT(
const int ngRow = 1 - (fc(cfa, 0, 0) & 1); const int ngRow = 1 - (fc(cfa, 0, 0) & 1);
const int ngCol = fc(cfa, ngRow, 0) & 1; const int ngCol = fc(cfa, ngRow, 0) & 1;
const int colour = fc(cfa, ngRow, ngCol); const int colour = fc(cfa, ngRow, ngCol);
const array2D<float>* nonGreen = colour == 0 ? redFactor : blueFactor; array2D<float>* nonGreen = colour == 0 ? redFactor : blueFactor;
for (int i = 0; i < (H + 1 - 2 * cb) / 2; ++i) { for (int i = 0; i < (H + 1 - 2 * cb) / 2; ++i) {
(*nonGreen)[i][(W - 2 * cb + 1) / 2 - 1] = (*nonGreen)[i][(W - 2* cb + 1) / 2 - 2]; (*nonGreen)[i][(W - 2 * cb + 1) / 2 - 1] = (*nonGreen)[i][(W - 2* cb + 1) / 2 - 2];
} }

View File

@ -27,7 +27,7 @@
* *
* creates an array which is valid within the normal C/C++ scope "{ ... }" * creates an array which is valid within the normal C/C++ scope "{ ... }"
* *
* access to elements is a simple as: * access to elements is as simple as:
* *
* array2D<float> my_array (10,10); // creates 10x10 array of floats * array2D<float> my_array (10,10); // creates 10x10 array of floats
* value = my_array[3][5]; * value = my_array[3][5];
@ -48,25 +48,20 @@
* array2D<float> my_array ; // empty container. * array2D<float> my_array ; // empty container.
* my_array(10,10) ; // resize to 10x10 array * my_array(10,10) ; // resize to 10x10 array
* my_array(10,10,ARRAY2D_CLEAR_DATA) ; // resize to 10x10 and clear data * my_array(10,10,ARRAY2D_CLEAR_DATA) ; // resize to 10x10 and clear data
* my_array(10,10,ARRAY2D_CLEAR_DATA|ARRAY2D_LOCK_DATA) ; same but set a lock on changes
* *
* !! locked arrays cannot be resized and cannot be unlocked again !!
*/ */
#pragma once #pragma once
#include <csignal> // for raise()
#include <cassert> #include <cassert>
#include <cstring>
#include <sys/types.h>
#include <vector>
#include "noncopyable.h"
// flags for use // flags for use
#define ARRAY2D_LOCK_DATA 1 constexpr unsigned int ARRAY2D_CLEAR_DATA = 1;
#define ARRAY2D_CLEAR_DATA 2 constexpr unsigned int ARRAY2D_BYREFERENCE = 2;
#define ARRAY2D_BYREFERENCE 4
#define ARRAY2D_VERBOSE 8
#include <cstring>
#include <cstdio>
#include "noncopyable.h"
template<typename T> template<typename T>
class array2D : class array2D :
@ -74,249 +69,158 @@ class array2D :
{ {
private: private:
int x, y, owner; ssize_t width;
unsigned int flags; std::vector<T*> rows;
T ** ptr; std::vector<T> buffer;
T * data;
bool lock; // useful lock to ensure data is not changed anymore. void initRows(ssize_t h, int offset = 0)
void ar_realloc(int w, int h, int offset = 0)
{ {
if ((ptr) && ((h > y) || (4 * h < y))) { rows.resize(h);
delete[] ptr; T* start = buffer.data() + offset;
ptr = nullptr; for (ssize_t i = 0; i < h; ++i) {
rows[i] = start + width * i;
} }
}
if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) { void ar_realloc(ssize_t w, ssize_t h, int offset = 0)
delete[] data; {
data = nullptr; width = w;
} buffer.resize(h * width + offset);
initRows(h, offset);
if (ptr == nullptr) {
ptr = new T*[h];
}
if (data == nullptr) {
data = new T[h * w + offset];
}
x = w;
y = h;
for (int i = 0; i < h; i++) {
ptr[i] = data + offset + w * i;
}
owner = 1;
} }
public: public:
// use as empty declaration, resize before use! // use as empty declaration, resize before use!
// very useful as a member object // very useful as a member object
array2D() : array2D() : width(0) {}
x(0), y(0), owner(0), flags(0), ptr(nullptr), data(nullptr), lock(false)
{
//printf("got empty array2D init\n");
}
// creator type1 // creator type1
array2D(int w, int h, unsigned int flgs = 0) array2D(int w, int h, unsigned int flags = 0) : width(w)
{ {
flags = flgs;
lock = flags & ARRAY2D_LOCK_DATA;
data = new T[h * w];
owner = 1;
x = w;
y = h;
ptr = new T*[h];
for (int i = 0; i < h; i++) {
ptr[i] = data + i * w;
}
if (flags & ARRAY2D_CLEAR_DATA) { if (flags & ARRAY2D_CLEAR_DATA) {
memset(data, 0, w * h * sizeof(T)); buffer.resize(h * width, 0);
} else {
buffer.resize(h * width);
} }
initRows(h);
} }
// creator type 2 // creator type 2
array2D(int w, int h, T ** source, unsigned int flgs = 0) array2D(int w, int h, T ** source, unsigned int flags = 0) : width(w)
{ {
flags = flgs; rows.resize(h);
//if (lock) { printf("array2D attempt to overwrite data\n");raise(SIGSEGV);} if (!(flags & ARRAY2D_BYREFERENCE)) {
lock = flags & ARRAY2D_LOCK_DATA; buffer.resize(h * width);
// when by reference T* start = buffer.data();
// TODO: improve this code with ar_realloc() for (ssize_t i = 0; i < h; ++i) {
owner = (flags & ARRAY2D_BYREFERENCE) ? 0 : 1; rows[i] = start + i * width;
for (ssize_t j = 0; j < width; ++j) {
if (owner) { rows[i][j] = source[i][j];
data = new T[h * w];
} else {
data = nullptr;
}
x = w;
y = h;
ptr = new T*[h];
for (int i = 0; i < h; i++) {
if (owner) {
ptr[i] = data + i * w;
for (int j = 0; j < w; j++) {
ptr[i][j] = source[i][j];
} }
} else {
ptr[i] = source[i];
} }
} } else {
} for (ssize_t i = 0; i < h; ++i) {
rows[i] = source[i];
// destructor }
~array2D()
{
if (flags & ARRAY2D_VERBOSE) {
printf(" deleting array2D size %dx%d \n", x, y);
}
if ((owner) && (data)) {
delete[] data;
}
if (ptr) {
delete[] ptr;
} }
} }
void fill(const T val, bool multiThread = false) void fill(const T val, bool multiThread = false)
{ {
const ssize_t height = rows.size();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for if(multiThread) #pragma omp parallel for if(multiThread)
#endif #endif
for (int i = 0; i < x * y; ++i) { for (ssize_t i = 0; i < width * height; ++i) {
data[i] = val; buffer[i] = val;
} }
} }
void free() void free()
{ {
if ((owner) && (data)) { buffer.clear();
delete[] data; rows.clear();
data = nullptr;
}
if (ptr) {
delete [] ptr;
ptr = nullptr;
}
} }
// use with indices // use with indices
T * operator[](int index) const T * operator[](int index)
{ {
assert((index >= 0) && (index < y)); assert((index >= 0) && (index < rows.size()));
return ptr[index]; return rows[index];
}
const T * operator[](int index) const
{
assert((index >= 0) && (index < rows.size()));
return rows[index];
} }
// use as pointer to T** // use as pointer to T**
operator T**() operator T**()
{ {
return ptr; return rows.data();
} }
// use as pointer to T** // use as pointer to T**
operator const T* const *() operator const T* const *() const
{ {
return ptr; return rows.data();
} }
// use as pointer to data // use as pointer to buffer
operator T*() operator T*()
{ {
// only if owner this will return a valid pointer // only if owner this will return a valid pointer
return data; return buffer.data();
}
operator const T*() const
{
// only if owner this will return a valid pointer
return buffer.data();
} }
// useful within init of parent object // useful within init of parent object
// or use as resize of 2D array // or use as resize of 2D array
void operator()(int w, int h, unsigned int flgs = 0, int offset = 0) void operator()(int w, int h, unsigned int flags = 0, int offset = 0)
{ {
flags = flgs;
if (flags & ARRAY2D_VERBOSE) {
printf("got init request %dx%d flags=%u\n", w, h, flags);
printf("previous was data %p ptr %p \n", data, ptr);
}
if (lock) { // our object was locked so don't allow a change.
printf("got init request but object was locked!\n");
raise( SIGSEGV);
}
lock = flags & ARRAY2D_LOCK_DATA;
ar_realloc(w, h, offset); ar_realloc(w, h, offset);
if (flags & ARRAY2D_CLEAR_DATA) { if (flags & ARRAY2D_CLEAR_DATA) {
memset(data + offset, 0, static_cast<unsigned long>(w) * h * sizeof(T)); fill(0);
} }
} }
// import from flat data int getWidth() const
void operator()(int w, int h, T* copy, unsigned int flgs = 0)
{ {
flags = flgs; return width;
if (flags & ARRAY2D_VERBOSE) {
printf("got init request %dx%d flags=%u\n", w, h, flags);
printf("previous was data %p ptr %p \n", data, ptr);
}
if (lock) { // our object was locked so don't allow a change.
printf("got init request but object was locked!\n");
raise( SIGSEGV);
}
lock = flags & ARRAY2D_LOCK_DATA;
ar_realloc(w, h);
memcpy(data, copy, w * h * sizeof(T));
} }
int width() const int getHeight() const
{ {
return x; return rows.size();
}
int height() const
{
return y;
} }
operator bool() operator bool()
{ {
return (x > 0 && y > 0); return (width > 0 && !rows.empty());
} }
}; };
template<typename T, const size_t num> template<typename T, const size_t num>
class multi_array2D class multi_array2D : public rtengine::NonCopyable
{ {
private: private:
array2D<T> list[num]; array2D<T> list[num];
public: public:
multi_array2D(int x, int y, int flags = 0, int offset = 0) multi_array2D(int width, int height, int flags = 0, int offset = 0)
{ {
for (size_t i = 0; i < num; i++) { for (size_t i = 0; i < num; ++i) {
list[i](x, y, flags, (i + 1) * offset); list[i](width, height, flags, (i + 1) * offset);
} }
} }
~multi_array2D()
{
//printf("trying to delete the list of array2D objects\n");
}
array2D<T> & operator[](int index) array2D<T> & operator[](int index)
{ {
assert(static_cast<size_t>(index) < num); assert(static_cast<size_t>(index) < num);

View File

@ -1401,9 +1401,17 @@ Camera constants:
"ranges": { "white": [ 16105, 16270, 16082 ] } // These values are the lowest pixel values >16000 for all ISOs. LENR has a negligble effect. "ranges": { "white": [ 16105, 16270, 16082 ] } // These values are the lowest pixel values >16000 for all ISOs. LENR has a negligble effect.
// No aperture scaling data provided, but likely negligible // No aperture scaling data provided, but likely negligible
}, },
{ // Quality C, only raw crop { // Quality A, samples provided by Daniel Catalina (#5839) and pi99y (#5860)
"make_model": [ "FUJIFILM X-T3", "FUJIFILM X-T30", "FUJIFILM X-PRO3", "FUJIFILM X100V", "FUJIFILM X-T4" ], "make_model": [ "FUJIFILM X-T3", "FUJIFILM X-PRO3" ],
"dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v11, standard_v2 d65
"raw_crop": [ 0, 5, 6252, 4176],
"white": [ 16170, 16275, 16170 ] // typical safe-margins with LENR
// negligible aperture scaling effect
},
{ // Quality B
"make_model": [ "FUJIFILM X-T30", "FUJIFILM X100V", "FUJIFILM X-T4" ],
"dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v11, standard_v2 d65 "dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v11, standard_v2 d65
"raw_crop": [ 0, 5, 6252, 4176] "raw_crop": [ 0, 5, 6252, 4176]
}, },
@ -2747,6 +2755,12 @@ Camera constants:
"ranges": { "black": 0, "white": 64400 } "ranges": { "black": 0, "white": 64400 }
}, },
{ // Quality B
"make_model": ["HASSELBLAD NEX-7", "SONY NEX-7"], // Hasselblad NEX-7 also known as Hasselblad Lunar
"dcraw_matrix": [ 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 ], // adobe DNGv12.2 d65
"ranges": { "black": 512, "white": 16372 } // Typical white level (samples provided by @ggc on Pixls, influence from LENR unknown
},
{ // Quality A for tested CFV, the other models have the same sensor (16 megapixel square sensor) { // Quality A for tested CFV, the other models have the same sensor (16 megapixel square sensor)
"make_model": [ "Hasselblad V96C", "Hasselblad CFV", "Hasselblad CFV-II" ], "make_model": [ "Hasselblad V96C", "Hasselblad CFV", "Hasselblad CFV-II" ],
"dcraw_matrix": [ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809 ] // borrowed from Adobe's DNG converter "dcraw_matrix": [ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809 ] // borrowed from Adobe's DNG converter

View File

@ -1772,7 +1772,7 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b,
} }
} }
void Color::RGB2L(float *R, float *G, float *B, float *L, const float wp[3][3], int width) void Color::RGB2L(const float *R, const float *G, const float *B, float *L, const float wp[3][3], int width)
{ {
#ifdef __SSE2__ #ifdef __SSE2__

View File

@ -623,7 +623,7 @@ public:
static void XYZ2Lab(float x, float y, float z, float &L, float &a, float &b); static void XYZ2Lab(float x, float y, float z, float &L, float &a, float &b);
static void RGB2Lab(float *X, float *Y, float *Z, float *L, float *a, float *b, const float wp[3][3], int width); static void RGB2Lab(float *X, float *Y, float *Z, float *L, float *a, float *b, const float wp[3][3], int width);
static void Lab2RGBLimit(float *L, float *a, float *b, float *R, float *G, float *B, const float wp[3][3], float limit, float afactor, float bfactor, int width); static void Lab2RGBLimit(float *L, float *a, float *b, float *R, float *G, float *B, const float wp[3][3], float limit, float afactor, float bfactor, int width);
static void RGB2L(float *X, float *Y, float *Z, float *L, const float wp[3][3], int width); static void RGB2L(const float *R, const float *G, const float *B, float *L, const float wp[3][3], int width);
/** /**
* @brief Convert Lab in Yuv * @brief Convert Lab in Yuv

View File

@ -82,8 +82,8 @@ int calculate_subsampling(int w, int h, int r)
void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2D<float> &dst, int r, float epsilon, bool multithread, int subsampling) void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2D<float> &dst, int r, float epsilon, bool multithread, int subsampling)
{ {
const int W = src.width(); const int W = src.getWidth();
const int H = src.height(); const int H = src.getHeight();
if (subsampling <= 0) { if (subsampling <= 0) {
subsampling = calculate_subsampling(W, H, r); subsampling = calculate_subsampling(W, H, r);
@ -94,8 +94,8 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
const auto apply = const auto apply =
[=](Op op, array2D<float> &res, const array2D<float> &a, const array2D<float> &b, const array2D<float> &c=array2D<float>()) -> void [=](Op op, array2D<float> &res, const array2D<float> &a, const array2D<float> &b, const array2D<float> &c=array2D<float>()) -> void
{ {
const int w = res.width(); const int w = res.getWidth();
const int h = res.height(); const int h = res.getHeight();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for if (multithread) #pragma omp parallel for if (multithread)
@ -142,12 +142,12 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
const auto f_subsample = const auto f_subsample =
[=](array2D<float> &d, const array2D<float> &s) -> void [=](array2D<float> &d, const array2D<float> &s) -> void
{ {
if (d.width() == s.width() && d.height() == s.height()) { if (d.getWidth() == s.getWidth() && d.getHeight() == s.getHeight()) {
#ifdef _OPENMP #ifdef _OPENMP
# pragma omp parallel for if (multithread) # pragma omp parallel for if (multithread)
#endif #endif
for (int y = 0; y < s.height(); ++y) { for (int y = 0; y < s.getHeight(); ++y) {
for (int x = 0; x < s.width(); ++x) { for (int x = 0; x < s.getWidth(); ++x) {
d[y][x] = s[y][x]; d[y][x] = s[y][x];
} }
} }
@ -164,9 +164,9 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
const auto f_mean = const auto f_mean =
[multithread](array2D<float> &d, array2D<float> &s, int rad) -> void [multithread](array2D<float> &d, array2D<float> &s, int rad) -> void
{ {
rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1); rad = LIM(rad, 0, (min(s.getWidth(), s.getHeight()) - 1) / 2 - 1);
// boxblur(s, d, rad, s.width(), s.height(), multithread); // boxblur(s, d, rad, s.getWidth(), s.getHeight(), multithread);
boxblur(static_cast<float**>(s), static_cast<float**>(d), rad, s.width(), s.height(), multithread); boxblur(static_cast<float**>(s), static_cast<float**>(d), rad, s.getWidth(), s.getHeight(), multithread);
}; };
array2D<float> I1(w, h); array2D<float> I1(w, h);
@ -225,10 +225,10 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
DEBUG_DUMP(meanb); DEBUG_DUMP(meanb);
// speedup by heckflosse67 // speedup by heckflosse67
const int Ws = meana.width(); const int Ws = meana.getWidth();
const int Hs = meana.height(); const int Hs = meana.getHeight();
const int Wd = q.width(); const int Wd = q.getWidth();
const int Hd = q.height(); const int Hd = q.getHeight();
const float col_scale = float(Ws) / float(Wd); const float col_scale = float(Ws) / float(Wd);
const float row_scale = float(Hs) / float(Hd); const float row_scale = float(Hs) / float(Hd);
@ -249,8 +249,8 @@ void guidedFilterLog(const array2D<float> &guide, float base, array2D<float> &ch
#ifdef _OPENMP #ifdef _OPENMP
# pragma omp parallel for if (multithread) # pragma omp parallel for if (multithread)
#endif #endif
for (int y = 0; y < chan.height(); ++y) { for (int y = 0; y < chan.getHeight(); ++y) {
for (int x = 0; x < chan.width(); ++x) { for (int x = 0; x < chan.getWidth(); ++x) {
chan[y][x] = xlin2log(max(chan[y][x], 0.f), base); chan[y][x] = xlin2log(max(chan[y][x], 0.f), base);
} }
} }
@ -260,8 +260,8 @@ void guidedFilterLog(const array2D<float> &guide, float base, array2D<float> &ch
#ifdef _OPENMP #ifdef _OPENMP
# pragma omp parallel for if (multithread) # pragma omp parallel for if (multithread)
#endif #endif
for (int y = 0; y < chan.height(); ++y) { for (int y = 0; y < chan.getHeight(); ++y) {
for (int x = 0; x < chan.width(); ++x) { for (int x = 0; x < chan.getWidth(); ++x) {
chan[y][x] = xlog2lin(max(chan[y][x], 0.f), base); chan[y][x] = xlog2lin(max(chan[y][x], 0.f), base);
} }
} }

View File

@ -103,10 +103,10 @@ void restore(Imagefloat *rgb, float maxval, bool multithread)
} }
} }
int get_dark_channel(const array2D<float> &R, const array2D<float> &G, const array2D<float> &B, const array2D<float> &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength) int get_dark_channel(const array2D<float> &R, const array2D<float> &G, const array2D<float> &B, array2D<float> &dst, int patchsize, const float ambient[3], bool clip, bool multithread, float strength)
{ {
const int W = R.width(); const int W = R.getWidth();
const int H = R.height(); const int H = R.getHeight();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for if (multithread) #pragma omp parallel for if (multithread)
@ -162,10 +162,10 @@ int get_dark_channel(const array2D<float> &R, const array2D<float> &G, const arr
return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0)); return (W / patchsize + ((W % patchsize) > 0)) * (H / patchsize + ((H % patchsize) > 0));
} }
int get_dark_channel_downsized(const array2D<float> &R, const array2D<float> &G, const array2D<float> &B, const array2D<float> &dst, int patchsize, bool multithread) int get_dark_channel_downsized(const array2D<float> &R, const array2D<float> &G, const array2D<float> &B, array2D<float> &dst, int patchsize, bool multithread)
{ {
const int W = R.width(); const int W = R.getWidth();
const int H = R.height(); const int H = R.getHeight();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for if (multithread) #pragma omp parallel for if (multithread)
@ -195,8 +195,8 @@ int get_dark_channel_downsized(const array2D<float> &R, const array2D<float> &G,
float estimate_ambient_light(const array2D<float> &R, const array2D<float> &G, const array2D<float> &B, const array2D<float> &dark, int patchsize, int npatches, float ambient[3]) float estimate_ambient_light(const array2D<float> &R, const array2D<float> &G, const array2D<float> &B, const array2D<float> &dark, int patchsize, int npatches, float ambient[3])
{ {
const int W = R.width(); const int W = R.getWidth();
const int H = R.height(); const int H = R.getHeight();
float darklim = RT_INFINITY_F; float darklim = RT_INFINITY_F;
{ {

View File

@ -1840,8 +1840,8 @@ void tone_eq(array2D<float> &R, array2D<float> &G, array2D<float> &B, const stru
{ {
BENCHFUN BENCHFUN
const int W = R.width(); const int W = R.getWidth();
const int H = R.height(); const int H = R.getHeight();
array2D<float> Y(W, H); array2D<float> Y(W, H);
const auto log2 = const auto log2 =

View File

@ -323,14 +323,14 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
} }
cp.CHSLmet = 1; cp.CHSLmet = 1;
cp.EDmet = 1; cp.EDmet = 2;
/*
if (params->wavelet.EDmethod == "SL") { if (params->wavelet.EDmethod == "SL") {
cp.EDmet = 1; cp.EDmet = 1;
} else if (params->wavelet.EDmethod == "CU") { } else if (params->wavelet.EDmethod == "CU") {
cp.EDmet = 2; cp.EDmet = 2;
} }
*/
cp.cbena = params->wavelet.cbenab; cp.cbena = params->wavelet.cbenab;
cp.blhigh = (float)params->wavelet.bluehigh; cp.blhigh = (float)params->wavelet.bluehigh;
cp.grhigh = (float)params->wavelet.greenhigh; cp.grhigh = (float)params->wavelet.greenhigh;
@ -1579,10 +1579,16 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
if (numtiles > 1) { if (numtiles > 1) {
float factor = Vmask[i1] * Hmask[j1]; float factor = Vmask[i1] * Hmask[j1];
if(L <= 0.f) {
L= 1.f;
}
dsttmp->L[i][j] += factor * L; dsttmp->L[i][j] += factor * L;
dsttmp->a[i][j] += factor * a; dsttmp->a[i][j] += factor * a;
dsttmp->b[i][j] += factor * b; dsttmp->b[i][j] += factor * b;
} else { } else {
if(L <= 0.f) {
L= 1.f;
}
dsttmp->L[i][j] = L; dsttmp->L[i][j] = L;
dsttmp->a[i][j] = a; dsttmp->a[i][j] = a;
dsttmp->b[i][j] = b; dsttmp->b[i][j] = b;
@ -2073,7 +2079,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
ContrastResid(WavCoeffs_L0, cp, W_L, H_L, maxp); ContrastResid(WavCoeffs_L0, cp, W_L, H_L, maxp);
} }
if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step // if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step
if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step
const std::unique_ptr<LabImage> temp(new LabImage(W_L, H_L)); const std::unique_ptr<LabImage> temp(new LabImage(W_L, H_L));
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1) #pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1)
@ -2098,7 +2105,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
} }
} }
if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step // if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step
if ((cp.conres < 0.f || cp.conresH < 0.f) && cp.resena) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
#endif #endif
@ -2208,9 +2216,9 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
for (int lvl = 0; lvl < 4; lvl++) { for (int lvl = 0; lvl < 4; lvl++) {
for (int dir = 1; dir < 4; dir++) { for (int dir = 1; dir < 4; dir++) {
const float* const* WavCoeffs_LL = WaveletCoeffs_L.level_coeffs(lvl); const float* const* WavCoeffs_LL = WaveletCoeffs_L.level_coeffs(lvl);
float tempkoeli; float tempkoeli = 0.f;
calckoe (WavCoeffs_LL, gradw, tloww, koeLi, lvl , dir, W_L, H_L, edd, tempkoeli, tmC); calckoe (WavCoeffs_LL, gradw, tloww, koeLi, lvl , dir, W_L, H_L, edd, tempkoeli, tmC);
maxkoeLi[lvl * 3 + dir - 1] = tempkoeli; maxkoeLi[lvl * 3 + dir - 1] = tempkoeli ;
// return convolution KoeLi and maxkoeLi of level 0 1 2 3 and Dir Horiz, Vert, Diag // return convolution KoeLi and maxkoeLi of level 0 1 2 3 and Dir Horiz, Vert, Diag
} }
} }
@ -2766,7 +2774,6 @@ void ImProcFunctions::calckoe (const float* const* WavCoeffs_LL, float gradw, fl
if (koeLi[level * 3 + dir - 1][i * W_L + j] > maxkoeLi) { if (koeLi[level * 3 + dir - 1][i * W_L + j] > maxkoeLi) {
maxkoeLi = koeLi[level * 3 + dir - 1][i * W_L + j]; maxkoeLi = koeLi[level * 3 + dir - 1][i * W_L + j];
} }
float diff = maxkoeLi - koeLi[level * 3 + dir - 1][i * W_L + j]; float diff = maxkoeLi - koeLi[level * 3 + dir - 1][i * W_L + j];
diff *= diffFactor; diff *= diffFactor;
koeLi[level * 3 + dir - 1][i * W_L + j] = maxkoeLi - diff; koeLi[level * 3 + dir - 1][i * W_L + j] = maxkoeLi - diff;
@ -2781,13 +2788,13 @@ void ImProcFunctions::finalContAllL(float* const* WavCoeffs_L, float * WavCoeffs
if (cp.diagcurv && cp.finena && MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { //curve if (cp.diagcurv && cp.finena && MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { //curve
float insigma = 0.666f; //SD float insigma = 0.666f; //SD
float logmax = log(MaxP[level]); //log Max float logmax = log(MaxP[level]); //log Max
float rapX = (mean[level] + cp.sigmafin * sigma[level]) / MaxP[level]; //rapport between sD / max float rapX = (mean[level] + cp.sigmafin * sigma[level]) / (MaxP[level]); //rapport between sD / max
float inx = log(insigma); float inx = log(insigma);
float iny = log(rapX); float iny = log(rapX);
float rap = inx / iny; //koef float rap = inx / iny; //koef
float asig = 0.166f / (sigma[level] * cp.sigmafin); float asig = 0.166f / (sigma[level] * cp.sigmafin);
float bsig = 0.5f - asig * mean[level]; float bsig = 0.5f - asig * mean[level];
float amean = 0.5f / mean[level]; float amean = 0.5f / (mean[level]);
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for schedule(dynamic, W_L * 16) num_threads(wavNestedLevels) if (wavNestedLevels>1) #pragma omp parallel for schedule(dynamic, W_L * 16) num_threads(wavNestedLevels) if (wavNestedLevels>1)
@ -3058,7 +3065,6 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
koe[i * W_L + j] = rtengine::min(thr2, std::fabs(tmC[i][j] / temp)); koe[i * W_L + j] = rtengine::min(thr2, std::fabs(tmC[i][j] / temp));
maxkoe = rtengine::max(maxkoe, koe[i * W_L + j]); maxkoe = rtengine::max(maxkoe, koe[i * W_L + j]);
float diff = maxkoe - koe[i * W_L + j]; float diff = maxkoe - koe[i * W_L + j];
diff *= (cp.eddet / 100.f); diff *= (cp.eddet / 100.f);
float interm = maxkoe - diff; float interm = maxkoe - diff;
@ -3089,10 +3095,13 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
float atten01234 = 0.80f; float atten01234 = 0.80f;
value *= (atten01234 * scaleskip[1]); //for zoom < 100% reduce strength...I choose level 1...but!! value *= (atten01234 * scaleskip[1]); //for zoom < 100% reduce strength...I choose level 1...but!!
} }
float edghig = settings->edghi;//increase or reduce "reinforce"
float edglow = settings->edglo;//increase or reduce "reduce"
float limrad = settings->limrad;//threshold action in function radius (rad)
printf("edghi=%f edglo=%f limrad=%f\n", edghig, edglow, limrad);
// value *= beta; // value *= beta;
float edge = 1.f; float edge = 1.f;
float lim0 = 20.f; //arbitrary limit for low radius and level between 2 or 3 to 30 maxi float lim0 = limrad; //arbitrary limit for low radius and level between 2 or 3 to 30 maxi
float lev = float (level); float lev = float (level);
float repart = (float)cp.til; float repart = (float)cp.til;
@ -3100,15 +3109,14 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
if (cp.reinforce != 2) { if (cp.reinforce != 2) {
const float brepart = const float brepart =
cp.reinforce == 1 cp.reinforce == 1
? 3.f ? edghig
: 0.5f; : edglow;
const float arepart = -(brepart - 1.f) / (lim0 / 60.f); const float arepart = -(brepart - 1.f) / (lim0 / 60.f);
if (rad < lim0 / 60.f) { if (rad < (lim0 / 60.f)) {
repart *= (arepart * rad + brepart); //linear repartition of repart repart *= (arepart * rad + brepart); //linear repartition of repart
} }
} }
float al0 = 1.f + (repart) / 50.f; float al0 = 1.f + (repart) / 50.f;
float al10 = 1.0f; //arbitrary value ==> less = take into account high levels float al10 = 1.0f; //arbitrary value ==> less = take into account high levels
// float ak =-(al0-al10)/10.f;//10 = maximum levels // float ak =-(al0-al10)/10.f;//10 = maximum levels
@ -3116,15 +3124,16 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
float bk = al0; float bk = al0;
float koef = ak * level + bk; //modulate for levels : more levels high, more koef low ==> concentrated action on low levels, without or near for high levels float koef = ak * level + bk; //modulate for levels : more levels high, more koef low ==> concentrated action on low levels, without or near for high levels
float expkoef = -std::pow(std::fabs(rad - lev), koef); //reduce effect for high levels float expkoef = -std::pow(std::fabs(rad - lev), koef); //reduce effect for high levels
printf("repart=%f\n", repart);
if (cp.reinforce == 3) { if (cp.reinforce == 3) {
if (rad < lim0 / 60.f && level == 0) { if (rad < (lim0 / 60.f) && level == 0) {
expkoef *= abs(repart); //reduce effect for low values of rad and level=0==> quasi only level 1 is effective expkoef *= abs(repart); //reduce effect for low values of rad and level=0==> quasi only level 1 is effective
} }
} }
if (cp.reinforce == 1) { if (cp.reinforce == 1) {
if (rad < lim0 / 60.f && level == 1) { if (rad < (lim0 / 60.f) && level == 1) {
expkoef /= repart; //increase effect for low values of rad and level=1==> quasi only level 0 is effective expkoef /= repart; //increase effect for low values of rad and level=1==> quasi only level 0 is effective
} }
} }
@ -3158,13 +3167,13 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
// if (exa) {//curve // if (exa) {//curve
float insigma = 0.666f; //SD float insigma = 0.666f; //SD
float logmax = log(MaxP[level]); //log Max float logmax = log(MaxP[level]); //log Max
float rapX = (mean[level] + sigma[level]) / MaxP[level]; //rapport between sD / max float rapX = (mean[level] + sigma[level]) / (MaxP[level]); //rapport between sD / max
float inx = log(insigma); float inx = log(insigma);
float iny = log(rapX); float iny = log(rapX);
float rap = inx / iny; //koef float rap = inx / iny; //koef
float asig = 0.166f / sigma[level]; float asig = 0.166f / (sigma[level]);
float bsig = 0.5f - asig * mean[level]; float bsig = 0.5f - asig * mean[level];
float amean = 0.5f / mean[level]; float amean = 0.5f / (mean[level]);
float absciss = 0.f; float absciss = 0.f;
float kinterm; float kinterm;
float kmul; float kmul;

View File

@ -459,6 +459,7 @@ RetinexParams::RetinexParams() :
shadows(0), shadows(0),
stonalwidth(80), stonalwidth(80),
radius(40), radius(40),
complexmethod("normal"),
retinexMethod("high"), retinexMethod("high"),
retinexcolorspace("Lab"), retinexcolorspace("Lab"),
gammaretinex("none"), gammaretinex("none"),
@ -496,6 +497,7 @@ bool RetinexParams::operator ==(const RetinexParams& other) const
&& shadows == other.shadows && shadows == other.shadows
&& stonalwidth == other.stonalwidth && stonalwidth == other.stonalwidth
&& radius == other.radius && radius == other.radius
&& complexmethod == other.complexmethod
&& retinexMethod == other.retinexMethod && retinexMethod == other.retinexMethod
&& retinexcolorspace == other.retinexcolorspace && retinexcolorspace == other.retinexcolorspace
&& gammaretinex == other.gammaretinex && gammaretinex == other.gammaretinex
@ -2395,6 +2397,7 @@ WaveletParams::WaveletParams() :
CLmethod("all"), CLmethod("all"),
Backmethod("grey"), Backmethod("grey"),
Tilesmethod("full"), Tilesmethod("full"),
complexmethod("normal"),
daubcoeffmethod("4_"), daubcoeffmethod("4_"),
CHmethod("without"), CHmethod("without"),
Medgreinf("less"), Medgreinf("less"),
@ -2527,6 +2530,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const
&& CLmethod == other.CLmethod && CLmethod == other.CLmethod
&& Backmethod == other.Backmethod && Backmethod == other.Backmethod
&& Tilesmethod == other.Tilesmethod && Tilesmethod == other.Tilesmethod
&& complexmethod == other.complexmethod
&& daubcoeffmethod == other.daubcoeffmethod && daubcoeffmethod == other.daubcoeffmethod
&& CHmethod == other.CHmethod && CHmethod == other.CHmethod
&& Medgreinf == other.Medgreinf && Medgreinf == other.Medgreinf
@ -5025,6 +5029,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->retinex.limd, "Retinex", "Limd", retinex.limd, keyFile); saveToKeyfile(!pedited || pedited->retinex.limd, "Retinex", "Limd", retinex.limd, keyFile);
saveToKeyfile(!pedited || pedited->retinex.highl, "Retinex", "highl", retinex.highl, keyFile); saveToKeyfile(!pedited || pedited->retinex.highl, "Retinex", "highl", retinex.highl, keyFile);
saveToKeyfile(!pedited || pedited->retinex.skal, "Retinex", "skal", retinex.skal, keyFile); saveToKeyfile(!pedited || pedited->retinex.skal, "Retinex", "skal", retinex.skal, keyFile);
saveToKeyfile(!pedited || pedited->retinex.complexmethod, "Retinex", "complexMethod", retinex.complexmethod, keyFile);
saveToKeyfile(!pedited || pedited->retinex.retinexMethod, "Retinex", "RetinexMethod", retinex.retinexMethod, keyFile); saveToKeyfile(!pedited || pedited->retinex.retinexMethod, "Retinex", "RetinexMethod", retinex.retinexMethod, keyFile);
saveToKeyfile(!pedited || pedited->retinex.mapMethod, "Retinex", "mapMethod", retinex.mapMethod, keyFile); saveToKeyfile(!pedited || pedited->retinex.mapMethod, "Retinex", "mapMethod", retinex.mapMethod, keyFile);
saveToKeyfile(!pedited || pedited->retinex.viewMethod, "Retinex", "viewMethod", retinex.viewMethod, keyFile); saveToKeyfile(!pedited || pedited->retinex.viewMethod, "Retinex", "viewMethod", retinex.viewMethod, keyFile);
@ -5988,6 +5993,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile); saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.complexmethod, "Wavelet", "complexMethod", wavelet.complexmethod, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.daubcoeffmethod, "Wavelet", "DaubMethod", wavelet.daubcoeffmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.daubcoeffmethod, "Wavelet", "DaubMethod", wavelet.daubcoeffmethod, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.CLmethod, "Wavelet", "ChoiceLevMethod", wavelet.CLmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.CLmethod, "Wavelet", "ChoiceLevMethod", wavelet.CLmethod, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.Backmethod, "Wavelet", "BackMethod", wavelet.Backmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Backmethod, "Wavelet", "BackMethod", wavelet.Backmethod, keyFile);
@ -6494,6 +6500,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
if (keyFile.has_group("Retinex")) { if (keyFile.has_group("Retinex")) {
assignFromKeyfile(keyFile, "Retinex", "Median", pedited, retinex.medianmap, pedited->retinex.medianmap); assignFromKeyfile(keyFile, "Retinex", "Median", pedited, retinex.medianmap, pedited->retinex.medianmap);
assignFromKeyfile(keyFile, "Retinex", "complexMethod", pedited, retinex.complexmethod, pedited->retinex.complexmethod);
assignFromKeyfile(keyFile, "Retinex", "RetinexMethod", pedited, retinex.retinexMethod, pedited->retinex.retinexMethod); assignFromKeyfile(keyFile, "Retinex", "RetinexMethod", pedited, retinex.retinexMethod, pedited->retinex.retinexMethod);
assignFromKeyfile(keyFile, "Retinex", "mapMethod", pedited, retinex.mapMethod, pedited->retinex.mapMethod); assignFromKeyfile(keyFile, "Retinex", "mapMethod", pedited, retinex.mapMethod, pedited->retinex.mapMethod);
assignFromKeyfile(keyFile, "Retinex", "viewMethod", pedited, retinex.viewMethod, pedited->retinex.viewMethod); assignFromKeyfile(keyFile, "Retinex", "viewMethod", pedited, retinex.viewMethod, pedited->retinex.viewMethod);
@ -7858,6 +7865,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Wavelet", "ChoiceLevMethod", pedited, wavelet.CLmethod, pedited->wavelet.CLmethod); assignFromKeyfile(keyFile, "Wavelet", "ChoiceLevMethod", pedited, wavelet.CLmethod, pedited->wavelet.CLmethod);
assignFromKeyfile(keyFile, "Wavelet", "BackMethod", pedited, wavelet.Backmethod, pedited->wavelet.Backmethod); assignFromKeyfile(keyFile, "Wavelet", "BackMethod", pedited, wavelet.Backmethod, pedited->wavelet.Backmethod);
assignFromKeyfile(keyFile, "Wavelet", "TilesMethod", pedited, wavelet.Tilesmethod, pedited->wavelet.Tilesmethod); assignFromKeyfile(keyFile, "Wavelet", "TilesMethod", pedited, wavelet.Tilesmethod, pedited->wavelet.Tilesmethod);
assignFromKeyfile(keyFile, "Wavelet", "complexMethod", pedited, wavelet.complexmethod, pedited->wavelet.complexmethod);
assignFromKeyfile(keyFile, "Wavelet", "DaubMethod", pedited, wavelet.daubcoeffmethod, pedited->wavelet.daubcoeffmethod); assignFromKeyfile(keyFile, "Wavelet", "DaubMethod", pedited, wavelet.daubcoeffmethod, pedited->wavelet.daubcoeffmethod);
assignFromKeyfile(keyFile, "Wavelet", "CHromaMethod", pedited, wavelet.CHmethod, pedited->wavelet.CHmethod); assignFromKeyfile(keyFile, "Wavelet", "CHromaMethod", pedited, wavelet.CHmethod, pedited->wavelet.CHmethod);
assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", pedited, wavelet.Medgreinf, pedited->wavelet.Medgreinf); assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", pedited, wavelet.Medgreinf, pedited->wavelet.Medgreinf);

View File

@ -336,6 +336,7 @@ struct RetinexParams {
int stonalwidth; int stonalwidth;
int radius; int radius;
Glib::ustring complexmethod;
Glib::ustring retinexMethod; Glib::ustring retinexMethod;
Glib::ustring retinexcolorspace; Glib::ustring retinexcolorspace;
Glib::ustring gammaretinex; Glib::ustring gammaretinex;
@ -1790,6 +1791,7 @@ struct WaveletParams {
Glib::ustring CLmethod; Glib::ustring CLmethod;
Glib::ustring Backmethod; Glib::ustring Backmethod;
Glib::ustring Tilesmethod; Glib::ustring Tilesmethod;
Glib::ustring complexmethod;
Glib::ustring daubcoeffmethod; Glib::ustring daubcoeffmethod;
Glib::ustring CHmethod; Glib::ustring CHmethod;
Glib::ustring Medgreinf; Glib::ustring Medgreinf;

View File

@ -247,7 +247,7 @@ protected:
double cared, double cared,
double cablue, double cablue,
bool avoidColourshift, bool avoidColourshift,
const array2D<float> &rawData, array2D<float> &rawData,
double* fitParamsTransfer, double* fitParamsTransfer,
bool fitParamsIn, bool fitParamsIn,
bool fitParamsOut, bool fitParamsOut,

View File

@ -31,8 +31,8 @@ namespace rtengine
inline float getBilinearValue(const array2D<float> &src, float x, float y) inline float getBilinearValue(const array2D<float> &src, float x, float y)
{ {
const int W = src.width(); const int W = src.getWidth();
const int H = src.height(); const int H = src.getHeight();
// Get integer and fractional parts of numbers // Get integer and fractional parts of numbers
int xi = x; int xi = x;
@ -57,10 +57,10 @@ inline float getBilinearValue(const array2D<float> &src, float x, float y)
inline void rescaleBilinear(const array2D<float> &src, array2D<float> &dst, bool multithread) inline void rescaleBilinear(const array2D<float> &src, array2D<float> &dst, bool multithread)
{ {
const int Ws = src.width(); const int Ws = src.getWidth();
const int Hs = src.height(); const int Hs = src.getHeight();
const int Wd = dst.width(); const int Wd = dst.getWidth();
const int Hd = dst.height(); const int Hd = dst.getHeight();
float col_scale = float (Ws) / float (Wd); float col_scale = float (Ws) / float (Wd);
float row_scale = float (Hs) / float (Hd); float row_scale = float (Hs) / float (Hd);
@ -81,10 +81,10 @@ inline void rescaleBilinear(const array2D<float> &src, array2D<float> &dst, bool
inline void rescaleNearest(const array2D<float> &src, array2D<float> &dst, bool multithread) inline void rescaleNearest(const array2D<float> &src, array2D<float> &dst, bool multithread)
{ {
const int width = src.width(); const int width = src.getWidth();
const int height = src.height(); const int height = src.getHeight();
const int nw = dst.width(); const int nw = dst.getWidth();
const int nh = dst.height(); const int nh = dst.getHeight();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for if (multithread) #pragma omp parallel for if (multithread)

View File

@ -99,6 +99,10 @@ public:
int itcwb_delta; int itcwb_delta;
bool itcwb_stdobserver10; bool itcwb_stdobserver10;
int itcwb_precis; int itcwb_precis;
//wavelet levels
double edghi;
double edglo;
double limrad;
enum class ThumbnailInspectorMode { enum class ThumbnailInspectorMode {

View File

@ -123,12 +123,12 @@ public:
int getRows() const int getRows() const
{ {
return const_cast<Array2Df &>(*this).height(); return const_cast<Array2Df &>(*this).getHeight();
} }
int getCols() const int getCols() const
{ {
return const_cast<Array2Df &>(*this).width(); return const_cast<Array2Df &>(*this).getWidth();
} }
float *data() float *data()

View File

@ -42,6 +42,7 @@
#include "pathutils.h" #include "pathutils.h"
#include "thumbnail.h" #include "thumbnail.h"
#include "toolbar.h" #include "toolbar.h"
#include "inspector.h"
using namespace std; using namespace std;
@ -2508,6 +2509,15 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event)
} }
} }
if (!ctrl && !alt) {
switch (event->keyval) {
case GDK_KEY_f:
case GDK_KEY_F:
fileBrowser->getInspector()->showWindow(!shift);
return true;
}
}
return fileBrowser->keyPressed(event); return fileBrowser->keyPressed(event);
} }

View File

@ -115,9 +115,9 @@ FilePanel::FilePanel () : parent(nullptr), error(0)
Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) ); Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) );
devLab->set_name ("LabelRightNotebook"); devLab->set_name ("LabelRightNotebook");
devLab->set_angle (90); devLab->set_angle (90);
Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) ); //Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) );
inspectLab->set_name ("LabelRightNotebook"); //inspectLab->set_name ("LabelRightNotebook");
inspectLab->set_angle (90); //inspectLab->set_angle (90);
Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) ); Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) );
filtLab->set_name ("LabelRightNotebook"); filtLab->set_name ("LabelRightNotebook");
filtLab->set_angle (90); filtLab->set_angle (90);
@ -132,7 +132,7 @@ FilePanel::FilePanel () : parent(nullptr), error(0)
tpcPaned->pack2 (*history, true, false); tpcPaned->pack2 (*history, true, false);
rightNotebook->append_page (*sFilterPanel, *filtLab); rightNotebook->append_page (*sFilterPanel, *filtLab);
rightNotebook->append_page (*inspectorPanel, *inspectLab); //rightNotebook->append_page (*inspectorPanel, *inspectLab);
rightNotebook->append_page (*tpcPaned, *devLab); rightNotebook->append_page (*tpcPaned, *devLab);
//rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ... //rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ...
rightNotebook->append_page (*sExportPanel, *exportLab); rightNotebook->append_page (*sExportPanel, *exportLab);

View File

@ -82,9 +82,25 @@ InspectorBuffer::~InspectorBuffer() {
// return deg; // return deg;
//} //}
Inspector::Inspector () : currImage(nullptr), zoom(0.0), active(false) Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false)
{ {
set_name("Inspector"); set_name("Inspector");
window.set_visible(false);
window.set_title("RawTherapee Inspector");
window.add_events(Gdk::KEY_PRESS_MASK);
window.signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release));
window.signal_key_press_event().connect(sigc::mem_fun(*this, &Inspector::on_key_press));
add_events(Gdk::BUTTON_PRESS_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
gestureZoom = Gtk::GestureZoom::create(*this);
gestureZoom->signal_begin().connect(sigc::mem_fun(*this, &Inspector::on_zoom_begin));
gestureZoom->signal_scale_changed().connect(sigc::mem_fun(*this, &Inspector::on_zoom_scale_changed));
window.add(*this);
window.show_all();
window.set_visible(false);
active = true; // always track inspected thumbnails
} }
Inspector::~Inspector() Inspector::~Inspector()
@ -92,8 +108,184 @@ Inspector::~Inspector()
deleteBuffers(); deleteBuffers();
} }
void Inspector::showWindow(bool scaled)
{
this->scaled = scaled;
window.fullscreen();
window.set_visible(true);
pinned = false;
}
bool Inspector::on_key_release(GdkEventKey *event)
{
if (!pinned) {
switch (event->keyval) {
case GDK_KEY_f:
case GDK_KEY_F:
zoomScale = 1.0;
window.set_visible(false);
return true;
}
}
return false;
}
bool Inspector::on_key_press(GdkEventKey *event)
{
switch (event->keyval) {
case GDK_KEY_z:
case GDK_KEY_F:
if (pinned || scaled)
zoomScale = 1.0; // reset if not key hold
scaled = false;
queue_draw();
return true;
case GDK_KEY_f:
if (pinned || !scaled)
zoomScale = 1.0; // reset if not key hold
scaled = true;
queue_draw();
return true;
case GDK_KEY_Escape:
zoomScale = 1.0;
window.set_visible(false);
return true;
}
return false;
}
bool Inspector::on_button_press_event(GdkEventButton *event)
{
if (event->type == GDK_BUTTON_PRESS) {
if (!pinned)
// pin window with mouse click
pinned = true;
return true;
}
return false;
}
bool Inspector::on_scroll_event(GdkEventScroll *event)
{
if (!currImage)
return false;
bool alt = event->state & GDK_MOD1_MASK;
int deviceScale = get_scale_factor();
int imW = currImage->imgBuffer.getWidth();
int imH = currImage->imgBuffer.getHeight();
#ifdef GDK_WINDOWING_QUARTZ
// event reports speed of scroll wheel
double step_x = -event->delta_x;
double step_y = event->delta_y;
#else
// assume fixed step of 5%
double step_x = 5;
double step_y = 5;
#endif
int delta_x = 0;
int delta_y = 0;
switch (event->direction) {
case GDK_SCROLL_SMOOTH:
#ifdef GDK_WINDOWING_QUARTZ
// no additional step for smooth scrolling
delta_x = event->delta_x * deviceScale;
delta_y = event->delta_y * deviceScale;
#else
// apply step to smooth scrolling as well
delta_x = event->delta_x * deviceScale * step_x * imW / 100;
delta_y = event->delta_y * deviceScale * step_y * imH / 100;
#endif
break;
case GDK_SCROLL_DOWN:
delta_y = step_y * deviceScale * imH / 100;
break;
case GDK_SCROLL_UP:
delta_y = -step_y * deviceScale * imH / 100;
break;
case GDK_SCROLL_LEFT:
delta_x = step_x * deviceScale * imW / 100;
break;
case GDK_SCROLL_RIGHT:
delta_x = -step_x * deviceScale * imW / 100;
break;
}
if (alt) {
// zoom
beginZoom(event->x, event->y);
if (std::fabs(delta_y) > std::fabs(delta_x))
on_zoom_scale_changed(1.0 - (double)delta_y / imH / deviceScale);
else
on_zoom_scale_changed(1.0 - (double)delta_x / imW / deviceScale);
return true;
}
// scroll
moveCenter(delta_x, delta_y, imW, imH, deviceScale);
if (!dirty) {
dirty = true;
queue_draw();
}
return true;
}
void Inspector::moveCenter(int delta_x, int delta_y, int imW, int imH, int deviceScale)
{
rtengine::Coord margin; // limit to image size
margin.x = rtengine::min<int>(window.get_width() * deviceScale / scale, imW) / 2;
margin.y = rtengine::min<int>(window.get_height() * deviceScale / scale, imH) / 2;
center.set(rtengine::LIM<int>(center.x + delta_x, margin.x, imW - margin.x),
rtengine::LIM<int>(center.y + delta_y, margin.y, imH - margin.y));
}
void Inspector::beginZoom(double x, double y)
{
int deviceScale = get_scale_factor();
int imW = currImage->imgBuffer.getWidth();
int imH = currImage->imgBuffer.getHeight();
// limit center to image size
moveCenter(0, 0, imW, imH, deviceScale);
// store center and current position for zooming
dcenterBegin.x = (x - window.get_width()/2) / scale * deviceScale;
dcenterBegin.y = (y - window.get_height()/2) / scale * deviceScale;
centerBegin = center;
zoomScaleBegin = zoomScale;
}
void Inspector::on_zoom_begin(GdkEventSequence *s)
{
double x, y;
if (gestureZoom->get_point(s, x, y))
beginZoom(x, y);
}
void Inspector::on_zoom_scale_changed(double zscale)
{
if (!currImage)
return;
zoomScale = rtengine::LIM<double>(zoomScaleBegin * zscale, 0.01, 16.0);
double dcenterRatio = 1.0 - zoomScaleBegin / zoomScale;
center.x = centerBegin.x + dcenterBegin.x * dcenterRatio;
center.y = centerBegin.y + dcenterBegin.y * dcenterRatio;
if (!dirty) {
dirty = true;
queue_draw();
}
}
bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
{ {
dirty = false;
Glib::RefPtr<Gdk::Window> win = get_window(); Glib::RefPtr<Gdk::Window> win = get_window();
@ -116,10 +308,24 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
rtengine::Coord availableSize; rtengine::Coord availableSize;
rtengine::Coord topLeft; rtengine::Coord topLeft;
rtengine::Coord dest(0, 0); rtengine::Coord dest(0, 0);
availableSize.x = win->get_width(); int deviceScale = get_scale_factor();
availableSize.y = win->get_height(); availableSize.x = win->get_width() * deviceScale;
int imW = currImage->imgBuffer.getWidth(); availableSize.y = win->get_height() * deviceScale;
int imH = currImage->imgBuffer.getHeight(); int imW = rtengine::max<int>(currImage->imgBuffer.getWidth(), 1);
int imH = rtengine::max<int>(currImage->imgBuffer.getHeight(), 1);
scale = rtengine::min<double>((double)availableSize.x / imW, (double)availableSize.y / imH);
if (scaled) {
// reduce size of image to fit into window, no further zoom down
zoomScale = rtengine::max<double>(zoomScale, 1.0);
scale *= zoomScale;
}
else {
// limit zoom to fill at least complete window or 1:1
zoomScale = rtengine::max<double>(zoomScale, rtengine::min<double>(1.0, scale));
scale = zoomScale;
}
availableSize.x /= scale;
availableSize.y /= scale;
if (imW < availableSize.x) { if (imW < availableSize.x) {
// center the image in the available space along X // center the image in the available space along X
@ -146,7 +352,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
topLeft.y -= availableSize.y; topLeft.y -= availableSize.y;
topLeft.y = rtengine::max<int>(topLeft.y, 0); topLeft.y = rtengine::max<int>(topLeft.y, 0);
} }
//printf("center: %d, %d (img: %d, %d) (availableSize: %d, %d) (topLeft: %d, %d)\n", center.x, center.y, imW, imH, availableSize.x, availableSize.y, topLeft.x, topLeft.y); //printf("center: %d, %d (img: %d, %d) (availableSize: %d, %d) (topLeft: %d, %d)\n", center.x, center.y, imW, imH, availableSize.x, availableSize.y, topLeft.x, topLeft.y);
// define the destination area // define the destination area
@ -163,24 +368,50 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
Glib::RefPtr<Gtk::StyleContext> style = get_style_context(); Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
// draw the background // draw the background
style->render_background(cr, 0, 0, get_width(), get_height()); //style->render_background(cr, 0, 0, get_width(), get_height());
/* --- old method ///* --- old method (the new method does not seem to work)
c = style->get_background_color (Gtk::STATE_FLAG_NORMAL); c = style->get_background_color (Gtk::STATE_FLAG_NORMAL);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
cr->set_line_width (0); cr->set_line_width (0);
cr->rectangle (0, 0, availableSize.x, availableSize.y); cr->rectangle (0, 0, availableSize.x, availableSize.y);
cr->fill (); cr->fill ();
*/ //*/
currImage->imgBuffer.copySurface(win); bool scaledImage = scale != 1.0;
if (deviceScale == 1 && !scaledImage) {
// standard drawing
currImage->imgBuffer.copySurface(win);
}
else {
// consider device scale and image scale
if (deviceScale > 1) {
// use full device resolution and let it scale the image (macOS)
cairo_surface_set_device_scale(cr->get_target()->cobj(), scale, scale);
scaledImage = false;
}
int viewW = rtengine::min<int>(imW, availableSize.x);
int viewH = rtengine::min<int>(imH, availableSize.y);
Glib::RefPtr<Gdk::Pixbuf> crop = Gdk::Pixbuf::create(currImage->imgBuffer.getSurface(), topLeft.x, topLeft.y, viewW, viewH);
if (!scaledImage) {
Gdk::Cairo::set_source_pixbuf(cr, crop, dest.x, dest.y);
}
else {
// scale crop as the device does not seem to support it (Linux)
crop = crop->scale_simple(viewW*scale, viewH*scale, Gdk::INTERP_BILINEAR);
Gdk::Cairo::set_source_pixbuf(cr, crop, dest.x*scale, dest.y*scale);
}
cr->paint();
}
/* --- not for separate window
// draw the frame // draw the frame
c = style->get_border_color (Gtk::STATE_FLAG_NORMAL); c = style->get_border_color (Gtk::STATE_FLAG_NORMAL);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
cr->set_line_width (1); cr->set_line_width (1);
cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1); cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1);
cr->stroke (); cr->stroke ();
*/
} }
return true; return true;
@ -309,7 +540,7 @@ void Inspector::setActive(bool state)
flushBuffers(); flushBuffers();
} }
active = state; //active = state;
} }

View File

@ -47,12 +47,30 @@ private:
rtengine::Coord center; rtengine::Coord center;
std::vector<InspectorBuffer*> images; std::vector<InspectorBuffer*> images;
InspectorBuffer* currImage; InspectorBuffer* currImage;
double zoom; bool scaled; // fit image into window
double scale; // current scale
double zoomScale, zoomScaleBegin; // scale during zoom
rtengine::Coord centerBegin, dcenterBegin; // center during zoom
bool active; bool active;
bool pinned;
bool dirty;
sigc::connection delayconn; sigc::connection delayconn;
Glib::ustring next_image_path; Glib::ustring next_image_path;
Gtk::Window window;
bool on_key_release(GdkEventKey *event);
bool on_key_press(GdkEventKey *event);
bool on_button_press_event(GdkEventButton *event) override;
bool on_scroll_event(GdkEventScroll *event) override;
void moveCenter(int delta_x, int delta_y, int imW, int imH, int deviceScale);
Glib::RefPtr<Gtk::GestureZoom> gestureZoom;
void beginZoom(double x, double y);
void on_zoom_begin(GdkEventSequence *);
void on_zoom_scale_changed(double zscale);
bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override;
void deleteBuffers(); void deleteBuffers();
@ -62,6 +80,11 @@ public:
Inspector(); Inspector();
~Inspector() override; ~Inspector() override;
/** @brief Show or hide window
* @param scaled fit image into window
*/
void showWindow(bool scaled);
/** @brief Mouse movement to a new position /** @brief Mouse movement to a new position
* @param pos Location of the mouse, in percentage (i.e. [0;1] range) relative to the full size image ; -1,-1 == out of the image * @param pos Location of the mouse, in percentage (i.e. [0;1] range) relative to the full size image ; -1,-1 == out of the image
* @param transform H/V flip and coarse rotation transformation * @param transform H/V flip and coarse rotation transformation

View File

@ -663,6 +663,8 @@ void LCurve::updateCurveBackgroundHistogram(
{ {
lshape->updateBackgroundHistogram (histLCurve); lshape->updateBackgroundHistogram (histLCurve);
ccshape->updateBackgroundHistogram (histCCurve); ccshape->updateBackgroundHistogram (histCCurve);
lcshape->updateBackgroundHistogram (histCCurve);
clshape->updateBackgroundHistogram (histLCurve);
} }
void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd)

View File

@ -618,6 +618,12 @@ void Options::setDefaults()
rtSettings.itcwb_precis = 5;//3 or 5 or 9 rtSettings.itcwb_precis = 5;//3 or 5 or 9
// end locallab // end locallab
//wavelet
rtSettings.edghi = 3.0;//1.1 and 5.
rtSettings.edglo = 0.5;//0.1 and 0.95
rtSettings.limrad = 20.;//1 and 60
rtSettings.protectred = 60; rtSettings.protectred = 60;
rtSettings.protectredh = 0.3; rtSettings.protectredh = 0.3;
rtSettings.CRI_color = 0; rtSettings.CRI_color = 0;
@ -1709,6 +1715,22 @@ void Options::readFromFile(Glib::ustring fname)
} }
if (keyFile.has_group("Wavelet")) {
if (keyFile.has_key("Wavelet", "Edghi")) {
rtSettings.edghi = keyFile.get_double("Wavelet", "Edghi");
}
if (keyFile.has_key("Wavelet", "Edglo")) {
rtSettings.edglo = keyFile.get_double("Wavelet", "Edglo");
}
if (keyFile.has_key("Wavelet", "Limrad")) {
rtSettings.limrad = keyFile.get_double("Wavelet", "Limrad");
}
}
if (keyFile.has_group("ICC Profile Creator")) { if (keyFile.has_group("ICC Profile Creator")) {
if (keyFile.has_key("ICC Profile Creator", "PimariesPreset")) { if (keyFile.has_key("ICC Profile Creator", "PimariesPreset")) {
ICCPC_primariesPreset = keyFile.get_string("ICC Profile Creator", "PimariesPreset"); ICCPC_primariesPreset = keyFile.get_string("ICC Profile Creator", "PimariesPreset");
@ -2308,6 +2330,11 @@ void Options::saveToFile(Glib::ustring fname)
keyFile.set_integer("Color Management", "Previewselection", rtSettings.previewselection); keyFile.set_integer("Color Management", "Previewselection", rtSettings.previewselection);
keyFile.set_double("Color Management", "Cbdlsensi", rtSettings.cbdlsensi); keyFile.set_double("Color Management", "Cbdlsensi", rtSettings.cbdlsensi);
keyFile.set_double("Wavelet", "Edghi", rtSettings.edghi);
keyFile.set_double("Wavelet", "Edglo", rtSettings.edglo);
keyFile.set_double("Wavelet", "Limrad", rtSettings.limrad);
keyFile.set_string("ICC Profile Creator", "PimariesPreset", ICCPC_primariesPreset); keyFile.set_string("ICC Profile Creator", "PimariesPreset", ICCPC_primariesPreset);
keyFile.set_double("ICC Profile Creator", "RedPrimaryX", ICCPC_redPrimaryX); keyFile.set_double("ICC Profile Creator", "RedPrimaryX", ICCPC_redPrimaryX);
keyFile.set_double("ICC Profile Creator", "RedPrimaryY", ICCPC_redPrimaryY); keyFile.set_double("ICC Profile Creator", "RedPrimaryY", ICCPC_redPrimaryY);

View File

@ -60,6 +60,7 @@ void ParamsEdited::set(bool v)
retinex.mapcurve = v; retinex.mapcurve = v;
retinex.cdHcurve = v; retinex.cdHcurve = v;
retinex.lhcurve = v; retinex.lhcurve = v;
retinex.complexmethod = v;
retinex.retinexMethod = v; retinex.retinexMethod = v;
retinex.mapMethod = v; retinex.mapMethod = v;
retinex.viewMethod = v; retinex.viewMethod = v;
@ -531,6 +532,7 @@ void ParamsEdited::set(bool v)
wavelet.CLmethod = v; wavelet.CLmethod = v;
wavelet.Backmethod = v; wavelet.Backmethod = v;
wavelet.Tilesmethod = v; wavelet.Tilesmethod = v;
wavelet.complexmethod = v;
wavelet.daubcoeffmethod = v; wavelet.daubcoeffmethod = v;
wavelet.CHmethod = v; wavelet.CHmethod = v;
wavelet.CHSLmethod = v; wavelet.CHSLmethod = v;
@ -710,6 +712,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
retinex.lhcurve = retinex.lhcurve && p.retinex.lhcurve == other.retinex.lhcurve; retinex.lhcurve = retinex.lhcurve && p.retinex.lhcurve == other.retinex.lhcurve;
retinex.transmissionCurve = retinex.transmissionCurve && p.retinex.transmissionCurve == other.retinex.transmissionCurve; retinex.transmissionCurve = retinex.transmissionCurve && p.retinex.transmissionCurve == other.retinex.transmissionCurve;
retinex.gaintransmissionCurve = retinex.gaintransmissionCurve && p.retinex.gaintransmissionCurve == other.retinex.gaintransmissionCurve; retinex.gaintransmissionCurve = retinex.gaintransmissionCurve && p.retinex.gaintransmissionCurve == other.retinex.gaintransmissionCurve;
retinex.complexmethod = retinex.complexmethod && p.retinex.complexmethod == other.retinex.complexmethod;
retinex.retinexMethod = retinex.retinexMethod && p.retinex.retinexMethod == other.retinex.retinexMethod; retinex.retinexMethod = retinex.retinexMethod && p.retinex.retinexMethod == other.retinex.retinexMethod;
retinex.mapMethod = retinex.mapMethod && p.retinex.mapMethod == other.retinex.mapMethod; retinex.mapMethod = retinex.mapMethod && p.retinex.mapMethod == other.retinex.mapMethod;
retinex.viewMethod = retinex.viewMethod && p.retinex.viewMethod == other.retinex.viewMethod; retinex.viewMethod = retinex.viewMethod && p.retinex.viewMethod == other.retinex.viewMethod;
@ -1679,6 +1682,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
wavelet.CLmethod = wavelet.CLmethod && p.wavelet.CLmethod == other.wavelet.CLmethod; wavelet.CLmethod = wavelet.CLmethod && p.wavelet.CLmethod == other.wavelet.CLmethod;
wavelet.Backmethod = wavelet.Backmethod && p.wavelet.Backmethod == other.wavelet.Backmethod; wavelet.Backmethod = wavelet.Backmethod && p.wavelet.Backmethod == other.wavelet.Backmethod;
wavelet.Tilesmethod = wavelet.Tilesmethod && p.wavelet.Tilesmethod == other.wavelet.Tilesmethod; wavelet.Tilesmethod = wavelet.Tilesmethod && p.wavelet.Tilesmethod == other.wavelet.Tilesmethod;
wavelet.complexmethod = wavelet.complexmethod && p.wavelet.complexmethod == other.wavelet.complexmethod;
wavelet.daubcoeffmethod = wavelet.daubcoeffmethod && p.wavelet.daubcoeffmethod == other.wavelet.daubcoeffmethod; wavelet.daubcoeffmethod = wavelet.daubcoeffmethod && p.wavelet.daubcoeffmethod == other.wavelet.daubcoeffmethod;
wavelet.CHmethod = wavelet.CHmethod && p.wavelet.CHmethod == other.wavelet.CHmethod; wavelet.CHmethod = wavelet.CHmethod && p.wavelet.CHmethod == other.wavelet.CHmethod;
wavelet.CHSLmethod = wavelet.CHSLmethod && p.wavelet.CHSLmethod == other.wavelet.CHSLmethod; wavelet.CHSLmethod = wavelet.CHSLmethod && p.wavelet.CHSLmethod == other.wavelet.CHSLmethod;
@ -1915,6 +1919,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.retinex.gaintransmissionCurve = mods.retinex.gaintransmissionCurve; toEdit.retinex.gaintransmissionCurve = mods.retinex.gaintransmissionCurve;
} }
if (retinex.complexmethod) {
toEdit.retinex.complexmethod = mods.retinex.complexmethod;
}
if (retinex.retinexMethod) { if (retinex.retinexMethod) {
toEdit.retinex.retinexMethod = mods.retinex.retinexMethod; toEdit.retinex.retinexMethod = mods.retinex.retinexMethod;
} }
@ -5574,6 +5582,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.wavelet.Tilesmethod = mods.wavelet.Tilesmethod; toEdit.wavelet.Tilesmethod = mods.wavelet.Tilesmethod;
} }
if (wavelet.complexmethod) {
toEdit.wavelet.complexmethod = mods.wavelet.complexmethod;
}
if (wavelet.daubcoeffmethod) { if (wavelet.daubcoeffmethod) {
toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod; toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod;
} }

View File

@ -73,6 +73,7 @@ struct RetinexParamsEdited {
bool slope; bool slope;
bool neigh; bool neigh;
bool offs; bool offs;
bool complexmethod;
bool retinexMethod; bool retinexMethod;
bool mapMethod; bool mapMethod;
bool viewMethod; bool viewMethod;
@ -1039,6 +1040,7 @@ struct WaveletParamsEdited {
bool CLmethod; bool CLmethod;
bool Backmethod; bool Backmethod;
bool Tilesmethod; bool Tilesmethod;
bool complexmethod;
bool daubcoeffmethod; bool daubcoeffmethod;
bool Dirmethod; bool Dirmethod;
bool sigma; bool sigma;

View File

@ -9,6 +9,7 @@
#include "rtimage.h" #include "rtimage.h"
#include "options.h" #include "options.h"
#include "../rtengine/color.h" #include "../rtengine/color.h"
#include "eventmapper.h"
using namespace rtengine; using namespace rtengine;
using namespace rtengine::procparams; using namespace rtengine::procparams;
@ -25,13 +26,26 @@ Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL")
nextsigma = 0.; nextsigma = 0.;
nextminT = 0.; nextminT = 0.;
nextmaxT = 0.; nextmaxT = 0.;
auto m = ProcEventMapper::getInstance();
EvReticomplex = m->newEvent(DEMOSAIC, "HISTORY_MSG_COMPLEXRETI");
const RetinexParams default_params;
// MAIN Expander ================================================================== // MAIN Expander ==================================================================
complexmethod = Gtk::manage (new MyComboBoxText ());
complexmethod->append(M("TP_WAVELET_COMPNORMAL"));
complexmethod->append(M("TP_WAVELET_COMPEXPERT"));
complexmethodconn = complexmethod->signal_changed().connect(sigc::mem_fun(*this, &Retinex::complexmethodChanged));
complexmethod->set_tooltip_text(M("TP_WAVELET_COMPLEX_TOOLTIP"));
Gtk::HBox* const complexHBox = Gtk::manage(new Gtk::HBox());
Gtk::Label* const complexLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_COMPLEXLAB") + ":"));
complexHBox->pack_start(*complexLabel, Gtk::PACK_SHRINK, 4);
complexHBox->pack_start(*complexmethod);
pack_start(*complexHBox);
Gtk::Grid *retinexGrid = Gtk::manage ( new Gtk::Grid()); Gtk::Grid *retinexGrid = Gtk::manage ( new Gtk::Grid());
@ -116,7 +130,8 @@ Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL")
// MAP (MASK) Frame --------------------------------------------------------------- // MAP (MASK) Frame ---------------------------------------------------------------
Gtk::Frame *maskFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_LABEL_MASK")) ); // Gtk::Frame *maskFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_LABEL_MASK")) );
maskFrame = Gtk::manage (new Gtk::Frame (M ("TP_RETINEX_LABEL_MASK")) );
setExpandAlignProperties (maskFrame, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); setExpandAlignProperties (maskFrame, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
Gtk::Grid *maskGrid = Gtk::manage ( new Gtk::Grid()); Gtk::Grid *maskGrid = Gtk::manage ( new Gtk::Grid());
@ -384,7 +399,6 @@ Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL")
Gtk::Grid *tranGrid = Gtk::manage (new Gtk::Grid()); Gtk::Grid *tranGrid = Gtk::manage (new Gtk::Grid());
setExpandAlignProperties (tranGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); setExpandAlignProperties (tranGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
const RetinexParams default_params;
// Transmission map curve // Transmission map curve
transmissionCurveEditorG = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_TRANSMISSION")); transmissionCurveEditorG = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_TRANSMISSION"));
@ -628,12 +642,14 @@ void Retinex::neutral_pressed ()
limd->resetValue (false); limd->resetValue (false);
highl->resetValue (false); highl->resetValue (false);
gam->resetValue (false); gam->resetValue (false);
skal->resetValue (false);
slope->resetValue (false); slope->resetValue (false);
highlights->resetValue (false); highlights->resetValue (false);
h_tonalwidth->resetValue (false); h_tonalwidth->resetValue (false);
shadows->resetValue (false); shadows->resetValue (false);
s_tonalwidth->resetValue (false); s_tonalwidth->resetValue (false);
radius->resetValue (false); radius->resetValue (false);
medianmap->set_active (false);
mapMethod->set_active (0); mapMethod->set_active (0);
viewMethod->set_active (0); viewMethod->set_active (0);
retinexMethod->set_active (2); retinexMethod->set_active (2);
@ -742,7 +758,53 @@ void Retinex::updateTrans ()
} }
} }
void Retinex::convertParamToNormal()
{
const RetinexParams def_params;
disableListener();
iter->setValue(def_params.iter);
viewMethod->set_active(0);
mapMethod->set_active(0);
cdshape->reset();
cdshapeH->reset();
lhshape->reset();
transmissionShape->reset();
medianmap->set_active(def_params.medianmap);
enableListener();
}
void Retinex::updateGUIToMode(int mode)
{
if(mode ==0) {
iterFrame->hide();
maskFrame->hide();
equalFrame->hide();
viewMethod->hide();
mapMethod->hide();
transmissionCurveEditorG->hide();
medianmap->hide();
} else {
iterFrame->show();
maskFrame->show();
equalFrame->show();
viewMethod->show();
transmissionCurveEditorG->show();
medianmap->show();
mapMethod->show();
if (iter->getIntValue() > 1) {
grad->set_sensitive (true);
scal->set_sensitive (true);
grads->set_sensitive (true);
} else {
grad->set_sensitive (false);
scal->set_sensitive (false);
grads->set_sensitive (false);
}
}
}
void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
{ {
@ -752,6 +814,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
gammaretinexConn.block (true); gammaretinexConn.block (true);
mapMethodConn.block (true); mapMethodConn.block (true);
viewMethodConn.block (true); viewMethodConn.block (true);
complexmethodconn.block (true);
if (pedited) { if (pedited) {
@ -775,6 +838,9 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
shadows->setEditedState (pedited->retinex.shadows ? Edited : UnEdited); shadows->setEditedState (pedited->retinex.shadows ? Edited : UnEdited);
s_tonalwidth->setEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited); s_tonalwidth->setEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited);
if (!pedited->retinex.complexmethod) {
complexmethod->set_active_text (M ("GENERAL_UNCHANGED"));
}
if (!pedited->retinex.retinexMethod) { if (!pedited->retinex.retinexMethod) {
retinexMethod->set_active_text (M ("GENERAL_UNCHANGED")); retinexMethod->set_active_text (M ("GENERAL_UNCHANGED"));
@ -844,6 +910,13 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
medianmapConn.block (false); medianmapConn.block (false);
lastmedianmap = pp->retinex.medianmap; lastmedianmap = pp->retinex.medianmap;
if (pp->retinex.complexmethod == "normal") {
complexmethod->set_active(0);
} else if (pp->retinex.complexmethod == "expert") {
complexmethod->set_active(1);
}
if (pp->retinex.retinexMethod == "low") { if (pp->retinex.retinexMethod == "low") {
retinexMethod->set_active (0); retinexMethod->set_active (0);
} else if (pp->retinex.retinexMethod == "uni") { } else if (pp->retinex.retinexMethod == "uni") {
@ -906,6 +979,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
mapMethodChanged (); mapMethodChanged ();
viewMethodChanged (); viewMethodChanged ();
medianmapConn.block (true); medianmapConn.block (true);
medianmapChanged (); medianmapChanged ();
medianmapConn.block (false); medianmapConn.block (false);
@ -914,7 +988,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
cdshapeH->setCurve (pp->retinex.cdHcurve); cdshapeH->setCurve (pp->retinex.cdHcurve);
lhshape->setCurve (pp->retinex.lhcurve); lhshape->setCurve (pp->retinex.lhcurve);
mapshape->setCurve (pp->retinex.mapcurve); mapshape->setCurve (pp->retinex.mapcurve);
retinexMethodConn.block (false); retinexMethodConn.block (false);
retinexColorSpaceConn.block (false); retinexColorSpaceConn.block (false);
gammaretinexConn.block (false); gammaretinexConn.block (false);
@ -923,8 +997,18 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
transmissionShape->setCurve (pp->retinex.transmissionCurve); transmissionShape->setCurve (pp->retinex.transmissionCurve);
gaintransmissionShape->setCurve (pp->retinex.gaintransmissionCurve); gaintransmissionShape->setCurve (pp->retinex.gaintransmissionCurve);
complexmethodconn.block (false);
enableListener (); enableListener ();
if (complexmethod->get_active_row_number() == 0) {
updateGUIToMode(0);
// convertParamToNormal();
} else {
updateGUIToMode(1);
}
} }
@ -961,6 +1045,7 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
pp->retinex.stonalwidth = (int)s_tonalwidth->getValue (); pp->retinex.stonalwidth = (int)s_tonalwidth->getValue ();
if (pedited) { if (pedited) {
pedited->retinex.complexmethod = complexmethod->get_active_text() != M ("GENERAL_UNCHANGED");
pedited->retinex.retinexMethod = retinexMethod->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->retinex.retinexMethod = retinexMethod->get_active_text() != M ("GENERAL_UNCHANGED");
pedited->retinex.retinexcolorspace = retinexcolorspace->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->retinex.retinexcolorspace = retinexcolorspace->get_active_text() != M ("GENERAL_UNCHANGED");
pedited->retinex.gammaretinex = gammaretinex->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->retinex.gammaretinex = gammaretinex->get_active_text() != M ("GENERAL_UNCHANGED");
@ -998,6 +1083,12 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
} }
if (complexmethod->get_active_row_number() == 0) {
pp->retinex.complexmethod = "normal";
} else if (complexmethod->get_active_row_number() == 1) {
pp->retinex.complexmethod = "expert";
}
if (retinexMethod->get_active_row_number() == 0) { if (retinexMethod->get_active_row_number() == 0) {
pp->retinex.retinexMethod = "low"; pp->retinex.retinexMethod = "low";
} else if (retinexMethod->get_active_row_number() == 1) { } else if (retinexMethod->get_active_row_number() == 1) {
@ -1056,6 +1147,27 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited)
} }
void Retinex::complexmethodChanged()
{
if (!batchMode) {
if (complexmethod->get_active_row_number() == 0) {
updateGUIToMode(0);
convertParamToNormal();
} else {
updateGUIToMode(1);
}
}
if (listener) {
listener->panelChanged(EvReticomplex, complexmethod->get_active_text());
}
}
void Retinex::retinexMethodChanged() void Retinex::retinexMethodChanged()
{ {
@ -1138,8 +1250,11 @@ void Retinex::viewMethodChanged()
limd->show(); limd->show();
transmissionCurveEditorG->show(); transmissionCurveEditorG->show();
medianmap->show(); medianmap->show();
if (complexmethod->get_active_row_number() == 0) {
iterFrame->show(); iterFrame->hide();
} else {
iterFrame->show();
}
/* /*
iter->show(); iter->show();
scal->show(); scal->show();
@ -1522,6 +1637,7 @@ void Retinex::setBatchMode (bool batchMode)
h_tonalwidth->showEditedCB (); h_tonalwidth->showEditedCB ();
shadows->showEditedCB (); shadows->showEditedCB ();
s_tonalwidth->showEditedCB (); s_tonalwidth->showEditedCB ();
// complexmethod->append(M("GENERAL_UNCHANGED"));
skal->showEditedCB (); skal->showEditedCB ();
curveEditorGD->setBatchMode (batchMode); curveEditorGD->setBatchMode (batchMode);

View File

@ -28,6 +28,7 @@ class Retinex final :
{ {
private: private:
IdleRegister idle_register; IdleRegister idle_register;
rtengine::ProcEvent EvReticomplex;
protected: protected:
CurveEditorGroup* curveEditorGD; CurveEditorGroup* curveEditorGD;
@ -72,6 +73,9 @@ protected:
MyComboBoxText* mapMethod; MyComboBoxText* mapMethod;
MyComboBoxText* viewMethod; MyComboBoxText* viewMethod;
Gtk::CheckButton* medianmap; Gtk::CheckButton* medianmap;
MyComboBoxText* complexmethod;
sigc::connection complexmethodconn;
double nextmin; double nextmin;
double nextmax; double nextmax;
double nextminiT; double nextminiT;
@ -87,6 +91,7 @@ protected:
Gtk::Frame *gainFrame; Gtk::Frame *gainFrame;
Gtk::Frame *tranFrame; Gtk::Frame *tranFrame;
Gtk::Frame *iterFrame; Gtk::Frame *iterFrame;
Gtk::Frame *maskFrame;
Gtk::Frame *equalFrame; Gtk::Frame *equalFrame;
DiagonalCurveEditor* cdshape; DiagonalCurveEditor* cdshape;
@ -148,4 +153,7 @@ public:
private: private:
void foldAllButMe(GdkEventButton* event, MyExpander *expander); void foldAllButMe(GdkEventButton* event, MyExpander *expander);
void convertParamToNormal();
void updateGUIToMode(int mode);
void complexmethodChanged();
}; };

View File

@ -158,6 +158,7 @@ Wavelet::Wavelet() :
HSmethod(Gtk::manage(new MyComboBoxText())), HSmethod(Gtk::manage(new MyComboBoxText())),
CLmethod(Gtk::manage(new MyComboBoxText())), CLmethod(Gtk::manage(new MyComboBoxText())),
Backmethod(Gtk::manage(new MyComboBoxText())), Backmethod(Gtk::manage(new MyComboBoxText())),
complexmethod(Gtk::manage(new MyComboBoxText())),
Tilesmethod(Gtk::manage(new MyComboBoxText())), Tilesmethod(Gtk::manage(new MyComboBoxText())),
daubcoeffmethod(Gtk::manage(new MyComboBoxText())), daubcoeffmethod(Gtk::manage(new MyComboBoxText())),
Dirmethod(Gtk::manage(new MyComboBoxText())), Dirmethod(Gtk::manage(new MyComboBoxText())),
@ -190,7 +191,10 @@ Wavelet::Wavelet() :
expclari(Gtk::manage(new MyExpander(true, M("TP_WAVELET_CLARI")))), expclari(Gtk::manage(new MyExpander(true, M("TP_WAVELET_CLARI")))),
expbl(Gtk::manage(new MyExpander(true, M("TP_WAVELET_BL")))), expbl(Gtk::manage(new MyExpander(true, M("TP_WAVELET_BL")))),
neutrHBox(Gtk::manage(new Gtk::HBox())), neutrHBox(Gtk::manage(new Gtk::HBox())),
usharpHBox(Gtk::manage(new Gtk::HBox())) usharpHBox(Gtk::manage(new Gtk::HBox())),
ctboxch(Gtk::manage(new Gtk::HBox())),
ctboxBA(Gtk::manage(new Gtk::VBox()))
{ {
CurveListener::setMulti(true); CurveListener::setMulti(true);
auto m = ProcEventMapper::getInstance(); auto m = ProcEventMapper::getInstance();
@ -227,6 +231,7 @@ Wavelet::Wavelet() :
EvWavrangeab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_RANGEAB"); EvWavrangeab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_RANGEAB");
EvWavprotab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_PROTAB"); EvWavprotab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_PROTAB");
EvWavlevelshc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_LEVELSHC"); EvWavlevelshc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_LEVELSHC");
EvWavcomplexmet = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_COMPLEX");
labgrid = Gtk::manage(new LabGrid(EvWavLabGridValue, M("TP_WAVELET_LABGRID_VALUES"))); labgrid = Gtk::manage(new LabGrid(EvWavLabGridValue, M("TP_WAVELET_LABGRID_VALUES")));
@ -269,6 +274,16 @@ Wavelet::Wavelet() :
thres->set_tooltip_text(M("TP_WAVELET_LEVELS_TOOLTIP")); thres->set_tooltip_text(M("TP_WAVELET_LEVELS_TOOLTIP"));
thres->setAdjusterListener(this); thres->setAdjusterListener(this);
complexmethod->append(M("TP_WAVELET_COMPNORMAL"));
complexmethod->append(M("TP_WAVELET_COMPEXPERT"));
complexmethodconn = complexmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::complexmethodChanged));
complexmethod->set_tooltip_text(M("TP_WAVELET_COMPLEX_TOOLTIP"));
Gtk::HBox* const complexHBox = Gtk::manage(new Gtk::HBox());
Gtk::Label* const complexLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_COMPLEXLAB") + ":"));
complexHBox->pack_start(*complexLabel, Gtk::PACK_SHRINK, 4);
complexHBox->pack_start(*complexmethod);
Tilesmethod->append(M("TP_WAVELET_TILESFULL")); Tilesmethod->append(M("TP_WAVELET_TILESFULL"));
Tilesmethod->append(M("TP_WAVELET_TILESBIG")); Tilesmethod->append(M("TP_WAVELET_TILESBIG"));
// Tilesmethod->append(M("TP_WAVELET_TILESLIT")); // Tilesmethod->append(M("TP_WAVELET_TILESLIT"));
@ -335,6 +350,7 @@ Wavelet::Wavelet() :
levdirSubHBox->pack_start(*Lmethod); levdirSubHBox->pack_start(*Lmethod);
levdirSubHBox->pack_start(*Dirmethod, Gtk::PACK_EXPAND_WIDGET, 2); // same, but 2 not 4? levdirSubHBox->pack_start(*Dirmethod, Gtk::PACK_EXPAND_WIDGET, 2); // same, but 2 not 4?
settingsBox->pack_start(*complexHBox);
settingsBox->pack_start(*strength); settingsBox->pack_start(*strength);
settingsBox->pack_start(*thres); settingsBox->pack_start(*thres);
settingsBox->pack_start(*tilesizeHBox); settingsBox->pack_start(*tilesizeHBox);
@ -452,7 +468,7 @@ Wavelet::Wavelet() :
ToolParamBlock* const chBox = Gtk::manage(new ToolParamBlock()); ToolParamBlock* const chBox = Gtk::manage(new ToolParamBlock());
Gtk::Label* const labmch = Gtk::manage(new Gtk::Label(M("TP_WAVELET_CHTYPE") + ":")); Gtk::Label* const labmch = Gtk::manage(new Gtk::Label(M("TP_WAVELET_CHTYPE") + ":"));
Gtk::HBox* const ctboxch = Gtk::manage(new Gtk::HBox()); // Gtk::HBox* const ctboxch = Gtk::manage(new Gtk::HBox());
ctboxch->pack_start(*labmch, Gtk::PACK_SHRINK, 1); ctboxch->pack_start(*labmch, Gtk::PACK_SHRINK, 1);
CHmethod->append(M("TP_WAVELET_CH1")); CHmethod->append(M("TP_WAVELET_CH1"));
@ -674,7 +690,7 @@ Wavelet::Wavelet() :
EDmethod->append(M("TP_WAVELET_EDCU")); EDmethod->append(M("TP_WAVELET_EDCU"));
EDmethodconn = EDmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::EDmethodChanged)); EDmethodconn = EDmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::EDmethodChanged));
ctboxED->pack_start(*EDmethod); ctboxED->pack_start(*EDmethod);
edgBox->pack_start(*ctboxED); // edgBox->pack_start(*ctboxED);
edgcont->setAdjusterListener(this); edgcont->setAdjusterListener(this);
edgcont->setBgGradient(milestones2); edgcont->setBgGradient(milestones2);
@ -838,7 +854,7 @@ Wavelet::Wavelet() :
thrH->setAdjusterListener(this); thrH->setAdjusterListener(this);
radius->setAdjusterListener(this); radius->setAdjusterListener(this);
radius->hide(); // radius->hide();
shFrame->set_label_align(0.025, 0.5); shFrame->set_label_align(0.025, 0.5);
ToolParamBlock* const shBox = Gtk::manage(new ToolParamBlock()); ToolParamBlock* const shBox = Gtk::manage(new ToolParamBlock());
@ -1007,7 +1023,7 @@ Wavelet::Wavelet() :
resBox->pack_start(*neutrHBox); resBox->pack_start(*neutrHBox);
// Final Touchup // Final Touchup
Gtk::VBox* const ctboxBA = Gtk::manage(new Gtk::VBox()); // Gtk::VBox* const ctboxBA = Gtk::manage(new Gtk::VBox());
ctboxBA->set_spacing(2); ctboxBA->set_spacing(2);
@ -1236,6 +1252,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
CLmethodconn.block(true); CLmethodconn.block(true);
Backmethodconn.block(true); Backmethodconn.block(true);
Tilesmethodconn.block(true); Tilesmethodconn.block(true);
complexmethodconn.block(true);
daubcoeffmethodconn.block(true); daubcoeffmethodconn.block(true);
Dirmethodconn.block(true); Dirmethodconn.block(true);
CHmethodconn.block(true); CHmethodconn.block(true);
@ -1357,6 +1374,12 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
} else if (pp->wavelet.CLmethod == "all") { } else if (pp->wavelet.CLmethod == "all") {
CLmethod->set_active(3); CLmethod->set_active(3);
} }
if (pp->wavelet.complexmethod == "normal") {
complexmethod->set_active(0);
} else if (pp->wavelet.complexmethod == "expert") {
complexmethod->set_active(1);
}
//Tilesmethod->set_active (2); //Tilesmethod->set_active (2);
if (pp->wavelet.Tilesmethod == "full") { if (pp->wavelet.Tilesmethod == "full") {
@ -1558,6 +1581,11 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
Backmethod->set_active_text(M("GENERAL_UNCHANGED")); Backmethod->set_active_text(M("GENERAL_UNCHANGED"));
} }
if (!pedited->wavelet.complexmethod) {
complexmethod->set_active_text(M("GENERAL_UNCHANGED"));
}
if (!pedited->wavelet.Tilesmethod) { if (!pedited->wavelet.Tilesmethod) {
Tilesmethod->set_active_text(M("GENERAL_UNCHANGED")); Tilesmethod->set_active_text(M("GENERAL_UNCHANGED"));
} }
@ -1774,6 +1802,15 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
} else { } else {
sup->hide(); sup->hide();
} }
if (complexmethod->get_active_row_number() == 0) {
updateGUIToMode(0);
convertParamToNormal();
} else {
updateGUIToMode(1);
}
} }
/***************************************************************************************************** /*****************************************************************************************************
@ -1786,6 +1823,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
CLmethodconn.block(false); CLmethodconn.block(false);
Backmethodconn.block(false); Backmethodconn.block(false);
Tilesmethodconn.block(false); Tilesmethodconn.block(false);
complexmethodconn.block(false);
daubcoeffmethodconn.block(false); daubcoeffmethodconn.block(false);
CHmethodconn.block(false); CHmethodconn.block(false);
CHSLmethodconn.block(false); CHSLmethodconn.block(false);
@ -1965,6 +2003,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pedited->wavelet.CLmethod = CLmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.CLmethod = CLmethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->wavelet.Backmethod = Backmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.Backmethod = Backmethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->wavelet.Tilesmethod = Tilesmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.Tilesmethod = Tilesmethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->wavelet.complexmethod = complexmethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->wavelet.daubcoeffmethod = daubcoeffmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.daubcoeffmethod = daubcoeffmethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->wavelet.CHmethod = CHmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.CHmethod = CHmethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->wavelet.CHSLmethod = CHSLmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.CHSLmethod = CHSLmethod->get_active_text() != M("GENERAL_UNCHANGED");
@ -2168,6 +2207,12 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
// pp->wavelet.Tilesmethod = "lit"; // pp->wavelet.Tilesmethod = "lit";
} }
if (complexmethod->get_active_row_number() == 0) {
pp->wavelet.complexmethod = "normal";
} else if (complexmethod->get_active_row_number() == 1) {
pp->wavelet.complexmethod = "expert";
}
if (daubcoeffmethod->get_active_row_number() == 0) { if (daubcoeffmethod->get_active_row_number() == 0) {
pp->wavelet.daubcoeffmethod = "2_"; pp->wavelet.daubcoeffmethod = "2_";
} else if (daubcoeffmethod->get_active_row_number() == 1) { } else if (daubcoeffmethod->get_active_row_number() == 1) {
@ -2835,6 +2880,110 @@ void Wavelet::ushamethodChanged()
} }
void Wavelet::convertParamToNormal()
{
const WaveletParams def_params;
disableListener();
//contrast
offset->setValue(def_params.offset);
sigma->setValue(def_params.sigma);
lowthr->setValue(def_params.lowthr);
//chroma
expchroma->setEnabled(def_params.expchroma);
sigmacol->setValue(def_params.sigmacol);
CHmethod->set_active(2);
//denoise
chromfi->setValue(def_params.chromfi);
chromco->setValue(def_params.chromco);
//toning
exptoning->setEnabled(def_params.exptoning);
//gamut
median->set_active(def_params.median);
avoid->set_active(def_params.avoid);
hueskin->setValue(def_params.hueskin);
skinprotect->setValue(def_params.skinprotect);
//blur
expbl->setEnabled(def_params.expbl);
//edge sharpness
lipst->set_active(def_params.lipst);
lipstUpdateUI();
edgesensi->setValue(def_params.edgesensi);
edgeampli->setValue(def_params.edgeampli);
NPmethod->set_active(0);
//resid
// oldsh->set_active(true);
radius->setValue(def_params.radius);
resblur->setValue(def_params.resblur);
resblurc->setValue(def_params.resblurc);
cbenab->set_active(false);
//final touchup
BAmethod->set_active(0);
sigmafin->setValue(def_params.sigmafin);
enableListener();
// Update GUI based on converted widget parameters:
}
void Wavelet::updateGUIToMode(int mode)
{
if(mode ==0) {
offset->hide();
sigma->hide();
lowthr->hide();
ctboxch->hide();
sigmacol->hide();
expgamut->hide();
exptoning->hide();
chroFrame->hide();
expbl->hide();
lipst->hide();
dirFrame->hide();
oldsh->hide();
radius->hide();
blurFrame->hide();
cbenab->hide();
sigmafin->hide();
} else {
offset->show();
sigma->show();
lowthr->show();
ctboxch->show();
sigmacol->show();
expgamut->show();
exptoning->show();
chroFrame->show();
expbl->show();
lipst->show();
dirFrame->show();
oldsh->hide();
radius->show();
blurFrame->show();
cbenab->show();
sigmafin->show();
}
}
void Wavelet::complexmethodChanged()
{
if (complexmethod->get_active_row_number() == 0) {
updateGUIToMode(0);
convertParamToNormal();
} else {
updateGUIToMode(1);
}
if (listener && (multiImage || getEnabled())) {
listener->panelChanged(EvWavcomplexmet, complexmethod->get_active_text());
}
}
void Wavelet::TilesmethodChanged() void Wavelet::TilesmethodChanged()
{ {
//TilesmethodUpdateUI(); //TilesmethodUpdateUI();
@ -2916,6 +3065,7 @@ void Wavelet::setBatchMode(bool batchMode)
CLmethod->append(M("GENERAL_UNCHANGED")); CLmethod->append(M("GENERAL_UNCHANGED"));
Backmethod->append(M("GENERAL_UNCHANGED")); Backmethod->append(M("GENERAL_UNCHANGED"));
Tilesmethod->append(M("GENERAL_UNCHANGED")); Tilesmethod->append(M("GENERAL_UNCHANGED"));
complexmethod->append(M("GENERAL_UNCHANGED"));
daubcoeffmethod->append(M("GENERAL_UNCHANGED")); daubcoeffmethod->append(M("GENERAL_UNCHANGED"));
CHmethod->append(M("GENERAL_UNCHANGED")); CHmethod->append(M("GENERAL_UNCHANGED"));
Medgreinf->append(M("GENERAL_UNCHANGED")); Medgreinf->append(M("GENERAL_UNCHANGED"));

View File

@ -47,7 +47,6 @@ class Wavelet final :
public: public:
Wavelet(); Wavelet();
~Wavelet() override; ~Wavelet() override;
bool wavComputed_(); bool wavComputed_();
void adjusterChanged(Adjuster* a, double newval) override; void adjusterChanged(Adjuster* a, double newval) override;
void autoOpenCurve() override; void autoOpenCurve() override;
@ -102,6 +101,7 @@ private:
rtengine::ProcEvent EvWavrangeab; rtengine::ProcEvent EvWavrangeab;
rtengine::ProcEvent EvWavprotab; rtengine::ProcEvent EvWavprotab;
rtengine::ProcEvent EvWavlevelshc; rtengine::ProcEvent EvWavlevelshc;
rtengine::ProcEvent EvWavcomplexmet;
LabGrid *labgrid; LabGrid *labgrid;
@ -121,6 +121,7 @@ private:
void LmethodChanged(); void LmethodChanged();
void MedgreinfChanged(); void MedgreinfChanged();
void TMmethodChanged(); void TMmethodChanged();
void complexmethodChanged();
void TilesmethodChanged(); void TilesmethodChanged();
void avoidToggled(); void avoidToggled();
void showmaskToggled (); void showmaskToggled ();
@ -143,7 +144,8 @@ private:
void ushamethodChanged(); void ushamethodChanged();
void updateGUI(); void updateGUI();
void updateGUImaxlev(); void updateGUImaxlev();
void convertParamToNormal();
void updateGUIToMode(int mode);
void HSmethodUpdateUI(); void HSmethodUpdateUI();
void CHmethodUpdateUI(); void CHmethodUpdateUI();
// void CHSLmethodChangedUI(); // void CHSLmethodChangedUI();
@ -297,6 +299,8 @@ private:
sigc::connection CLmethodconn; sigc::connection CLmethodconn;
MyComboBoxText* const Backmethod; MyComboBoxText* const Backmethod;
sigc::connection Backmethodconn; sigc::connection Backmethodconn;
MyComboBoxText* const complexmethod;
sigc::connection complexmethodconn;
MyComboBoxText* const Tilesmethod; MyComboBoxText* const Tilesmethod;
sigc::connection Tilesmethodconn; sigc::connection Tilesmethodconn;
MyComboBoxText* const daubcoeffmethod; MyComboBoxText* const daubcoeffmethod;
@ -338,6 +342,8 @@ private:
Gtk::HBox* const neutrHBox; Gtk::HBox* const neutrHBox;
Gtk::HBox* const usharpHBox; Gtk::HBox* const usharpHBox;
Gtk::HBox* const ctboxch;
Gtk::VBox* const ctboxBA;// = Gtk::manage(new Gtk::VBox());
sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enabletmConn, enableFinalConn, enableclariConn; sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enabletmConn, enableFinalConn, enableclariConn;
sigc::connection enableNoiseConn, enableResidConn, enableToningConn; sigc::connection enableNoiseConn, enableResidConn, enableToningConn;