Merge from dev
This commit is contained in:
commit
2f06f56d9c
@ -15,6 +15,7 @@ Development contributors, in last name alphabetical order:
|
||||
Maciek Dworak
|
||||
Michael Ezra
|
||||
Flössie
|
||||
Rüdiger Franke
|
||||
Jean-Christophe Frisch
|
||||
Ilias Giarimis
|
||||
Alberto Griggio
|
||||
|
@ -45,7 +45,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION
|
||||
endif()
|
||||
|
||||
# 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")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-tree-loop-vectorize")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-loop-vectorize")
|
||||
|
@ -2653,6 +2653,8 @@ TP_WAVELET_CHR_TOOLTIP;Ajuste le chroma en fonction des "niveaux de contraste" e
|
||||
TP_WAVELET_CHSL;Curseurs
|
||||
TP_WAVELET_CHTYPE;Méthode de chrominance
|
||||
TP_WAVELET_COLORT;Opacité Rouge-Vert
|
||||
TP_WAVELET_COMPLEX_TOOLTIP;Standard: l’application dispose du nécessaire pour assurer les opérations courantes, l’interface 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_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.
|
||||
|
@ -569,10 +569,10 @@ HISTORY_MSG_314;W - Gamut - Reduce artifacts
|
||||
HISTORY_MSG_315;W - Residual - Contrast
|
||||
HISTORY_MSG_316;W - Gamut - Skin tar/prot
|
||||
HISTORY_MSG_317;W - Gamut - Skin hue
|
||||
HISTORY_MSG_318;W - Contrast - Fine levels
|
||||
HISTORY_MSG_319;W - Contrast - Fine range
|
||||
HISTORY_MSG_320;W - Contrast - Coarse range
|
||||
HISTORY_MSG_321;W - Contrast - Coarse levels
|
||||
HISTORY_MSG_318;W - Contrast - Finer levels
|
||||
HISTORY_MSG_319;W - Contrast - Finer range
|
||||
HISTORY_MSG_320;W - Contrast - Coarser range
|
||||
HISTORY_MSG_321;W - Contrast - Coarser levels
|
||||
HISTORY_MSG_322;W - Gamut - Avoid color shift
|
||||
HISTORY_MSG_323;W - ES - Local contrast
|
||||
HISTORY_MSG_324;W - Chroma - Pastel
|
||||
@ -636,14 +636,14 @@ HISTORY_MSG_381;PRS RLD - Radius
|
||||
HISTORY_MSG_382;PRS RLD - Amount
|
||||
HISTORY_MSG_383;PRS RLD - Damping
|
||||
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_387;W - Residual - CB blue high
|
||||
HISTORY_MSG_388;W - Residual - CB green mid
|
||||
HISTORY_MSG_389;W - Residual - CB blue mid
|
||||
HISTORY_MSG_390;W - Residual - CB green 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_394;DCP - Baseline exposure
|
||||
HISTORY_MSG_395;DCP - Base table
|
||||
@ -1199,7 +1199,7 @@ HISTORY_MSG_956;Local - CH Curve
|
||||
HISTORY_MSG_BLSHAPE;Blur by level
|
||||
HISTORY_MSG_BLURCWAV;Blur chroma
|
||||
HISTORY_MSG_BLURWAV;Blur luminance
|
||||
HISTORY_MSG_BLUWAV;Attenuation Response
|
||||
HISTORY_MSG_BLUWAV;Attenuation response
|
||||
HISTORY_MSG_CAT02PRESET;Cat02 automatic preset
|
||||
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
|
||||
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_SHOWMASK;CT - region show mask
|
||||
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_ENABLED;Haze Removal
|
||||
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_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto 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_FILMBASE;Film base color
|
||||
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_CONTRAST;Sharpening - Contrast threshold
|
||||
HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace
|
||||
HISTORY_MSG_SIGMACOL;Chroma Attenuation Response
|
||||
HISTORY_MSG_SIGMADIR;Dir Attenuation Response
|
||||
HISTORY_MSG_SIGMAFIN;Final contrast Attenuation Response
|
||||
HISTORY_MSG_SIGMATON;Toning Attenuation Response
|
||||
HISTORY_MSG_SIGMACOL;Chroma Attenuation response
|
||||
HISTORY_MSG_SIGMADIR;Dir Attenuation response
|
||||
HISTORY_MSG_SIGMAFIN;Final contrast Attenuation response
|
||||
HISTORY_MSG_SIGMATON;Toning Attenuation response
|
||||
HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
|
||||
HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
|
||||
HISTORY_MSG_TEMPOUT;CAM02 automatic temperature
|
||||
@ -1292,10 +1294,10 @@ HISTORY_MSG_WAVMERGEC;Merge C
|
||||
HISTORY_MSG_WAVMERGEL;Merge L
|
||||
HISTORY_MSG_WAVOFFSET;Offset
|
||||
HISTORY_MSG_WAVOLDSH;Old algorithm
|
||||
HISTORY_MSG_WAVRADIUS;Radius Shadows-Highlight
|
||||
HISTORY_MSG_WAVRADIUS;Radius shadows-highlights
|
||||
HISTORY_MSG_WAVSCALE;Scale
|
||||
HISTORY_MSG_WAVSHOWMASK;Show wavelet mask
|
||||
HISTORY_MSG_WAVSIGMA;Attenuation Response
|
||||
HISTORY_MSG_WAVSIGMA;Attenuation response
|
||||
HISTORY_MSG_WAVSOFTRAD;Soft radius clarity
|
||||
HISTORY_MSG_WAVSOFTRADEND;Soft radius final
|
||||
HISTORY_MSG_WAVUSHAMET;Clarity method
|
||||
@ -3237,18 +3239,18 @@ TP_WAVELET_6;Level 6
|
||||
TP_WAVELET_7;Level 7
|
||||
TP_WAVELET_8;Level 8
|
||||
TP_WAVELET_9;Level 9
|
||||
TP_WAVELET_APPLYTO;Apply To
|
||||
TP_WAVELET_APPLYTO;Apply to
|
||||
TP_WAVELET_AVOID;Avoid color shift
|
||||
TP_WAVELET_B0;Black
|
||||
TP_WAVELET_B1;Grey
|
||||
TP_WAVELET_B1;Gray
|
||||
TP_WAVELET_B2;Residual
|
||||
TP_WAVELET_BACKGROUND;Background
|
||||
TP_WAVELET_BACUR;Curve
|
||||
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_BALCHRO;Chrominance balance
|
||||
TP_WAVELET_BALCHROM;Denoise Equalizer Blue-yellow Red-green
|
||||
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_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_BANONE;None
|
||||
TP_WAVELET_BASLI;Slider
|
||||
@ -3256,9 +3258,9 @@ TP_WAVELET_BATYPE;Contrast balance method
|
||||
TP_WAVELET_BL;Blur levels
|
||||
TP_WAVELET_BLCURVE;Blur by levels
|
||||
TP_WAVELET_BLURFRAME;Blur
|
||||
TP_WAVELET_BLUWAV;Attenuation Response
|
||||
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_BLUWAV;Attenuation response
|
||||
TP_WAVELET_CBENAB;Toning and Color balance
|
||||
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_CH1;Whole chroma range
|
||||
TP_WAVELET_CH2;Saturated/pastel
|
||||
@ -3266,7 +3268,7 @@ TP_WAVELET_CH3;Link contrast levels
|
||||
TP_WAVELET_CHCU;Curve
|
||||
TP_WAVELET_CHR;Chroma-contrast link strength
|
||||
TP_WAVELET_CHRO;Saturated/pastel threshold
|
||||
TP_WAVELET_CHROFRAME;Denoise Chrominance
|
||||
TP_WAVELET_CHROFRAME;Denoise chrominance
|
||||
TP_WAVELET_CHROMAFRAME;Chroma
|
||||
TP_WAVELET_CHROMCO;Chrominance Coarse
|
||||
TP_WAVELET_CHROMFI;Chrominance Fine
|
||||
@ -3277,10 +3279,14 @@ TP_WAVELET_CHSL;Sliders
|
||||
TP_WAVELET_CHTYPE;Chrominance method
|
||||
TP_WAVELET_CLA;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_COMPGAMMA;Compression gamma
|
||||
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_CONTEDIT;'After' contrast curve
|
||||
TP_WAVELET_CONTFRAME;Contrast - Compression
|
||||
@ -3289,16 +3295,16 @@ TP_WAVELET_CONTRA;Contrast
|
||||
TP_WAVELET_CONTRASTEDIT;Finer - Coarser levels
|
||||
TP_WAVELET_CONTRAST_MINUS;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_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_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_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_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_DAUB;Edge performance
|
||||
TP_WAVELET_DAUB2;D2 - low
|
||||
@ -3307,34 +3313,34 @@ TP_WAVELET_DAUB6;D6 - standard plus
|
||||
TP_WAVELET_DAUB10;D10 - medium
|
||||
TP_WAVELET_DAUB14;D14 - high
|
||||
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_DONE;Vertical
|
||||
TP_WAVELET_DTHR;Diagonal
|
||||
TP_WAVELET_DTWO;Horizontal
|
||||
TP_WAVELET_EDCU;Curve
|
||||
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;Attenuation response
|
||||
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_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_EDGEAMPLI;Base amplification
|
||||
TP_WAVELET_EDGEDETECT;Gradient sensitivity
|
||||
TP_WAVELET_EDGEDETECTTHR;Threshold low (noise)
|
||||
TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection)
|
||||
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_EDGEDETECTTHR2;Edge enhancement
|
||||
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_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_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_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_EDSL;Threshold Sliders
|
||||
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_EDTYPE;Local contrast method
|
||||
TP_WAVELET_EDVAL;Strength
|
||||
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_FINEST;Finest
|
||||
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_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_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_ITER;Delta balance 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_LEVCH;Chroma
|
||||
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_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_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_LEVLABEL;Preview maximum possible levels = %1
|
||||
TP_WAVELET_LEVONE;Level 2
|
||||
TP_WAVELET_LEVTHRE;Level 4
|
||||
TP_WAVELET_LEVTWO;Level 3
|
||||
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_LOWLIGHT;Coarser levels luminance range
|
||||
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_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_MERGEC;Merge Chroma
|
||||
TP_WAVELET_MERGEC;Merge chroma
|
||||
TP_WAVELET_MERGEL;Merge Luma
|
||||
TP_WAVELET_NEUTRAL;Neutral
|
||||
TP_WAVELET_NOIS;Denoise
|
||||
@ -3380,24 +3386,24 @@ TP_WAVELET_NPLOW;Low
|
||||
TP_WAVELET_NPNONE;None
|
||||
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_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_OPACITY;Opacity Blue-Yellow
|
||||
TP_WAVELET_OPACITY;Opacity blue-yellow
|
||||
TP_WAVELET_OPACITYW;Contrast balance d/v-h curve
|
||||
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_PASTEL;Pastel chroma
|
||||
TP_WAVELET_PROC;Process
|
||||
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_RE1;Reinforced
|
||||
TP_WAVELET_RE2;Unchanged
|
||||
TP_WAVELET_RE3;Reduced
|
||||
TP_WAVELET_RESBLUR;Blur Luminance
|
||||
TP_WAVELET_RESBLURC;Blur Chroma
|
||||
TP_WAVELET_RESBLUR;Blur luminance
|
||||
TP_WAVELET_RESBLURC;Blur chroma
|
||||
TP_WAVELET_RESBLUR_TOOLTIP;Disabled if zoom > about 500%
|
||||
TP_WAVELET_RESCHRO;Intensity
|
||||
TP_WAVELET_RESCHRO;Strength
|
||||
TP_WAVELET_RESCON;Shadows
|
||||
TP_WAVELET_RESCONH;Highlights
|
||||
TP_WAVELET_RESID;Residual Image
|
||||
@ -3406,15 +3412,15 @@ TP_WAVELET_SETTINGS;Wavelet Settings
|
||||
TP_WAVELET_SHA;Sharp mask
|
||||
TP_WAVELET_SHFRAME;Shadows/Highlights
|
||||
TP_WAVELET_SHOWMASK;Show wavelet 'mask'
|
||||
TP_WAVELET_SIGMA;Attenuation Response
|
||||
TP_WAVELET_SIGMAFIN;Attenuation Response
|
||||
TP_WAVELET_SIGMA;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_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_SKY;Sky 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_SOFTRAD;Soft Radius
|
||||
TP_WAVELET_STREN;Strength
|
||||
TP_WAVELET_SKY;Hue targetting/protection
|
||||
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_STREN;Refine
|
||||
TP_WAVELET_STRENGTH;Strength
|
||||
TP_WAVELET_SUPE;Extra
|
||||
TP_WAVELET_THR;Shadows threshold
|
||||
@ -3422,7 +3428,7 @@ TP_WAVELET_THRESHOLD;Finer 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_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_TILESBIG;Tiles
|
||||
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_TMTYPE;Compression method
|
||||
TP_WAVELET_TON;Toning
|
||||
TP_WAVELET_TONFRAME;Excluded Colors
|
||||
TP_WAVELET_TONFRAME;Excluded colors
|
||||
TP_WAVELET_USH;None
|
||||
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_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_WAVOFFSET;Offset
|
||||
TP_WBALANCE_AUTO;Auto
|
||||
|
@ -123,7 +123,7 @@ float* RawImageSource::CA_correct_RT(
|
||||
double cared,
|
||||
double cablue,
|
||||
bool avoidColourshift,
|
||||
const array2D<float> &rawData,
|
||||
array2D<float> &rawData,
|
||||
double* fitParamsTransfer,
|
||||
bool fitParamsIn,
|
||||
bool fitParamsOut,
|
||||
@ -1291,7 +1291,7 @@ float* RawImageSource::CA_correct_RT(
|
||||
for (int i = 0; i < H - 2 * cb; ++i) {
|
||||
const int firstCol = fc(cfa, i, 0) & 1;
|
||||
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;
|
||||
#ifdef __SSE2__
|
||||
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 ngCol = fc(cfa, ngRow, 0) & 1;
|
||||
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) {
|
||||
(*nonGreen)[i][(W - 2 * cb + 1) / 2 - 1] = (*nonGreen)[i][(W - 2* cb + 1) / 2 - 2];
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
*
|
||||
* 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
|
||||
* value = my_array[3][5];
|
||||
@ -48,25 +48,20 @@
|
||||
* array2D<float> my_array ; // empty container.
|
||||
* 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|ARRAY2D_LOCK_DATA) ; same but set a lock on changes
|
||||
*
|
||||
* !! locked arrays cannot be resized and cannot be unlocked again !!
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <csignal> // for raise()
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <sys/types.h>
|
||||
#include <vector>
|
||||
#include "noncopyable.h"
|
||||
|
||||
// flags for use
|
||||
#define ARRAY2D_LOCK_DATA 1
|
||||
#define ARRAY2D_CLEAR_DATA 2
|
||||
#define ARRAY2D_BYREFERENCE 4
|
||||
#define ARRAY2D_VERBOSE 8
|
||||
constexpr unsigned int ARRAY2D_CLEAR_DATA = 1;
|
||||
constexpr unsigned int ARRAY2D_BYREFERENCE = 2;
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include "noncopyable.h"
|
||||
|
||||
template<typename T>
|
||||
class array2D :
|
||||
@ -74,249 +69,158 @@ class array2D :
|
||||
{
|
||||
|
||||
private:
|
||||
int x, y, owner;
|
||||
unsigned int flags;
|
||||
T ** ptr;
|
||||
T * data;
|
||||
bool lock; // useful lock to ensure data is not changed anymore.
|
||||
void ar_realloc(int w, int h, int offset = 0)
|
||||
ssize_t width;
|
||||
std::vector<T*> rows;
|
||||
std::vector<T> buffer;
|
||||
|
||||
void initRows(ssize_t h, int offset = 0)
|
||||
{
|
||||
if ((ptr) && ((h > y) || (4 * h < y))) {
|
||||
delete[] ptr;
|
||||
ptr = nullptr;
|
||||
rows.resize(h);
|
||||
T* start = buffer.data() + offset;
|
||||
for (ssize_t i = 0; i < h; ++i) {
|
||||
rows[i] = start + width * i;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) {
|
||||
delete[] data;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
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;
|
||||
void ar_realloc(ssize_t w, ssize_t h, int offset = 0)
|
||||
{
|
||||
width = w;
|
||||
buffer.resize(h * width + offset);
|
||||
initRows(h, offset);
|
||||
}
|
||||
public:
|
||||
|
||||
// use as empty declaration, resize before use!
|
||||
// very useful as a member object
|
||||
array2D() :
|
||||
x(0), y(0), owner(0), flags(0), ptr(nullptr), data(nullptr), lock(false)
|
||||
{
|
||||
//printf("got empty array2D init\n");
|
||||
}
|
||||
array2D() : width(0) {}
|
||||
|
||||
// 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) {
|
||||
memset(data, 0, w * h * sizeof(T));
|
||||
buffer.resize(h * width, 0);
|
||||
} else {
|
||||
buffer.resize(h * width);
|
||||
}
|
||||
initRows(h);
|
||||
}
|
||||
|
||||
// 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;
|
||||
//if (lock) { printf("array2D attempt to overwrite data\n");raise(SIGSEGV);}
|
||||
lock = flags & ARRAY2D_LOCK_DATA;
|
||||
// when by reference
|
||||
// TODO: improve this code with ar_realloc()
|
||||
owner = (flags & ARRAY2D_BYREFERENCE) ? 0 : 1;
|
||||
|
||||
if (owner) {
|
||||
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];
|
||||
rows.resize(h);
|
||||
if (!(flags & ARRAY2D_BYREFERENCE)) {
|
||||
buffer.resize(h * width);
|
||||
T* start = buffer.data();
|
||||
for (ssize_t i = 0; i < h; ++i) {
|
||||
rows[i] = start + i * width;
|
||||
for (ssize_t j = 0; j < width; ++j) {
|
||||
rows[i][j] = source[i][j];
|
||||
}
|
||||
} else {
|
||||
ptr[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;
|
||||
} else {
|
||||
for (ssize_t i = 0; i < h; ++i) {
|
||||
rows[i] = source[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill(const T val, bool multiThread = false)
|
||||
{
|
||||
const ssize_t height = rows.size();
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for if(multiThread)
|
||||
#endif
|
||||
for (int i = 0; i < x * y; ++i) {
|
||||
data[i] = val;
|
||||
for (ssize_t i = 0; i < width * height; ++i) {
|
||||
buffer[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
if ((owner) && (data)) {
|
||||
delete[] data;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
delete [] ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
buffer.clear();
|
||||
rows.clear();
|
||||
}
|
||||
|
||||
// use with indices
|
||||
T * operator[](int index) const
|
||||
T * operator[](int index)
|
||||
{
|
||||
assert((index >= 0) && (index < y));
|
||||
return ptr[index];
|
||||
assert((index >= 0) && (index < rows.size()));
|
||||
return rows[index];
|
||||
}
|
||||
|
||||
const T * operator[](int index) const
|
||||
{
|
||||
assert((index >= 0) && (index < rows.size()));
|
||||
return rows[index];
|
||||
}
|
||||
|
||||
// use as pointer to T**
|
||||
operator T**()
|
||||
{
|
||||
return ptr;
|
||||
return rows.data();
|
||||
}
|
||||
|
||||
// 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*()
|
||||
{
|
||||
// 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
|
||||
// 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);
|
||||
|
||||
if (flags & ARRAY2D_CLEAR_DATA) {
|
||||
memset(data + offset, 0, static_cast<unsigned long>(w) * h * sizeof(T));
|
||||
fill(0);
|
||||
}
|
||||
}
|
||||
|
||||
// import from flat data
|
||||
void operator()(int w, int h, T* copy, unsigned int flgs = 0)
|
||||
int getWidth() const
|
||||
{
|
||||
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);
|
||||
memcpy(data, copy, w * h * sizeof(T));
|
||||
return width;
|
||||
}
|
||||
int width() const
|
||||
int getHeight() const
|
||||
{
|
||||
return x;
|
||||
}
|
||||
int height() const
|
||||
{
|
||||
return y;
|
||||
return rows.size();
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return (x > 0 && y > 0);
|
||||
return (width > 0 && !rows.empty());
|
||||
}
|
||||
|
||||
};
|
||||
template<typename T, const size_t num>
|
||||
class multi_array2D
|
||||
class multi_array2D : public rtengine::NonCopyable
|
||||
{
|
||||
private:
|
||||
array2D<T> list[num];
|
||||
|
||||
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++) {
|
||||
list[i](x, y, flags, (i + 1) * offset);
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
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)
|
||||
{
|
||||
assert(static_cast<size_t>(index) < num);
|
||||
|
@ -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.
|
||||
// No aperture scaling data provided, but likely negligible
|
||||
},
|
||||
|
||||
{ // Quality C, only raw crop
|
||||
"make_model": [ "FUJIFILM X-T3", "FUJIFILM X-T30", "FUJIFILM X-PRO3", "FUJIFILM X100V", "FUJIFILM X-T4" ],
|
||||
|
||||
{ // Quality A, samples provided by Daniel Catalina (#5839) and pi99y (#5860)
|
||||
"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
|
||||
"raw_crop": [ 0, 5, 6252, 4176]
|
||||
},
|
||||
@ -2747,6 +2755,12 @@ Camera constants:
|
||||
"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)
|
||||
"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
|
||||
|
@ -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__
|
||||
|
@ -623,7 +623,7 @@ public:
|
||||
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 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
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
const int W = src.width();
|
||||
const int H = src.height();
|
||||
const int W = src.getWidth();
|
||||
const int H = src.getHeight();
|
||||
|
||||
if (subsampling <= 0) {
|
||||
subsampling = calculate_subsampling(W, H, r);
|
||||
@ -94,8 +94,8 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
|
||||
const auto apply =
|
||||
[=](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 h = res.height();
|
||||
const int w = res.getWidth();
|
||||
const int h = res.getHeight();
|
||||
|
||||
#ifdef _OPENMP
|
||||
#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 =
|
||||
[=](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
|
||||
# pragma omp parallel for if (multithread)
|
||||
#endif
|
||||
for (int y = 0; y < s.height(); ++y) {
|
||||
for (int x = 0; x < s.width(); ++x) {
|
||||
for (int y = 0; y < s.getHeight(); ++y) {
|
||||
for (int x = 0; x < s.getWidth(); ++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 =
|
||||
[multithread](array2D<float> &d, array2D<float> &s, int rad) -> void
|
||||
{
|
||||
rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1);
|
||||
// boxblur(s, d, rad, s.width(), s.height(), multithread);
|
||||
boxblur(static_cast<float**>(s), static_cast<float**>(d), rad, s.width(), s.height(), multithread);
|
||||
rad = LIM(rad, 0, (min(s.getWidth(), s.getHeight()) - 1) / 2 - 1);
|
||||
// boxblur(s, d, rad, s.getWidth(), s.getHeight(), multithread);
|
||||
boxblur(static_cast<float**>(s), static_cast<float**>(d), rad, s.getWidth(), s.getHeight(), multithread);
|
||||
};
|
||||
|
||||
array2D<float> I1(w, h);
|
||||
@ -225,10 +225,10 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
|
||||
DEBUG_DUMP(meanb);
|
||||
|
||||
// speedup by heckflosse67
|
||||
const int Ws = meana.width();
|
||||
const int Hs = meana.height();
|
||||
const int Wd = q.width();
|
||||
const int Hd = q.height();
|
||||
const int Ws = meana.getWidth();
|
||||
const int Hs = meana.getHeight();
|
||||
const int Wd = q.getWidth();
|
||||
const int Hd = q.getHeight();
|
||||
const float col_scale = float(Ws) / float(Wd);
|
||||
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
|
||||
# pragma omp parallel for if (multithread)
|
||||
#endif
|
||||
for (int y = 0; y < chan.height(); ++y) {
|
||||
for (int x = 0; x < chan.width(); ++x) {
|
||||
for (int y = 0; y < chan.getHeight(); ++y) {
|
||||
for (int x = 0; x < chan.getWidth(); ++x) {
|
||||
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
|
||||
# pragma omp parallel for if (multithread)
|
||||
#endif
|
||||
for (int y = 0; y < chan.height(); ++y) {
|
||||
for (int x = 0; x < chan.width(); ++x) {
|
||||
for (int y = 0; y < chan.getHeight(); ++y) {
|
||||
for (int x = 0; x < chan.getWidth(); ++x) {
|
||||
chan[y][x] = xlog2lin(max(chan[y][x], 0.f), base);
|
||||
}
|
||||
}
|
||||
|
@ -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 H = R.height();
|
||||
const int W = R.getWidth();
|
||||
const int H = R.getHeight();
|
||||
|
||||
#ifdef _OPENMP
|
||||
#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));
|
||||
}
|
||||
|
||||
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 H = R.height();
|
||||
const int W = R.getWidth();
|
||||
const int H = R.getHeight();
|
||||
|
||||
#ifdef _OPENMP
|
||||
#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])
|
||||
{
|
||||
const int W = R.width();
|
||||
const int H = R.height();
|
||||
const int W = R.getWidth();
|
||||
const int H = R.getHeight();
|
||||
|
||||
float darklim = RT_INFINITY_F;
|
||||
{
|
||||
|
@ -1840,8 +1840,8 @@ void tone_eq(array2D<float> &R, array2D<float> &G, array2D<float> &B, const stru
|
||||
{
|
||||
BENCHFUN
|
||||
|
||||
const int W = R.width();
|
||||
const int H = R.height();
|
||||
const int W = R.getWidth();
|
||||
const int H = R.getHeight();
|
||||
array2D<float> Y(W, H);
|
||||
|
||||
const auto log2 =
|
||||
|
@ -323,14 +323,14 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
|
||||
}
|
||||
|
||||
cp.CHSLmet = 1;
|
||||
cp.EDmet = 1;
|
||||
|
||||
cp.EDmet = 2;
|
||||
/*
|
||||
if (params->wavelet.EDmethod == "SL") {
|
||||
cp.EDmet = 1;
|
||||
} else if (params->wavelet.EDmethod == "CU") {
|
||||
cp.EDmet = 2;
|
||||
}
|
||||
|
||||
*/
|
||||
cp.cbena = params->wavelet.cbenab;
|
||||
cp.blhigh = (float)params->wavelet.bluehigh;
|
||||
cp.grhigh = (float)params->wavelet.greenhigh;
|
||||
@ -1579,10 +1579,16 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
|
||||
|
||||
if (numtiles > 1) {
|
||||
float factor = Vmask[i1] * Hmask[j1];
|
||||
if(L <= 0.f) {
|
||||
L= 1.f;
|
||||
}
|
||||
dsttmp->L[i][j] += factor * L;
|
||||
dsttmp->a[i][j] += factor * a;
|
||||
dsttmp->b[i][j] += factor * b;
|
||||
} else {
|
||||
if(L <= 0.f) {
|
||||
L= 1.f;
|
||||
}
|
||||
dsttmp->L[i][j] = L;
|
||||
dsttmp->a[i][j] = a;
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
#ifdef _OPENMP
|
||||
#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
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
@ -2208,9 +2216,9 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
|
||||
for (int lvl = 0; lvl < 4; lvl++) {
|
||||
for (int dir = 1; dir < 4; dir++) {
|
||||
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);
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
maxkoeLi = koeLi[level * 3 + dir - 1][i * W_L + j];
|
||||
}
|
||||
|
||||
float diff = maxkoeLi - koeLi[level * 3 + dir - 1][i * W_L + j];
|
||||
diff *= diffFactor;
|
||||
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
|
||||
float insigma = 0.666f; //SD
|
||||
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 iny = log(rapX);
|
||||
float rap = inx / iny; //koef
|
||||
float asig = 0.166f / (sigma[level] * cp.sigmafin);
|
||||
float bsig = 0.5f - asig * mean[level];
|
||||
float amean = 0.5f / mean[level];
|
||||
float amean = 0.5f / (mean[level]);
|
||||
|
||||
#ifdef _OPENMP
|
||||
#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));
|
||||
|
||||
maxkoe = rtengine::max(maxkoe, koe[i * W_L + j]);
|
||||
|
||||
float diff = maxkoe - koe[i * W_L + j];
|
||||
diff *= (cp.eddet / 100.f);
|
||||
float interm = maxkoe - diff;
|
||||
@ -3089,10 +3095,13 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
|
||||
float atten01234 = 0.80f;
|
||||
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;
|
||||
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 repart = (float)cp.til;
|
||||
|
||||
@ -3100,15 +3109,14 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
|
||||
if (cp.reinforce != 2) {
|
||||
const float brepart =
|
||||
cp.reinforce == 1
|
||||
? 3.f
|
||||
: 0.5f;
|
||||
? edghig
|
||||
: edglow;
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
float al0 = 1.f + (repart) / 50.f;
|
||||
float al10 = 1.0f; //arbitrary value ==> less = take into account high 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 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
|
||||
printf("repart=%f\n", repart);
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -3158,13 +3167,13 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz,
|
||||
// if (exa) {//curve
|
||||
float insigma = 0.666f; //SD
|
||||
float logmax = log(MaxP[level]); //log Max
|
||||
float rapX = (mean[level] + sigma[level]) / MaxP[level]; //rapport between sD / max
|
||||
float rapX = (mean[level] + sigma[level]) / (MaxP[level]); //rapport between sD / max
|
||||
float inx = log(insigma);
|
||||
float iny = log(rapX);
|
||||
float rap = inx / iny; //koef
|
||||
float asig = 0.166f / sigma[level];
|
||||
float asig = 0.166f / (sigma[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 kinterm;
|
||||
float kmul;
|
||||
|
@ -459,6 +459,7 @@ RetinexParams::RetinexParams() :
|
||||
shadows(0),
|
||||
stonalwidth(80),
|
||||
radius(40),
|
||||
complexmethod("normal"),
|
||||
retinexMethod("high"),
|
||||
retinexcolorspace("Lab"),
|
||||
gammaretinex("none"),
|
||||
@ -496,6 +497,7 @@ bool RetinexParams::operator ==(const RetinexParams& other) const
|
||||
&& shadows == other.shadows
|
||||
&& stonalwidth == other.stonalwidth
|
||||
&& radius == other.radius
|
||||
&& complexmethod == other.complexmethod
|
||||
&& retinexMethod == other.retinexMethod
|
||||
&& retinexcolorspace == other.retinexcolorspace
|
||||
&& gammaretinex == other.gammaretinex
|
||||
@ -2395,6 +2397,7 @@ WaveletParams::WaveletParams() :
|
||||
CLmethod("all"),
|
||||
Backmethod("grey"),
|
||||
Tilesmethod("full"),
|
||||
complexmethod("normal"),
|
||||
daubcoeffmethod("4_"),
|
||||
CHmethod("without"),
|
||||
Medgreinf("less"),
|
||||
@ -2527,6 +2530,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const
|
||||
&& CLmethod == other.CLmethod
|
||||
&& Backmethod == other.Backmethod
|
||||
&& Tilesmethod == other.Tilesmethod
|
||||
&& complexmethod == other.complexmethod
|
||||
&& daubcoeffmethod == other.daubcoeffmethod
|
||||
&& CHmethod == other.CHmethod
|
||||
&& 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.highl, "Retinex", "highl", retinex.highl, 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.mapMethod, "Retinex", "mapMethod", retinex.mapMethod, 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.thres, "Wavelet", "MaxLev", wavelet.thres, 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.CLmethod, "Wavelet", "ChoiceLevMethod", wavelet.CLmethod, 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")) {
|
||||
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", "mapMethod", pedited, retinex.mapMethod, pedited->retinex.mapMethod);
|
||||
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", "BackMethod", pedited, wavelet.Backmethod, pedited->wavelet.Backmethod);
|
||||
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", "CHromaMethod", pedited, wavelet.CHmethod, pedited->wavelet.CHmethod);
|
||||
assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", pedited, wavelet.Medgreinf, pedited->wavelet.Medgreinf);
|
||||
|
@ -336,6 +336,7 @@ struct RetinexParams {
|
||||
int stonalwidth;
|
||||
int radius;
|
||||
|
||||
Glib::ustring complexmethod;
|
||||
Glib::ustring retinexMethod;
|
||||
Glib::ustring retinexcolorspace;
|
||||
Glib::ustring gammaretinex;
|
||||
@ -1790,6 +1791,7 @@ struct WaveletParams {
|
||||
Glib::ustring CLmethod;
|
||||
Glib::ustring Backmethod;
|
||||
Glib::ustring Tilesmethod;
|
||||
Glib::ustring complexmethod;
|
||||
Glib::ustring daubcoeffmethod;
|
||||
Glib::ustring CHmethod;
|
||||
Glib::ustring Medgreinf;
|
||||
|
@ -247,7 +247,7 @@ protected:
|
||||
double cared,
|
||||
double cablue,
|
||||
bool avoidColourshift,
|
||||
const array2D<float> &rawData,
|
||||
array2D<float> &rawData,
|
||||
double* fitParamsTransfer,
|
||||
bool fitParamsIn,
|
||||
bool fitParamsOut,
|
||||
|
@ -31,8 +31,8 @@ namespace rtengine
|
||||
|
||||
inline float getBilinearValue(const array2D<float> &src, float x, float y)
|
||||
{
|
||||
const int W = src.width();
|
||||
const int H = src.height();
|
||||
const int W = src.getWidth();
|
||||
const int H = src.getHeight();
|
||||
|
||||
// Get integer and fractional parts of numbers
|
||||
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)
|
||||
{
|
||||
const int Ws = src.width();
|
||||
const int Hs = src.height();
|
||||
const int Wd = dst.width();
|
||||
const int Hd = dst.height();
|
||||
const int Ws = src.getWidth();
|
||||
const int Hs = src.getHeight();
|
||||
const int Wd = dst.getWidth();
|
||||
const int Hd = dst.getHeight();
|
||||
|
||||
float col_scale = float (Ws) / float (Wd);
|
||||
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)
|
||||
{
|
||||
const int width = src.width();
|
||||
const int height = src.height();
|
||||
const int nw = dst.width();
|
||||
const int nh = dst.height();
|
||||
const int width = src.getWidth();
|
||||
const int height = src.getHeight();
|
||||
const int nw = dst.getWidth();
|
||||
const int nh = dst.getHeight();
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for if (multithread)
|
||||
|
@ -99,6 +99,10 @@ public:
|
||||
int itcwb_delta;
|
||||
bool itcwb_stdobserver10;
|
||||
int itcwb_precis;
|
||||
//wavelet levels
|
||||
double edghi;
|
||||
double edglo;
|
||||
double limrad;
|
||||
|
||||
|
||||
enum class ThumbnailInspectorMode {
|
||||
|
@ -123,12 +123,12 @@ public:
|
||||
|
||||
int getRows() const
|
||||
{
|
||||
return const_cast<Array2Df &>(*this).height();
|
||||
return const_cast<Array2Df &>(*this).getHeight();
|
||||
}
|
||||
|
||||
int getCols() const
|
||||
{
|
||||
return const_cast<Array2Df &>(*this).width();
|
||||
return const_cast<Array2Df &>(*this).getWidth();
|
||||
}
|
||||
|
||||
float *data()
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "pathutils.h"
|
||||
#include "thumbnail.h"
|
||||
#include "toolbar.h"
|
||||
#include "inspector.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -115,9 +115,9 @@ FilePanel::FilePanel () : parent(nullptr), error(0)
|
||||
Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) );
|
||||
devLab->set_name ("LabelRightNotebook");
|
||||
devLab->set_angle (90);
|
||||
Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) );
|
||||
inspectLab->set_name ("LabelRightNotebook");
|
||||
inspectLab->set_angle (90);
|
||||
//Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) );
|
||||
//inspectLab->set_name ("LabelRightNotebook");
|
||||
//inspectLab->set_angle (90);
|
||||
Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) );
|
||||
filtLab->set_name ("LabelRightNotebook");
|
||||
filtLab->set_angle (90);
|
||||
@ -132,7 +132,7 @@ FilePanel::FilePanel () : parent(nullptr), error(0)
|
||||
tpcPaned->pack2 (*history, true, false);
|
||||
|
||||
rightNotebook->append_page (*sFilterPanel, *filtLab);
|
||||
rightNotebook->append_page (*inspectorPanel, *inspectLab);
|
||||
//rightNotebook->append_page (*inspectorPanel, *inspectLab);
|
||||
rightNotebook->append_page (*tpcPaned, *devLab);
|
||||
//rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ...
|
||||
rightNotebook->append_page (*sExportPanel, *exportLab);
|
||||
|
@ -82,9 +82,25 @@ InspectorBuffer::~InspectorBuffer() {
|
||||
// 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");
|
||||
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()
|
||||
@ -92,8 +108,184 @@ Inspector::~Inspector()
|
||||
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)
|
||||
{
|
||||
dirty = false;
|
||||
|
||||
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 topLeft;
|
||||
rtengine::Coord dest(0, 0);
|
||||
availableSize.x = win->get_width();
|
||||
availableSize.y = win->get_height();
|
||||
int imW = currImage->imgBuffer.getWidth();
|
||||
int imH = currImage->imgBuffer.getHeight();
|
||||
int deviceScale = get_scale_factor();
|
||||
availableSize.x = win->get_width() * deviceScale;
|
||||
availableSize.y = win->get_height() * deviceScale;
|
||||
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) {
|
||||
// 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 = 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);
|
||||
|
||||
// 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();
|
||||
|
||||
// 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);
|
||||
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
|
||||
cr->set_line_width (0);
|
||||
cr->rectangle (0, 0, availableSize.x, availableSize.y);
|
||||
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
|
||||
c = style->get_border_color (Gtk::STATE_FLAG_NORMAL);
|
||||
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
|
||||
cr->set_line_width (1);
|
||||
cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1);
|
||||
cr->stroke ();
|
||||
*/
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -309,7 +540,7 @@ void Inspector::setActive(bool state)
|
||||
flushBuffers();
|
||||
}
|
||||
|
||||
active = state;
|
||||
//active = state;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,12 +47,30 @@ private:
|
||||
rtengine::Coord center;
|
||||
std::vector<InspectorBuffer*> images;
|
||||
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 pinned;
|
||||
bool dirty;
|
||||
|
||||
sigc::connection delayconn;
|
||||
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;
|
||||
void deleteBuffers();
|
||||
|
||||
@ -62,6 +80,11 @@ public:
|
||||
Inspector();
|
||||
~Inspector() override;
|
||||
|
||||
/** @brief Show or hide window
|
||||
* @param scaled fit image into window
|
||||
*/
|
||||
void showWindow(bool scaled);
|
||||
|
||||
/** @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 transform H/V flip and coarse rotation transformation
|
||||
|
@ -663,6 +663,8 @@ void LCurve::updateCurveBackgroundHistogram(
|
||||
{
|
||||
lshape->updateBackgroundHistogram (histLCurve);
|
||||
ccshape->updateBackgroundHistogram (histCCurve);
|
||||
lcshape->updateBackgroundHistogram (histCCurve);
|
||||
clshape->updateBackgroundHistogram (histLCurve);
|
||||
}
|
||||
|
||||
void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd)
|
||||
|
@ -618,6 +618,12 @@ void Options::setDefaults()
|
||||
rtSettings.itcwb_precis = 5;//3 or 5 or 9
|
||||
// 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.protectredh = 0.3;
|
||||
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_key("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_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_double("ICC Profile Creator", "RedPrimaryX", ICCPC_redPrimaryX);
|
||||
keyFile.set_double("ICC Profile Creator", "RedPrimaryY", ICCPC_redPrimaryY);
|
||||
|
@ -60,6 +60,7 @@ void ParamsEdited::set(bool v)
|
||||
retinex.mapcurve = v;
|
||||
retinex.cdHcurve = v;
|
||||
retinex.lhcurve = v;
|
||||
retinex.complexmethod = v;
|
||||
retinex.retinexMethod = v;
|
||||
retinex.mapMethod = v;
|
||||
retinex.viewMethod = v;
|
||||
@ -531,6 +532,7 @@ void ParamsEdited::set(bool v)
|
||||
wavelet.CLmethod = v;
|
||||
wavelet.Backmethod = v;
|
||||
wavelet.Tilesmethod = v;
|
||||
wavelet.complexmethod = v;
|
||||
wavelet.daubcoeffmethod = v;
|
||||
wavelet.CHmethod = 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.transmissionCurve = retinex.transmissionCurve && p.retinex.transmissionCurve == other.retinex.transmissionCurve;
|
||||
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.mapMethod = retinex.mapMethod && p.retinex.mapMethod == other.retinex.mapMethod;
|
||||
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.Backmethod = wavelet.Backmethod && p.wavelet.Backmethod == other.wavelet.Backmethod;
|
||||
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.CHmethod = wavelet.CHmethod && p.wavelet.CHmethod == other.wavelet.CHmethod;
|
||||
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;
|
||||
}
|
||||
|
||||
if (retinex.complexmethod) {
|
||||
toEdit.retinex.complexmethod = mods.retinex.complexmethod;
|
||||
}
|
||||
|
||||
if (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;
|
||||
}
|
||||
|
||||
if (wavelet.complexmethod) {
|
||||
toEdit.wavelet.complexmethod = mods.wavelet.complexmethod;
|
||||
}
|
||||
|
||||
if (wavelet.daubcoeffmethod) {
|
||||
toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod;
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ struct RetinexParamsEdited {
|
||||
bool slope;
|
||||
bool neigh;
|
||||
bool offs;
|
||||
bool complexmethod;
|
||||
bool retinexMethod;
|
||||
bool mapMethod;
|
||||
bool viewMethod;
|
||||
@ -1039,6 +1040,7 @@ struct WaveletParamsEdited {
|
||||
bool CLmethod;
|
||||
bool Backmethod;
|
||||
bool Tilesmethod;
|
||||
bool complexmethod;
|
||||
bool daubcoeffmethod;
|
||||
bool Dirmethod;
|
||||
bool sigma;
|
||||
|
126
rtgui/retinex.cc
126
rtgui/retinex.cc
@ -9,6 +9,7 @@
|
||||
#include "rtimage.h"
|
||||
#include "options.h"
|
||||
#include "../rtengine/color.h"
|
||||
#include "eventmapper.h"
|
||||
|
||||
using namespace rtengine;
|
||||
using namespace rtengine::procparams;
|
||||
@ -25,13 +26,26 @@ Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL")
|
||||
nextsigma = 0.;
|
||||
nextminT = 0.;
|
||||
nextmaxT = 0.;
|
||||
auto m = ProcEventMapper::getInstance();
|
||||
EvReticomplex = m->newEvent(DEMOSAIC, "HISTORY_MSG_COMPLEXRETI");
|
||||
|
||||
|
||||
const RetinexParams default_params;
|
||||
|
||||
|
||||
// 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());
|
||||
@ -116,7 +130,8 @@ Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL")
|
||||
// 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);
|
||||
|
||||
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());
|
||||
setExpandAlignProperties (tranGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
|
||||
|
||||
const RetinexParams default_params;
|
||||
|
||||
// Transmission map curve
|
||||
transmissionCurveEditorG = new CurveEditorGroup (options.lastRetinexDir, M ("TP_RETINEX_TRANSMISSION"));
|
||||
@ -628,12 +642,14 @@ void Retinex::neutral_pressed ()
|
||||
limd->resetValue (false);
|
||||
highl->resetValue (false);
|
||||
gam->resetValue (false);
|
||||
skal->resetValue (false);
|
||||
slope->resetValue (false);
|
||||
highlights->resetValue (false);
|
||||
h_tonalwidth->resetValue (false);
|
||||
shadows->resetValue (false);
|
||||
s_tonalwidth->resetValue (false);
|
||||
radius->resetValue (false);
|
||||
medianmap->set_active (false);
|
||||
mapMethod->set_active (0);
|
||||
viewMethod->set_active (0);
|
||||
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)
|
||||
{
|
||||
@ -752,6 +814,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
gammaretinexConn.block (true);
|
||||
mapMethodConn.block (true);
|
||||
viewMethodConn.block (true);
|
||||
complexmethodconn.block (true);
|
||||
|
||||
|
||||
if (pedited) {
|
||||
@ -775,6 +838,9 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
shadows->setEditedState (pedited->retinex.shadows ? 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) {
|
||||
retinexMethod->set_active_text (M ("GENERAL_UNCHANGED"));
|
||||
@ -844,6 +910,13 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
medianmapConn.block (false);
|
||||
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") {
|
||||
retinexMethod->set_active (0);
|
||||
} else if (pp->retinex.retinexMethod == "uni") {
|
||||
@ -906,6 +979,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
mapMethodChanged ();
|
||||
viewMethodChanged ();
|
||||
|
||||
|
||||
medianmapConn.block (true);
|
||||
medianmapChanged ();
|
||||
medianmapConn.block (false);
|
||||
@ -914,7 +988,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
cdshapeH->setCurve (pp->retinex.cdHcurve);
|
||||
lhshape->setCurve (pp->retinex.lhcurve);
|
||||
mapshape->setCurve (pp->retinex.mapcurve);
|
||||
|
||||
|
||||
retinexMethodConn.block (false);
|
||||
retinexColorSpaceConn.block (false);
|
||||
gammaretinexConn.block (false);
|
||||
@ -923,8 +997,18 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited)
|
||||
transmissionShape->setCurve (pp->retinex.transmissionCurve);
|
||||
gaintransmissionShape->setCurve (pp->retinex.gaintransmissionCurve);
|
||||
|
||||
complexmethodconn.block (false);
|
||||
|
||||
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 ();
|
||||
|
||||
if (pedited) {
|
||||
pedited->retinex.complexmethod = complexmethod->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.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) {
|
||||
pp->retinex.retinexMethod = "low";
|
||||
} 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()
|
||||
{
|
||||
|
||||
@ -1138,8 +1250,11 @@ void Retinex::viewMethodChanged()
|
||||
limd->show();
|
||||
transmissionCurveEditorG->show();
|
||||
medianmap->show();
|
||||
|
||||
iterFrame->show();
|
||||
if (complexmethod->get_active_row_number() == 0) {
|
||||
iterFrame->hide();
|
||||
} else {
|
||||
iterFrame->show();
|
||||
}
|
||||
/*
|
||||
iter->show();
|
||||
scal->show();
|
||||
@ -1522,6 +1637,7 @@ void Retinex::setBatchMode (bool batchMode)
|
||||
h_tonalwidth->showEditedCB ();
|
||||
shadows->showEditedCB ();
|
||||
s_tonalwidth->showEditedCB ();
|
||||
// complexmethod->append(M("GENERAL_UNCHANGED"));
|
||||
|
||||
skal->showEditedCB ();
|
||||
curveEditorGD->setBatchMode (batchMode);
|
||||
|
@ -28,6 +28,7 @@ class Retinex final :
|
||||
{
|
||||
private:
|
||||
IdleRegister idle_register;
|
||||
rtengine::ProcEvent EvReticomplex;
|
||||
|
||||
protected:
|
||||
CurveEditorGroup* curveEditorGD;
|
||||
@ -72,6 +73,9 @@ protected:
|
||||
MyComboBoxText* mapMethod;
|
||||
MyComboBoxText* viewMethod;
|
||||
Gtk::CheckButton* medianmap;
|
||||
MyComboBoxText* complexmethod;
|
||||
sigc::connection complexmethodconn;
|
||||
|
||||
double nextmin;
|
||||
double nextmax;
|
||||
double nextminiT;
|
||||
@ -87,6 +91,7 @@ protected:
|
||||
Gtk::Frame *gainFrame;
|
||||
Gtk::Frame *tranFrame;
|
||||
Gtk::Frame *iterFrame;
|
||||
Gtk::Frame *maskFrame;
|
||||
Gtk::Frame *equalFrame;
|
||||
|
||||
DiagonalCurveEditor* cdshape;
|
||||
@ -148,4 +153,7 @@ public:
|
||||
|
||||
private:
|
||||
void foldAllButMe(GdkEventButton* event, MyExpander *expander);
|
||||
void convertParamToNormal();
|
||||
void updateGUIToMode(int mode);
|
||||
void complexmethodChanged();
|
||||
};
|
||||
|
160
rtgui/wavelet.cc
160
rtgui/wavelet.cc
@ -158,6 +158,7 @@ Wavelet::Wavelet() :
|
||||
HSmethod(Gtk::manage(new MyComboBoxText())),
|
||||
CLmethod(Gtk::manage(new MyComboBoxText())),
|
||||
Backmethod(Gtk::manage(new MyComboBoxText())),
|
||||
complexmethod(Gtk::manage(new MyComboBoxText())),
|
||||
Tilesmethod(Gtk::manage(new MyComboBoxText())),
|
||||
daubcoeffmethod(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")))),
|
||||
expbl(Gtk::manage(new MyExpander(true, M("TP_WAVELET_BL")))),
|
||||
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);
|
||||
auto m = ProcEventMapper::getInstance();
|
||||
@ -227,6 +231,7 @@ Wavelet::Wavelet() :
|
||||
EvWavrangeab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_RANGEAB");
|
||||
EvWavprotab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_PROTAB");
|
||||
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")));
|
||||
|
||||
@ -269,6 +274,16 @@ Wavelet::Wavelet() :
|
||||
thres->set_tooltip_text(M("TP_WAVELET_LEVELS_TOOLTIP"));
|
||||
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_TILESBIG"));
|
||||
// Tilesmethod->append(M("TP_WAVELET_TILESLIT"));
|
||||
@ -335,6 +350,7 @@ Wavelet::Wavelet() :
|
||||
levdirSubHBox->pack_start(*Lmethod);
|
||||
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(*thres);
|
||||
settingsBox->pack_start(*tilesizeHBox);
|
||||
@ -452,7 +468,7 @@ Wavelet::Wavelet() :
|
||||
ToolParamBlock* const chBox = Gtk::manage(new ToolParamBlock());
|
||||
|
||||
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);
|
||||
|
||||
CHmethod->append(M("TP_WAVELET_CH1"));
|
||||
@ -674,7 +690,7 @@ Wavelet::Wavelet() :
|
||||
EDmethod->append(M("TP_WAVELET_EDCU"));
|
||||
EDmethodconn = EDmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::EDmethodChanged));
|
||||
ctboxED->pack_start(*EDmethod);
|
||||
edgBox->pack_start(*ctboxED);
|
||||
// edgBox->pack_start(*ctboxED);
|
||||
|
||||
edgcont->setAdjusterListener(this);
|
||||
edgcont->setBgGradient(milestones2);
|
||||
@ -838,7 +854,7 @@ Wavelet::Wavelet() :
|
||||
thrH->setAdjusterListener(this);
|
||||
|
||||
radius->setAdjusterListener(this);
|
||||
radius->hide();
|
||||
// radius->hide();
|
||||
|
||||
shFrame->set_label_align(0.025, 0.5);
|
||||
ToolParamBlock* const shBox = Gtk::manage(new ToolParamBlock());
|
||||
@ -1007,7 +1023,7 @@ Wavelet::Wavelet() :
|
||||
resBox->pack_start(*neutrHBox);
|
||||
|
||||
// Final Touchup
|
||||
Gtk::VBox* const ctboxBA = Gtk::manage(new Gtk::VBox());
|
||||
// Gtk::VBox* const ctboxBA = Gtk::manage(new Gtk::VBox());
|
||||
|
||||
ctboxBA->set_spacing(2);
|
||||
|
||||
@ -1236,6 +1252,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
|
||||
CLmethodconn.block(true);
|
||||
Backmethodconn.block(true);
|
||||
Tilesmethodconn.block(true);
|
||||
complexmethodconn.block(true);
|
||||
daubcoeffmethodconn.block(true);
|
||||
Dirmethodconn.block(true);
|
||||
CHmethodconn.block(true);
|
||||
@ -1357,6 +1374,12 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
|
||||
} else if (pp->wavelet.CLmethod == "all") {
|
||||
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);
|
||||
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"));
|
||||
}
|
||||
|
||||
if (!pedited->wavelet.complexmethod) {
|
||||
complexmethod->set_active_text(M("GENERAL_UNCHANGED"));
|
||||
}
|
||||
|
||||
|
||||
if (!pedited->wavelet.Tilesmethod) {
|
||||
Tilesmethod->set_active_text(M("GENERAL_UNCHANGED"));
|
||||
}
|
||||
@ -1774,6 +1802,15 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
|
||||
} else {
|
||||
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);
|
||||
Backmethodconn.block(false);
|
||||
Tilesmethodconn.block(false);
|
||||
complexmethodconn.block(false);
|
||||
daubcoeffmethodconn.block(false);
|
||||
CHmethodconn.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.Backmethod = Backmethod->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.CHmethod = CHmethod->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";
|
||||
}
|
||||
|
||||
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) {
|
||||
pp->wavelet.daubcoeffmethod = "2_";
|
||||
} 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()
|
||||
{
|
||||
//TilesmethodUpdateUI();
|
||||
@ -2916,6 +3065,7 @@ void Wavelet::setBatchMode(bool batchMode)
|
||||
CLmethod->append(M("GENERAL_UNCHANGED"));
|
||||
Backmethod->append(M("GENERAL_UNCHANGED"));
|
||||
Tilesmethod->append(M("GENERAL_UNCHANGED"));
|
||||
complexmethod->append(M("GENERAL_UNCHANGED"));
|
||||
daubcoeffmethod->append(M("GENERAL_UNCHANGED"));
|
||||
CHmethod->append(M("GENERAL_UNCHANGED"));
|
||||
Medgreinf->append(M("GENERAL_UNCHANGED"));
|
||||
|
@ -47,7 +47,6 @@ class Wavelet final :
|
||||
public:
|
||||
Wavelet();
|
||||
~Wavelet() override;
|
||||
|
||||
bool wavComputed_();
|
||||
void adjusterChanged(Adjuster* a, double newval) override;
|
||||
void autoOpenCurve() override;
|
||||
@ -102,6 +101,7 @@ private:
|
||||
rtengine::ProcEvent EvWavrangeab;
|
||||
rtengine::ProcEvent EvWavprotab;
|
||||
rtengine::ProcEvent EvWavlevelshc;
|
||||
rtengine::ProcEvent EvWavcomplexmet;
|
||||
|
||||
LabGrid *labgrid;
|
||||
|
||||
@ -121,6 +121,7 @@ private:
|
||||
void LmethodChanged();
|
||||
void MedgreinfChanged();
|
||||
void TMmethodChanged();
|
||||
void complexmethodChanged();
|
||||
void TilesmethodChanged();
|
||||
void avoidToggled();
|
||||
void showmaskToggled ();
|
||||
@ -143,7 +144,8 @@ private:
|
||||
void ushamethodChanged();
|
||||
void updateGUI();
|
||||
void updateGUImaxlev();
|
||||
|
||||
void convertParamToNormal();
|
||||
void updateGUIToMode(int mode);
|
||||
void HSmethodUpdateUI();
|
||||
void CHmethodUpdateUI();
|
||||
// void CHSLmethodChangedUI();
|
||||
@ -297,6 +299,8 @@ private:
|
||||
sigc::connection CLmethodconn;
|
||||
MyComboBoxText* const Backmethod;
|
||||
sigc::connection Backmethodconn;
|
||||
MyComboBoxText* const complexmethod;
|
||||
sigc::connection complexmethodconn;
|
||||
MyComboBoxText* const Tilesmethod;
|
||||
sigc::connection Tilesmethodconn;
|
||||
MyComboBoxText* const daubcoeffmethod;
|
||||
@ -338,6 +342,8 @@ private:
|
||||
|
||||
Gtk::HBox* const neutrHBox;
|
||||
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 enableNoiseConn, enableResidConn, enableToningConn;
|
||||
|
Loading…
x
Reference in New Issue
Block a user