diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala
index c9b6b4408..257807ca1 100644
--- a/rtdata/languages/Catala
+++ b/rtdata/languages/Catala
@@ -658,7 +658,6 @@ TP_CROP_GUIDETYPE;Tipus de guia:
TP_CROP_H;Alt
TP_CROP_LABEL;Cropa
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Selecc. cropar
TP_CROP_W;Ample
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified)
index d46b9f6f7..c9790898a 100644
--- a/rtdata/languages/Chinese (Simplified)
+++ b/rtdata/languages/Chinese (Simplified)
@@ -761,7 +761,6 @@ TP_CROP_GUIDETYPE;辅助方式:
TP_CROP_H;高
TP_CROP_LABEL;剪裁
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;选择预设
TP_CROP_W;宽
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Chinese (Traditional) b/rtdata/languages/Chinese (Traditional)
index 84f99ba81..91574c9d0 100644
--- a/rtdata/languages/Chinese (Traditional)
+++ b/rtdata/languages/Chinese (Traditional)
@@ -339,7 +339,6 @@ TP_CROP_GTRULETHIRDS;1/3法則
TP_CROP_GUIDETYPE;輔助方式:
TP_CROP_H;高
TP_CROP_LABEL;剪裁
-TP_CROP_SELECTCROP; 選擇預設
TP_CROP_W;寬
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech
index 16c68ec5d..5ccce935a 100644
--- a/rtdata/languages/Czech
+++ b/rtdata/languages/Czech
@@ -1425,7 +1425,6 @@ TP_CROP_GUIDETYPE;Druh vodítek:
TP_CROP_H;Výška
TP_CROP_LABEL;Ořez
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Vyznačit výřez
TP_CROP_W;Šířka
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk
index 1e83b4951..4a2e3c6d4 100644
--- a/rtdata/languages/Dansk
+++ b/rtdata/languages/Dansk
@@ -330,7 +330,6 @@ TP_CROP_GTRULETHIRDS;Reglen om tredjedele
TP_CROP_GUIDETYPE;Hjælpelinjer:
TP_CROP_H;H
TP_CROP_LABEL;Beskær
-TP_CROP_SELECTCROP; Vælg beskæring
TP_CROP_W;B
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK)
index a266349cd..07046d0e5 100644
--- a/rtdata/languages/English (UK)
+++ b/rtdata/languages/English (UK)
@@ -1553,7 +1553,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh
!TP_CROP_H;Height
!TP_CROP_LABEL;Crop
!TP_CROP_PPI;PPI=
-!TP_CROP_SELECTCROP;Select Crop
!TP_CROP_W;Width
!TP_CROP_X;X
!TP_CROP_Y;Y
diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US)
index 49553272b..e1d55b2a1 100644
--- a/rtdata/languages/English (US)
+++ b/rtdata/languages/English (US)
@@ -1515,7 +1515,6 @@
!TP_CROP_H;Height
!TP_CROP_LABEL;Crop
!TP_CROP_PPI;PPI=
-!TP_CROP_SELECTCROP;Select Crop
!TP_CROP_W;Width
!TP_CROP_X;X
!TP_CROP_Y;Y
diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol
index 1a8506d76..da37e03fd 100644
--- a/rtdata/languages/Espanol
+++ b/rtdata/languages/Espanol
@@ -1075,7 +1075,6 @@ TP_CROP_GUIDETYPE;Clase de guía:
TP_CROP_H;Al
TP_CROP_LABEL;Recortar
TP_CROP_PPI;Ptos/Pulgada=
-TP_CROP_SELECTCROP;Seleccionar recorte
TP_CROP_W;Ancho
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara
index 1a3f3f036..f1cc3290a 100644
--- a/rtdata/languages/Euskara
+++ b/rtdata/languages/Euskara
@@ -330,7 +330,6 @@ TP_CROP_GTRULETHIRDS;Herenen erregela
TP_CROP_GUIDETYPE;Gida mota:
TP_CROP_H;H
TP_CROP_LABEL;Moztu
-TP_CROP_SELECTCROP; Mozketa hautatu
TP_CROP_W;W
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index 074efb84d..12c122a2d 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -1509,7 +1509,6 @@ TP_CROP_GUIDETYPE;Type de guide:
TP_CROP_H;H
TP_CROP_LABEL;Recadrage
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP; Sélection du recadrage
TP_CROP_W;L
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek
index eff50dc3a..bf03647ca 100644
--- a/rtdata/languages/Greek
+++ b/rtdata/languages/Greek
@@ -330,7 +330,6 @@ TP_CROP_GTRULETHIRDS;Κανόνας τρίτων
TP_CROP_GUIDETYPE;Είδος βοηθών:
TP_CROP_H;H
TP_CROP_LABEL;Αποκοπή
-TP_CROP_SELECTCROP; Επιλογή αποκοπής
TP_CROP_W;W
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Hebrew b/rtdata/languages/Hebrew
index f1bbde6f9..e0e5d8a6c 100644
--- a/rtdata/languages/Hebrew
+++ b/rtdata/languages/Hebrew
@@ -330,7 +330,6 @@ TP_CROP_GTRULETHIRDS;כלל השליש
TP_CROP_GUIDETYPE;סוג מדריך
TP_CROP_H;גובה
TP_CROP_LABEL;גזור
-TP_CROP_SELECTCROP;בחור גזירה
TP_CROP_W;רוחב
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano
index d07e50f2b..6932a9b8c 100644
--- a/rtdata/languages/Italiano
+++ b/rtdata/languages/Italiano
@@ -944,7 +944,6 @@ TP_CROP_GUIDETYPE;Tipo di guida:
TP_CROP_H;A
TP_CROP_LABEL;Ritaglio
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP; Seleziona Area
TP_CROP_W;L
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese
index cbab4ca3f..11289fbce 100644
--- a/rtdata/languages/Japanese
+++ b/rtdata/languages/Japanese
@@ -1537,7 +1537,6 @@ TP_CROP_GUIDETYPE;ガイドタイプ:
TP_CROP_H;高さ
TP_CROP_LABEL;切り抜き
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP; 選択範囲切り抜き
TP_CROP_W;W 幅
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Latvian b/rtdata/languages/Latvian
index 0cfcb9e04..74c7d4435 100644
--- a/rtdata/languages/Latvian
+++ b/rtdata/languages/Latvian
@@ -330,7 +330,6 @@ TP_CROP_GTRULETHIRDS;Trešdaļas
TP_CROP_GUIDETYPE;Vadlīnijas:
TP_CROP_H;A
TP_CROP_LABEL;Kadrējums
-TP_CROP_SELECTCROP; Norādīt kadrējumu
TP_CROP_W;P
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar
index af10a8272..ac7dd6e81 100644
--- a/rtdata/languages/Magyar
+++ b/rtdata/languages/Magyar
@@ -626,7 +626,6 @@ TP_CROP_GUIDETYPE;Segédvonal típusa:
TP_CROP_H;M
TP_CROP_LABEL;Kivágás
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP; Kijelölés egérrel
TP_CROP_W;Sz
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands
index feb3cef52..be33cc433 100644
--- a/rtdata/languages/Nederlands
+++ b/rtdata/languages/Nederlands
@@ -1319,7 +1319,6 @@ TP_CROP_GUIDETYPE;Hulplijnen:
TP_CROP_H;Hoogte
TP_CROP_LABEL;Bijsnijden
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Selecteer gebied
TP_CROP_W;Breedte
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM
index 06a675819..d7e817dbc 100644
--- a/rtdata/languages/Norsk BM
+++ b/rtdata/languages/Norsk BM
@@ -330,7 +330,6 @@ TP_CROP_GTRULETHIRDS;Tredjedelsreglen
TP_CROP_GUIDETYPE;Guidetype:
TP_CROP_H;H
TP_CROP_LABEL;Beskjæring
-TP_CROP_SELECTCROP;Velg beskjæringsområde
TP_CROP_W;B
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish
index 763905496..71295015e 100644
--- a/rtdata/languages/Polish
+++ b/rtdata/languages/Polish
@@ -1030,7 +1030,6 @@ TP_CROP_GUIDETYPE;Typ pomocy:
TP_CROP_H;Wysokość
TP_CROP_LABEL;Kadrowanie
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Wybierz kadr
TP_CROP_W;Szerokość
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters)
index e1d110970..6abf773b6 100644
--- a/rtdata/languages/Polish (Latin Characters)
+++ b/rtdata/languages/Polish (Latin Characters)
@@ -1030,7 +1030,6 @@ TP_CROP_GUIDETYPE;Typ pomocy:
TP_CROP_H;Wysokosc
TP_CROP_LABEL;Kadrowanie
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Wybierz kadr
TP_CROP_W;Szerokosc
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil)
index 95923c6f0..e49129afd 100644
--- a/rtdata/languages/Portugues (Brasil)
+++ b/rtdata/languages/Portugues (Brasil)
@@ -1461,7 +1461,6 @@ TP_CROP_GUIDETYPE;Tipo de guia:
TP_CROP_H;Altura
TP_CROP_LABEL;Cortar
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Selecione para Cortar
TP_CROP_W;Largura
TP_CROP_X;X
TP_CROP_Y;Y
diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian
index 36f7f64a6..acf163298 100644
--- a/rtdata/languages/Russian
+++ b/rtdata/languages/Russian
@@ -1004,7 +1004,6 @@ TP_CROP_GUIDETYPE;Тип направляющей:
TP_CROP_H;Высота
TP_CROP_LABEL;Кадрирование
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Включить режим обрезки
TP_CROP_W;Ширина
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters)
index 1d5c6b3f9..6da76619f 100644
--- a/rtdata/languages/Serbian (Cyrilic Characters)
+++ b/rtdata/languages/Serbian (Cyrilic Characters)
@@ -909,7 +909,6 @@ TP_CROP_GUIDETYPE;Вођицe:
TP_CROP_H;В
TP_CROP_LABEL;Исецање
TP_CROP_PPI;ППИ=
-TP_CROP_SELECTCROP; Изабери област
TP_CROP_W;Ш
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Serbian (Latin Characters) b/rtdata/languages/Serbian (Latin Characters)
index 97399f629..ea663dab4 100644
--- a/rtdata/languages/Serbian (Latin Characters)
+++ b/rtdata/languages/Serbian (Latin Characters)
@@ -909,7 +909,6 @@ TP_CROP_GUIDETYPE;Vođice:
TP_CROP_H;V
TP_CROP_LABEL;Isecanje
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP; Izaberi oblast
TP_CROP_W;Š
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak
index ac6dc7928..98e330bbb 100644
--- a/rtdata/languages/Slovak
+++ b/rtdata/languages/Slovak
@@ -384,7 +384,6 @@ TP_CROP_GTRULETHIRDS;Pravidlo tretín
TP_CROP_GUIDETYPE;Type vodidiel:
TP_CROP_H;V
TP_CROP_LABEL;Orezanie
-TP_CROP_SELECTCROP; Vyberte Orez
TP_CROP_W;Š
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi
index 3d450a65c..6728207d2 100644
--- a/rtdata/languages/Suomi
+++ b/rtdata/languages/Suomi
@@ -331,7 +331,6 @@ TP_CROP_GTRULETHIRDS;Kolmijako
TP_CROP_GUIDETYPE;Sommittelumalli:
TP_CROP_H;Kork.
TP_CROP_LABEL;Rajaus
-TP_CROP_SELECTCROP;Valitse alue
TP_CROP_W;Lev.
TP_CROP_X; x
TP_CROP_Y; y
diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish
index 5d93a9279..af522505a 100644
--- a/rtdata/languages/Swedish
+++ b/rtdata/languages/Swedish
@@ -1206,7 +1206,6 @@ TP_CROP_GUIDETYPE;Guidetyp:
TP_CROP_H;Höjd
TP_CROP_LABEL;Beskär
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Välj beskärningsområde
TP_CROP_W;Bredd
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish
index 37338ba52..30b4e2b98 100644
--- a/rtdata/languages/Turkish
+++ b/rtdata/languages/Turkish
@@ -331,7 +331,6 @@ TP_CROP_GTRULETHIRDS;Üçler kuralı
TP_CROP_GUIDETYPE;Kılavuz türü:
TP_CROP_H;Y
TP_CROP_LABEL;Kırp
-TP_CROP_SELECTCROP; Kırpma alanı seç
TP_CROP_W;G
TP_CROP_X;x
TP_CROP_Y;y
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 869e96178..3ab9ced80 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -733,13 +733,18 @@ HISTORY_MSG_493;L*a*b* Adjustments
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction
HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction
-HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - C mask
+HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Channel
+HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - region C mask
HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H mask
HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Lightness
HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - L mask
+HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask
HISTORY_MSG_COLORTONING_LABREGION_LIST;CT - List
HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturation
-HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - Show mask
+HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope
+HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset
+HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power
+HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - region mask blur
HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth
HISTORY_MSG_DEHAZE_ENABLED;Haze Removal
HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map
@@ -931,7 +936,7 @@ MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the focus mask.\nShortcut: Shift
MAIN_TOOLTIP_PREVIEWG;Preview the green channel.\nShortcut: g
MAIN_TOOLTIP_PREVIEWL;Preview the luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B
MAIN_TOOLTIP_PREVIEWR;Preview the red channel.\nShortcut: r
-MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: None\n\nOnly works when sharpening is enabled and zoom >= 100%.
+MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%.
MAIN_TOOLTIP_QINFO;Quick info on the image.\nShortcut: i
MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l
MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l
@@ -1467,8 +1472,14 @@ TP_COLORTONING_LAB;L*a*b* blending
TP_COLORTONING_LABEL;Color Toning
TP_COLORTONING_LABGRID;L*a*b* color correction grid
TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4
-TP_COLORTONING_LABREGIONS;L*a*b* correction regions
+TP_COLORTONING_LABREGIONS;Color correction regions
TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2
+TP_COLORTONING_LABREGION_MASKBLUR;Mask Blur
+TP_COLORTONING_LABREGION_CHANNEL;Channel
+TP_COLORTONING_LABREGION_CHANNEL_ALL;All
+TP_COLORTONING_LABREGION_CHANNEL_B;Blue
+TP_COLORTONING_LABREGION_CHANNEL_G;Green
+TP_COLORTONING_LABREGION_CHANNEL_R;Red
TP_COLORTONING_LABREGION_CHROMATICITYMASK;C
TP_COLORTONING_LABREGION_HUEMASK;H
TP_COLORTONING_LABREGION_LIGHTNESS;Lightness
@@ -1477,6 +1488,9 @@ TP_COLORTONING_LABREGION_LIST_TITLE;Correction
TP_COLORTONING_LABREGION_MASK;Mask
TP_COLORTONING_LABREGION_SATURATION;Saturation
TP_COLORTONING_LABREGION_SHOWMASK;Show mask
+TP_COLORTONING_LABREGION_SLOPE;Slope
+TP_COLORTONING_LABREGION_OFFSET;Offset
+TP_COLORTONING_LABREGION_POWER;Power
TP_COLORTONING_LUMA;Luminance
TP_COLORTONING_LUMAMODE;Preserve luminance
TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved.
@@ -1516,10 +1530,11 @@ TP_CROP_GUIDETYPE;Guide type:
TP_CROP_H;Height
TP_CROP_LABEL;Crop
TP_CROP_PPI;PPI=
-TP_CROP_SELECTCROP;Select Crop
+TP_CROP_SELECTCROP;Select
+TP_CROP_RESETCROP;Reset
TP_CROP_W;Width
-TP_CROP_X;X
-TP_CROP_Y;Y
+TP_CROP_X;Left
+TP_CROP_Y;Top
TP_DARKFRAME_AUTOSELECT;Auto-selection
TP_DARKFRAME_LABEL;Dark-Frame
TP_DEFRINGE_LABEL;Defringe
diff --git a/rtengine/iplabregions.cc b/rtengine/iplabregions.cc
index d2380494a..28e7ddad3 100644
--- a/rtengine/iplabregions.cc
+++ b/rtengine/iplabregions.cc
@@ -143,8 +143,12 @@ BENCHFUN
}
for (int i = begin_idx; i < end_idx; ++i) {
- rtengine::guidedFilter(guide, abmask[i], abmask[i], max(int(4 / scale + 0.5), 1), 0.001, multiThread);
- rtengine::guidedFilter(guide, Lmask[i], Lmask[i], max(int(25 / scale + 0.5), 1), 0.0001, multiThread);
+ float blur = params->colorToning.labregions[i].maskBlur;
+ blur = blur < 0.f ? -1.f/blur : 1.f + blur;
+ int r1 = max(int(4 / scale * blur + 0.5), 1);
+ int r2 = max(int(25 / scale * blur + 0.5), 1);
+ rtengine::guidedFilter(guide, abmask[i], abmask[i], r1, 0.001, multiThread);
+ rtengine::guidedFilter(guide, Lmask[i], Lmask[i], r2, 0.0001, multiThread);
}
if (show_mask_idx >= 0) {
@@ -166,21 +170,115 @@ BENCHFUN
const auto abcoord =
[](float x) -> float
{
- return 12000.f * SGN(x) * xlog2lin(std::abs(x), 4.f);
+ return /*12000.f **/ SGN(x) * xlog2lin(std::abs(x), 4.f);
};
float abca[n];
float abcb[n];
float rs[n];
- float rl[n];
+ float slope[n];
+ float offset[n];
+ float power[n];
+ int channel[n];
for (int i = 0; i < n; ++i) {
auto &r = params->colorToning.labregions[i];
abca[i] = abcoord(r.a);
abcb[i] = abcoord(r.b);
- rs[i] = 1.f + r.saturation / 100.f;
- rl[i] = 1.f + r.lightness / 500.f;
+ rs[i] = 1.f + r.saturation / (SGN(r.saturation) > 0 ? 50.f : 100.f);
+ slope[i] = r.slope;
+ offset[i] = r.offset;
+ power[i] = r.power;
+ channel[i] = r.channel;
}
+ TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile);
+ TMatrix iws = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile);
+
+ const auto CDL =
+ [=](float &l, float &a, float &b, float slope, float offset, float power, float saturation) -> void
+ {
+ if (slope != 1.f || offset != 0.f || power != 1.f || saturation != 1.f) {
+ float rgb[3];
+ float x, y, z;
+ Color::Lab2XYZ(l, a, b, x, y, z);
+ Color::xyz2rgb(x, y, z, rgb[0], rgb[1], rgb[2], iws);
+ for (int i = 0; i < 3; ++i) {
+ rgb[i] = (pow_F(max((rgb[i] / 65535.f) * slope + offset, 0.f), power)) * 65535.f;
+ }
+ if (saturation != 1.f) {
+ float Y = Color::rgbLuminance(rgb[0], rgb[1], rgb[2], ws);
+ for (int i = 0; i < 3; ++i) {
+ rgb[i] = max(Y + saturation * (rgb[i] - Y), 0.f);
+ }
+ }
+ Color::rgbxyz(rgb[0], rgb[1], rgb[2], x, y, z, ws);
+ Color::XYZ2Lab(x, y, z, l, a, b);
+ }
+ };
+
+ const auto chan =
+ [=](float prev_l, float prev_a, float prev_b, float &l, float &a, float &b, int channel) -> void
+ {
+ if (channel >= 0) {
+ float prev_rgb[3];
+ float rgb[3];
+ float x, y, z;
+ Color::Lab2XYZ(l, a, b, x, y, z);
+ Color::xyz2rgb(x, y, z, rgb[0], rgb[1], rgb[2], iws);
+ Color::Lab2XYZ(prev_l, prev_a, prev_b, x, y, z);
+ Color::xyz2rgb(x, y, z, prev_rgb[0], prev_rgb[1], prev_rgb[2], iws);
+ prev_rgb[channel] = rgb[channel];
+ Color::rgbxyz(prev_rgb[0], prev_rgb[1], prev_rgb[2], x, y, z, ws);
+ Color::XYZ2Lab(x, y, z, l, a, b);
+ }
+ };
+
+#ifdef __SSE2__
+ const auto CDL_v =
+ [=](vfloat &l, vfloat &a, vfloat &b, float slope, float offset, float power, float saturation) -> void
+ {
+ if (slope != 1.f || offset != 0.f || power != 1.f || saturation != 1.f) {
+ float ll[4];
+ float aa[4];
+ float bb[4];
+ STVFU(ll[0], l);
+ STVFU(aa[0], a);
+ STVFU(bb[0], b);
+ for (int i = 0; i < 4; ++i) {
+ CDL(ll[i], aa[i], bb[i], slope, offset, power, saturation);
+ }
+ l = LVFU(ll[0]);
+ a = LVFU(aa[0]);
+ b = LVFU(bb[0]);
+ }
+ };
+
+ const auto chan_v =
+ [=](vfloat prev_l, vfloat prev_a, vfloat prev_b, vfloat &l, vfloat &a, vfloat &b, int channel) -> void
+ {
+ if (channel >= 0) {
+ float ll[4];
+ float aa[4];
+ float bb[4];
+ STVFU(ll[0], l);
+ STVFU(aa[0], a);
+ STVFU(bb[0], b);
+ float prev_ll[4];
+ float prev_aa[4];
+ float prev_bb[4];
+ STVFU(prev_ll[0], prev_l);
+ STVFU(prev_aa[0], prev_a);
+ STVFU(prev_bb[0], prev_b);
+ for (int i = 0; i < 4; ++i) {
+ chan(prev_ll[i], prev_aa[i], prev_bb[i], ll[i], aa[i], bb[i], channel);
+ }
+ l = LVFU(ll[0]);
+ a = LVFU(aa[0]);
+ b = LVFU(bb[0]);
+ }
+ };
+#endif
+
#ifdef _OPENMP
#pragma omp parallel if (multiThread)
#endif
@@ -188,7 +286,6 @@ BENCHFUN
#ifdef __SSE2__
vfloat c42000v = F2V(42000.f);
vfloat cm42000v = F2V(-42000.f);
- vfloat c32768v = F2V(32768.f);
#endif
#ifdef _OPENMP
#pragma omp for
@@ -203,10 +300,12 @@ BENCHFUN
for (int i = 0; i < n; ++i) {
vfloat blendv = LVFU(abmask[i][y][x]);
- vfloat sv = F2V(rs[i]);
- vfloat a_newv = vclampf(sv * (av + F2V(abca[i])), cm42000v, c42000v);
- vfloat b_newv = vclampf(sv * (bv + F2V(abcb[i])), cm42000v, c42000v);
- vfloat l_newv = vclampf(lv * F2V(rl[i]), ZEROV, c32768v);
+ vfloat l_newv = lv;
+ vfloat a_newv = vclampf(av + lv * F2V(abca[i]), cm42000v, c42000v);
+ vfloat b_newv = vclampf(bv + lv * F2V(abcb[i]), cm42000v, c42000v);
+ CDL_v(l_newv, a_newv, b_newv, slope[i], offset[i], power[i], rs[i]);
+ l_newv = vmaxf(l_newv, ZEROV);
+ chan_v(lv, av, bv, l_newv, a_newv, b_newv, channel[i]);
lv = vintpf(LVFU(Lmask[i][y][x]), l_newv, lv);
av = vintpf(blendv, a_newv, av);
bv = vintpf(blendv, b_newv, bv);
@@ -223,10 +322,12 @@ BENCHFUN
for (int i = 0; i < n; ++i) {
float blend = abmask[i][y][x];
- float s = rs[i];
- float a_new = LIM(s * (a + abca[i]), -42000.f, 42000.f);
- float b_new = LIM(s * (b + abcb[i]), -42000.f, 42000.f);
- float l_new = LIM(l * rl[i], 0.f, 32768.f);
+ float l_new = l;
+ float a_new = LIM(a + l * abca[i], -42000.f, 42000.f);
+ float b_new = LIM(b + l * abcb[i], -42000.f, 42000.f);
+ CDL(l_new, a_new, b_new, slope[i], offset[i], power[i], rs[i]);
+ l_new = max(l_new, 0.f);
+ chan(l, a, b, l_new, a_new, b_new, channel[i]);
l = intp(Lmask[i][y][x], l_new, l);
a = intp(blend, a_new, a);
b = intp(blend, b_new, b);
diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc
index e22e4553c..860823b3a 100644
--- a/rtengine/ipwavelet.cc
+++ b/rtengine/ipwavelet.cc
@@ -2773,8 +2773,8 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit
}
} else if(cp.EDmet == 1) { //threshold adjuster
float MaxPCompare = MaxP[level] * SQR(cp.edg_max / 100.f); //100 instead of b_r...case if b_r < 100
- float MaxNCompare = MaxN[level] * SQR(cp.edg_max / 100.f); //always rduce a little edge for near max values
- float edgeSdCompare = (mean[level] + 1.5f * sigma[level]) * SQR(cp.edg_sd / t_r); // 1.5 standard deviation #80% range between mean 50% and 80%
+ float MaxNCompare = MaxN[level] * SQR(cp.edg_max / 100.f); //always reduce a little edge for near max values
+ float edgeSdCompare = (mean[level] + 1.5f * sigma[level]) * SQR(cp.edg_sd / t_r); // 1.5 standard deviation #80% range between mean 50% and 80%
float edgeMeanCompare = mean[level] * SQR(cp.edg_mean / t_l);
float edgeLowCompare = (5.f + SQR(cp.edg_low));
float edgeMeanFactor = cbrt(cp.edg_mean / t_l);
@@ -2818,7 +2818,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit
edge = edgePrecalc;
}
- //algorithm that take into account local contrast
+ //algorithm that takes into account local contrast
// I use a thresholdadjuster with
// Bottom left ==> minimal low value for local contrast (not 0, but 5...we can change)
// 0 10*10 35*35 100*100 substantially correspond to the true distribution of low value, mean, standard-deviation and max (ed 5, 50, 400, 4000
@@ -2866,7 +2866,7 @@ void ImProcFunctions::ContAllL (float *koeLi[12], float *maxkoeLi, bool lipschit
if(edge < 1.f) {
edge = 1.f;
}
- }//mofify effect if sd change
+ }//modify effect if sd change
if (fabs(WavCoeffs_L[dir][k]) < edgeMeanCompare) {
edge *= edgeMeanFactor;
diff --git a/rtengine/klt/trackFeatures.cc b/rtengine/klt/trackFeatures.cc
index 474d0f5f5..a99225543 100644
--- a/rtengine/klt/trackFeatures.cc
+++ b/rtengine/klt/trackFeatures.cc
@@ -23,14 +23,14 @@ typedef float *_FloatWindow;
/*********************************************************************
* _interpolate
- *
- * Given a point (x,y) in an image, computes the bilinear interpolated
- * gray-level value of the point in the image.
+ *
+ * Given a point (x,y) in an image, computes the bilinear interpolated
+ * gray-level value of the point in the image.
*/
static float _interpolate(
- float x,
- float y,
+ float x,
+ float y,
_KLT_FloatImage img)
{
int xt = (int) x; /* coordinates of top-left corner */
@@ -61,7 +61,7 @@ static float _interpolate(
* _computeIntensityDifference
*
* Given two images and the window center in both images,
- * aligns the images wrt the window and computes the difference
+ * aligns the images wrt the window and computes the difference
* between the two overlaid images.
*/
@@ -91,7 +91,7 @@ static void _computeIntensityDifference(
* _computeGradientSum
*
* Given two gradients and the window center in both images,
- * aligns the gradients wrt the window and computes the sum of the two
+ * aligns the gradients wrt the window and computes the sum of the two
* overlaid gradients.
*/
@@ -126,7 +126,7 @@ static void _computeGradientSum(
* _computeIntensityDifferenceLightingInsensitive
*
* Given two images and the window center in both images,
- * aligns the images wrt the window and computes the difference
+ * aligns the images wrt the window and computes the difference
* between the two overlaid images; normalizes for overall gain and bias.
*/
@@ -141,7 +141,7 @@ static void _computeIntensityDifferenceLightingInsensitive(
int hw = width/2, hh = height/2;
float g1, g2, sum1_squared = 0, sum2_squared = 0;
int i, j;
-
+
float sum1 = 0, sum2 = 0;
float mean1, mean2,alpha,belta;
/* Compute values */
@@ -165,7 +165,7 @@ static void _computeIntensityDifferenceLightingInsensitive(
g1 = _interpolate(x1+i, y1+j, img1);
g2 = _interpolate(x2+i, y2+j, img2);
*imgdiff++ = g1- g2*alpha-belta;
- }
+ }
}
@@ -173,7 +173,7 @@ static void _computeIntensityDifferenceLightingInsensitive(
* _computeGradientSumLightingInsensitive
*
* Given two gradients and the window center in both images,
- * aligns the gradients wrt the window and computes the sum of the two
+ * aligns the gradients wrt the window and computes the sum of the two
* overlaid gradients; normalizes for overall gain and bias.
*/
@@ -184,7 +184,7 @@ static void _computeGradientSumLightingInsensitive(
_KLT_FloatImage grady2,
_KLT_FloatImage img1, /* images */
_KLT_FloatImage img2,
-
+
float x1, float y1, /* center of window in 1st img */
float x2, float y2, /* center of window in 2nd img */
int width, int height, /* size of window */
@@ -194,7 +194,7 @@ static void _computeGradientSumLightingInsensitive(
int hw = width/2, hh = height/2;
float g1, g2, sum1_squared = 0, sum2_squared = 0;
int i, j;
-
+
float mean1, mean2, alpha;
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
@@ -205,7 +205,7 @@ static void _computeGradientSumLightingInsensitive(
mean1 = sum1_squared/(width*height);
mean2 = sum2_squared/(width*height);
alpha = (float) sqrt(mean1/mean2);
-
+
/* Compute values */
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
@@ -215,7 +215,7 @@ static void _computeGradientSumLightingInsensitive(
g1 = _interpolate(x1+i, y1+j, grady1);
g2 = _interpolate(x2+i, y2+j, grady2);
*grady++ = g1+ g2*alpha;
- }
+ }
}
/*********************************************************************
@@ -229,8 +229,8 @@ static void _compute2by2GradientMatrix(
int width, /* size of window */
int height,
float *gxx, /* return values */
- float *gxy,
- float *gyy)
+ float *gxy,
+ float *gyy)
{
float gx, gy;
@@ -246,8 +246,8 @@ static void _compute2by2GradientMatrix(
*gyy += gy*gy;
}
}
-
-
+
+
/*********************************************************************
* _compute2by1ErrorVector
*
@@ -267,7 +267,7 @@ static void _compute2by1ErrorVector(
int i;
/* Compute values */
- *ex = 0; *ey = 0;
+ *ex = 0; *ey = 0;
for (i = 0 ; i < width * height ; i++) {
diff = *imgdiff++;
*ex += diff * (*gradx++);
@@ -297,7 +297,7 @@ static int _solveEquation(
{
float det = gxx*gyy - gxy*gxy;
-
+
if (det < small) return KLT_SMALL_DET;
*dx = (gyy*ex - gxy*ey)/det;
@@ -309,7 +309,7 @@ static int _solveEquation(
/*********************************************************************
* _allocateFloatWindow
*/
-
+
static _FloatWindow _allocateFloatWindow(
int width,
int height)
@@ -347,7 +347,7 @@ static void _printFloatWindow(
}
}
*/
-
+
/*********************************************************************
* _sumAbsFloatWindow
@@ -385,10 +385,10 @@ static int _trackFeature(
float y1,
float *x2, /* starting location of search in second image */
float *y2,
- _KLT_FloatImage img1,
+ _KLT_FloatImage img1,
_KLT_FloatImage gradx1,
_KLT_FloatImage grady1,
- _KLT_FloatImage img2,
+ _KLT_FloatImage img2,
_KLT_FloatImage gradx2,
_KLT_FloatImage grady2,
int width, /* size of window */
@@ -410,7 +410,7 @@ static int _trackFeature(
int nr = img1->nrows;
float one_plus_eps = 1.001f; /* To prevent rounding errors */
-
+
/* Allocate memory for windows */
imgdiff = _allocateFloatWindow(width, height);
gradx = _allocateFloatWindow(width, height);
@@ -430,24 +430,24 @@ static int _trackFeature(
/* Compute gradient and difference windows */
if (lighting_insensitive) {
- _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2,
+ _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
- _computeGradientSumLightingInsensitive(gradx1, grady1, gradx2, grady2,
+ _computeGradientSumLightingInsensitive(gradx1, grady1, gradx2, grady2,
img1, img2, x1, y1, *x2, *y2, width, height, gradx, grady);
} else {
- _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
+ _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
- _computeGradientSum(gradx1, grady1, gradx2, grady2,
+ _computeGradientSum(gradx1, grady1, gradx2, grady2,
x1, y1, *x2, *y2, width, height, gradx, grady);
}
-
+
/* Use these windows to construct matrices */
- _compute2by2GradientMatrix(gradx, grady, width, height,
+ _compute2by2GradientMatrix(gradx, grady, width, height,
&gxx, &gxy, &gyy);
_compute2by1ErrorVector(imgdiff, gradx, grady, width, height, step_factor,
&ex, &ey);
-
+
/* Using matrices, solve equation for new displacement */
status = _solveEquation(gxx, gxy, gyy, ex, ey, small, &dx, &dy);
if (status == KLT_SMALL_DET) break;
@@ -459,19 +459,19 @@ static int _trackFeature(
} while ((fabs(dx)>=th || fabs(dy)>=th) && iteration < max_iterations);
/* Check whether window is out of bounds */
- if (*x2-hw < 0.0f || nc-(*x2+hw) < one_plus_eps ||
+ if (*x2-hw < 0.0f || nc-(*x2+hw) < one_plus_eps ||
*y2-hh < 0.0f || nr-(*y2+hh) < one_plus_eps)
status = KLT_OOB;
/* Check whether residue is too large */
if (status == KLT_TRACKED) {
if (lighting_insensitive)
- _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2,
+ _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
else
- _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
+ _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
- if (_sumAbsFloatWindow(imgdiff, width, height)/(width*height) > max_residue)
+ if (_sumAbsFloatWindow(imgdiff, width, height)/(width*height) > max_residue)
status = KLT_LARGE_RESIDUE;
}
@@ -505,25 +505,25 @@ static KLT_BOOL _outOfBounds(
-/**********************************************************************
+/**********************************************************************
* CONSISTENCY CHECK OF FEATURES BY AFFINE MAPPING (BEGIN)
-*
-* Created by: Thorsten Thormaehlen (University of Hannover) June 2004
+*
+* Created by: Thorsten Thormaehlen (University of Hannover) June 2004
* thormae@tnt.uni-hannover.de
-*
+*
* Permission is granted to any individual or institution to use, copy, modify,
-* and distribute this part of the software, provided that this complete authorship
-* and permission notice is maintained, intact, in all copies.
+* and distribute this part of the software, provided that this complete authorship
+* and permission notice is maintained, intact, in all copies.
*
* This software is provided "as is" without express or implied warranty.
*
*
* The following static functions are helpers for the affine mapping.
-* They all start with "_am".
+* They all start with "_am".
* There are also small changes in other files for the
* affine mapping these are all marked by "for affine mapping"
-*
-* Thanks to Kevin Koeser (koeser@mip.informatik.uni-kiel.de) for fixing a bug
+*
+* Thanks to Kevin Koeser (koeser@mip.informatik.uni-kiel.de) for fixing a bug
*/
#define SWAP_ME(X,Y) {temp=(X);(X)=(Y);(Y)=temp;}
@@ -613,7 +613,7 @@ static int _am_gauss_jordan_elimination(float **a, int n, float **b, int m)
/*********************************************************************
* _am_getGradientWinAffine
*
- * aligns the gradients with the affine transformed window
+ * aligns the gradients with the affine transformed window
*/
static void _am_getGradientWinAffine(
@@ -628,7 +628,7 @@ static void _am_getGradientWinAffine(
int hw = width/2, hh = height/2;
int i, j;
float mi, mj;
-
+
/* Compute values */
for (j = -hh ; j <= hh ; j++)
for (i = -hw ; i <= hw ; i++) {
@@ -637,19 +637,19 @@ static void _am_getGradientWinAffine(
*out_gradx++ = _interpolate(x+mi, y+mj, in_gradx);
*out_grady++ = _interpolate(x+mi, y+mj, in_grady);
}
-
+
}
///*********************************************************************
// * _computeAffineMappedImage
// * used only for DEBUG output
-// *
+// *
//*/
//
//static void _am_computeAffineMappedImage(
// _KLT_FloatImage img, /* images */
// float x, float y, /* center of window */
-// float Axx, float Ayx , float Axy, float Ayy, /* affine mapping */
+// float Axx, float Ayx , float Axy, float Ayy, /* affine mapping */
// int width, int height, /* size of window */
// _FloatWindow imgdiff) /* output */
//{
@@ -679,14 +679,14 @@ static void _am_getSubFloatImage(
int hw = window->ncols/2, hh = window->nrows/2;
int x0 = (int) x;
int y0 = (int) y;
- float * windata = window->data;
+ float * windata = window->data;
int offset;
int i, j;
assert(x0 - hw >= 0);
assert(y0 - hh >= 0);
assert(x0 + hw <= img->ncols);
- assert(y0 + hh <= img->nrows);
+ assert(y0 + hh <= img->nrows);
/* copy values */
for (j = -hh ; j <= hh ; j++)
@@ -700,10 +700,10 @@ static void _am_getSubFloatImage(
* _am_computeIntensityDifferenceAffine
*
* Given two images and the window center in both images,
- * aligns the images with the window and computes the difference
+ * aligns the images with the window and computes the difference
* between the two overlaid images using the affine mapping.
* A = [ Axx Axy]
- * [ Ayx Ayy]
+ * [ Ayx Ayy]
*/
static void _am_computeIntensityDifferenceAffine(
@@ -711,7 +711,7 @@ static void _am_computeIntensityDifferenceAffine(
_KLT_FloatImage img2,
float x1, float y1, /* center of window in 1st img */
float x2, float y2, /* center of window in 2nd img */
- float Axx, float Ayx , float Axy, float Ayy, /* affine mapping */
+ float Axx, float Ayx , float Axy, float Ayy, /* affine mapping */
int width, int height, /* size of window */
_FloatWindow imgdiff) /* output */
{
@@ -746,15 +746,15 @@ static void _am_compute6by6GradientMatrix(
int hw = width/2, hh = height/2;
int i, j;
float gx, gy, gxx, gxy, gyy, x, y, xx, xy, yy;
-
-
- /* Set values to zero */
+
+
+ /* Set values to zero */
for (j = 0 ; j < 6 ; j++) {
for (i = j ; i < 6 ; i++) {
T[j][i] = 0.0;
}
}
-
+
for (j = -hh ; j <= hh ; j++) {
for (i = -hw ; i <= hw ; i++) {
gx = *gradx++;
@@ -762,41 +762,41 @@ static void _am_compute6by6GradientMatrix(
gxx = gx * gx;
gxy = gx * gy;
gyy = gy * gy;
- x = (float) i;
- y = (float) j;
+ x = (float) i;
+ y = (float) j;
xx = x * x;
xy = x * y;
yy = y * y;
-
- T[0][0] += xx * gxx;
+
+ T[0][0] += xx * gxx;
T[0][1] += xx * gxy;
T[0][2] += xy * gxx;
T[0][3] += xy * gxy;
T[0][4] += x * gxx;
T[0][5] += x * gxy;
-
+
T[1][1] += xx * gyy;
T[1][2] += xy * gxy;
T[1][3] += xy * gyy;
T[1][4] += x * gxy;
T[1][5] += x * gyy;
-
+
T[2][2] += yy * gxx;
T[2][3] += yy * gxy;
T[2][4] += y * gxx;
T[2][5] += y * gxy;
-
+
T[3][3] += yy * gyy;
T[3][4] += y * gxy;
- T[3][5] += y * gyy;
+ T[3][5] += y * gyy;
- T[4][4] += gxx;
+ T[4][4] += gxx;
T[4][5] += gxy;
-
- T[5][5] += gyy;
+
+ T[5][5] += gyy;
}
}
-
+
for (j = 0 ; j < 5 ; j++) {
for (i = j+1 ; i < 6 ; i++) {
T[i][j] = T[j][i];
@@ -824,9 +824,9 @@ static void _am_compute6by1ErrorVector(
int i, j;
float diff, diffgradx, diffgrady;
- /* Set values to zero */
- for(i = 0; i < 6; i++) e[i][0] = 0.0;
-
+ /* Set values to zero */
+ for(i = 0; i < 6; i++) e[i][0] = 0.0;
+
/* Compute values */
for (j = -hh ; j <= hh ; j++) {
for (i = -hw ; i <= hw ; i++) {
@@ -835,15 +835,15 @@ static void _am_compute6by1ErrorVector(
diffgrady = diff * (*grady++);
e[0][0] += diffgradx * i;
e[1][0] += diffgrady * i;
- e[2][0] += diffgradx * j;
- e[3][0] += diffgrady * j;
+ e[2][0] += diffgradx * j;
+ e[3][0] += diffgrady * j;
e[4][0] += diffgradx;
- e[5][0] += diffgrady;
+ e[5][0] += diffgrady;
}
}
-
+
for(i = 0; i < 6; i++) e[i][0] *= 0.5;
-
+
}
@@ -862,37 +862,37 @@ static void _am_compute4by4GradientMatrix(
int hw = width/2, hh = height/2;
int i, j;
float gx, gy, x, y;
-
-
- /* Set values to zero */
+
+
+ /* Set values to zero */
for (j = 0 ; j < 4 ; j++) {
for (i = 0 ; i < 4 ; i++) {
T[j][i] = 0.0;
}
}
-
+
for (j = -hh ; j <= hh ; j++) {
for (i = -hw ; i <= hw ; i++) {
gx = *gradx++;
gy = *grady++;
- x = (float) i;
- y = (float) j;
+ x = (float) i;
+ y = (float) j;
T[0][0] += (x*gx+y*gy) * (x*gx+y*gy);
T[0][1] += (x*gx+y*gy)*(x*gy-y*gx);
T[0][2] += (x*gx+y*gy)*gx;
T[0][3] += (x*gx+y*gy)*gy;
-
+
T[1][1] += (x*gy-y*gx) * (x*gy-y*gx);
T[1][2] += (x*gy-y*gx)*gx;
T[1][3] += (x*gy-y*gx)*gy;
-
+
T[2][2] += gx*gx;
T[2][3] += gx*gy;
-
+
T[3][3] += gy*gy;
}
}
-
+
for (j = 0 ; j < 3 ; j++) {
for (i = j+1 ; i < 4 ; i++) {
T[i][j] = T[j][i];
@@ -918,9 +918,9 @@ static void _am_compute4by1ErrorVector(
int i, j;
float diff, diffgradx, diffgrady;
- /* Set values to zero */
- for(i = 0; i < 4; i++) e[i][0] = 0.0;
-
+ /* Set values to zero */
+ for(i = 0; i < 4; i++) e[i][0] = 0.0;
+
/* Compute values */
for (j = -hh ; j <= hh ; j++) {
for (i = -hw ; i <= hw ; i++) {
@@ -933,9 +933,9 @@ static void _am_compute4by1ErrorVector(
e[3][0] += diffgrady;
}
}
-
+
for(i = 0; i < 4; i++) e[i][0] *= 0.5;
-
+
}
@@ -950,7 +950,7 @@ static void _am_compute4by1ErrorVector(
* KLT_TRACKED otherwise.
*/
-/* if you enalbe the DEBUG_AFFINE_MAPPING make sure you have created a directory "./debug" */
+/* if you enable the DEBUG_AFFINE_MAPPING make sure you have created a directory "./debug" */
/* #define DEBUG_AFFINE_MAPPING */
#ifdef DEBUG_AFFINE_MAPPING
@@ -963,10 +963,10 @@ static int _am_trackFeatureAffine(
float y1,
float *x2, /* starting location of search in second image */
float *y2,
- _KLT_FloatImage img1,
+ _KLT_FloatImage img1,
_KLT_FloatImage gradx1,
_KLT_FloatImage grady1,
- _KLT_FloatImage img2,
+ _KLT_FloatImage img2,
_KLT_FloatImage gradx2,
_KLT_FloatImage grady2,
int width, /* size of window */
@@ -980,7 +980,7 @@ static int _am_trackFeatureAffine(
int lighting_insensitive, /* whether to normalize for gain and bias */
int affine_map, /* whether to evaluates the consistency of features with affine mapping */
float mdd, /* difference between the displacements */
- float *Axx, float *Ayx,
+ float *Axx, float *Ayx,
float *Axy, float *Ayy) /* used affine mapping */
{
@@ -996,7 +996,7 @@ static int _am_trackFeatureAffine(
int nc2 = img2->ncols;
int nr2 = img2->nrows;
float **a;
- float **T;
+ float **T;
float one_plus_eps = 1.001f; /* To prevent rounding errors */
float old_x2 = *x2;
float old_y2 = *y2;
@@ -1007,7 +1007,7 @@ static int _am_trackFeatureAffine(
_KLT_FloatImage aff_diff_win = _KLTCreateFloatImage(width,height);
printf("starting location x2=%f y2=%f\n", *x2, *y2);
#endif
-
+
/* Allocate memory for windows */
imgdiff = _allocateFloatWindow(width, height);
gradx = _allocateFloatWindow(width, height);
@@ -1019,7 +1019,7 @@ static int _am_trackFeatureAffine(
do {
if(!affine_map) {
/* pure translation tracker */
-
+
/* If out of bounds, exit loop */
if ( x1-hw < 0.0f || nc1-( x1+hw) < one_plus_eps ||
*x2-hw < 0.0f || nc2-(*x2+hw) < one_plus_eps ||
@@ -1028,47 +1028,47 @@ static int _am_trackFeatureAffine(
status = KLT_OOB;
break;
}
-
+
/* Compute gradient and difference windows */
if (lighting_insensitive) {
- _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2,
+ _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
- _computeGradientSumLightingInsensitive(gradx1, grady1, gradx2, grady2,
+ _computeGradientSumLightingInsensitive(gradx1, grady1, gradx2, grady2,
img1, img2, x1, y1, *x2, *y2, width, height, gradx, grady);
} else {
- _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
+ _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
- _computeGradientSum(gradx1, grady1, gradx2, grady2,
+ _computeGradientSum(gradx1, grady1, gradx2, grady2,
x1, y1, *x2, *y2, width, height, gradx, grady);
}
-
-#ifdef DEBUG_AFFINE_MAPPING
+
+#ifdef DEBUG_AFFINE_MAPPING
aff_diff_win->data = imgdiff;
sprintf(fname, "./debug/kltimg_trans_diff_win%03d.%03d.pgm", glob_index, counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
printf("iter = %d translation tracker res: %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height));
#endif
-
+
/* Use these windows to construct matrices */
- _compute2by2GradientMatrix(gradx, grady, width, height,
+ _compute2by2GradientMatrix(gradx, grady, width, height,
&gxx, &gxy, &gyy);
_compute2by1ErrorVector(imgdiff, gradx, grady, width, height, step_factor,
&ex, &ey);
-
+
/* Using matrices, solve equation for new displacement */
status = _solveEquation(gxx, gxy, gyy, ex, ey, small, &dx, &dy);
convergence = (fabs(dx) < th && fabs(dy) < th);
-
+
*x2 += dx;
*y2 += dy;
-
+
}else{
/* affine tracker */
-
+
float ul_x = *Axx * (-hw) + *Axy * hh + *x2; /* upper left corner */
- float ul_y = *Ayx * (-hw) + *Ayy * hh + *y2;
+ float ul_y = *Ayx * (-hw) + *Ayy * hh + *y2;
float ll_x = *Axx * (-hw) + *Axy * (-hh) + *x2; /* lower left corner */
float ll_y = *Ayx * (-hw) + *Ayy * (-hh) + *y2;
float ur_x = *Axx * hw + *Axy * hh + *x2; /* upper right corner */
@@ -1098,25 +1098,25 @@ static int _am_trackFeatureAffine(
sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_1.pgm", glob_index, counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
-
+
_am_computeAffineMappedImage(img2, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy, width, height, imgdiff);
aff_diff_win->data = imgdiff;
sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_2.pgm", glob_index, counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
#endif
-
+
_am_computeIntensityDifferenceAffine(img1, img2, x1, y1, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy,
width, height, imgdiff);
-#ifdef DEBUG_AFFINE_MAPPING
+#ifdef DEBUG_AFFINE_MAPPING
aff_diff_win->data = imgdiff;
sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_3.pgm", glob_index,counter);
printf("%s\n", fname);
_KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0);
-
+
printf("iter = %d affine tracker res: %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height));
-#endif
-
+#endif
+
_am_getGradientWinAffine(gradx2, grady2, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy,
width, height, gradx, grady);
@@ -1124,24 +1124,24 @@ static int _am_trackFeatureAffine(
case 1:
_am_compute4by1ErrorVector(imgdiff, gradx, grady, width, height, a);
_am_compute4by4GradientMatrix(gradx, grady, width, height, T);
-
+
status = _am_gauss_jordan_elimination(T,4,a,1);
-
+
*Axx += a[0][0];
*Ayx += a[1][0];
*Ayy = *Axx;
*Axy = -(*Ayx);
-
+
dx = a[2][0];
dy = a[3][0];
-
+
break;
case 2:
_am_compute6by1ErrorVector(imgdiff, gradx, grady, width, height, a);
_am_compute6by6GradientMatrix(gradx, grady, width, height, T);
-
+
status = _am_gauss_jordan_elimination(T,6,a,1);
-
+
*Axx += a[0][0];
*Ayx += a[1][0];
*Axy += a[2][0];
@@ -1149,30 +1149,30 @@ static int _am_trackFeatureAffine(
dx = a[4][0];
dy = a[5][0];
-
+
break;
}
-
+
*x2 += dx;
*y2 += dy;
-
+
/* old upper left corner - new upper left corner */
- ul_x -= *Axx * (-hw) + *Axy * hh + *x2;
- ul_y -= *Ayx * (-hw) + *Ayy * hh + *y2;
+ ul_x -= *Axx * (-hw) + *Axy * hh + *x2;
+ ul_y -= *Ayx * (-hw) + *Ayy * hh + *y2;
/* old lower left corner - new lower left corner */
- ll_x -= *Axx * (-hw) + *Axy * (-hh) + *x2;
+ ll_x -= *Axx * (-hw) + *Axy * (-hh) + *x2;
ll_y -= *Ayx * (-hw) + *Ayy * (-hh) + *y2;
/* old upper right corner - new upper right corner */
- ur_x -= *Axx * hw + *Axy * hh + *x2;
+ ur_x -= *Axx * hw + *Axy * hh + *x2;
ur_y -= *Ayx * hw + *Ayy * hh + *y2;
/* old lower right corner - new lower right corner */
- lr_x -= *Axx * hw + *Axy * (-hh) + *x2;
+ lr_x -= *Axx * hw + *Axy * (-hh) + *x2;
lr_y -= *Ayx * hw + *Ayy * (-hh) + *y2;
-#ifdef DEBUG_AFFINE_MAPPING
+#ifdef DEBUG_AFFINE_MAPPING
printf ("iter = %d, ul_x=%f ul_y=%f ll_x=%f ll_y=%f ur_x=%f ur_y=%f lr_x=%f lr_y=%f \n",
iteration, ul_x, ul_y, ll_x, ll_y, ur_x, ur_y, lr_x, lr_y);
-#endif
+#endif
convergence = (fabs(dx) < th && fabs(dy) < th &&
fabs(ul_x) < th_aff && fabs(ul_y) < th_aff &&
@@ -1180,19 +1180,19 @@ static int _am_trackFeatureAffine(
fabs(ur_x) < th_aff && fabs(ur_y) < th_aff &&
fabs(lr_x) < th_aff && fabs(lr_y) < th_aff);
}
-
+
if (status == KLT_SMALL_DET) break;
iteration++;
-#ifdef DEBUG_AFFINE_MAPPING
+#ifdef DEBUG_AFFINE_MAPPING
printf ("iter = %d, x1=%f, y1=%f, x2=%f, y2=%f, Axx=%f, Ayx=%f , Axy=%f, Ayy=%f \n",iteration, x1, y1, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy);
-#endif
- } while ( !convergence && iteration < max_iterations);
+#endif
+ } while ( !convergence && iteration < max_iterations);
/*} while ( (fabs(dx)>=th || fabs(dy)>=th || (affine_map && iteration < 8) ) && iteration < max_iterations); */
_am_free_matrix(T);
_am_free_matrix(a);
/* Check whether window is out of bounds */
- if (*x2-hw < 0.0f || nc2-(*x2+hw) < one_plus_eps ||
+ if (*x2-hw < 0.0f || nc2-(*x2+hw) < one_plus_eps ||
*y2-hh < 0.0f || nr2-(*y2+hh) < one_plus_eps)
status = KLT_OOB;
@@ -1203,7 +1203,7 @@ static int _am_trackFeatureAffine(
/* Check whether residue is too large */
if (status == KLT_TRACKED) {
if(!affine_map){
- _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
+ _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2,
width, height, imgdiff);
}else{
_am_computeIntensityDifferenceAffine(img1, img2, x1, y1, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy,
@@ -1211,8 +1211,8 @@ static int _am_trackFeatureAffine(
}
#ifdef DEBUG_AFFINE_MAPPING
printf("iter = %d final_res = %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height));
-#endif
- if (_sumAbsFloatWindow(imgdiff, width, height)/(width*height) > max_residue)
+#endif
+ if (_sumAbsFloatWindow(imgdiff, width, height)/(width*height) > max_residue)
status = KLT_LARGE_RESIDUE;
}
@@ -1222,8 +1222,8 @@ static int _am_trackFeatureAffine(
#ifdef DEBUG_AFFINE_MAPPING
printf("iter = %d status=%d\n", iteration, status);
_KLTFreeFloatImage( aff_diff_win );
-#endif
-
+#endif
+
/* Return appropriate value */
return status;
}
@@ -1313,7 +1313,7 @@ void KLTTrackFeatures(
pyramid1_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels);
pyramid1_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels);
for (i = 0 ; i < tc->nPyramidLevels ; i++)
- _KLTComputeGradients(pyramid1->img[i], tc->grad_sigma,
+ _KLTComputeGradients(pyramid1->img[i], tc->grad_sigma,
pyramid1_gradx->img[i],
pyramid1_grady->img[i]);
}
@@ -1327,7 +1327,7 @@ void KLTTrackFeatures(
pyramid2_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels);
pyramid2_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels);
for (i = 0 ; i < tc->nPyramidLevels ; i++)
- _KLTComputeGradients(pyramid2->img[i], tc->grad_sigma,
+ _KLTComputeGradients(pyramid2->img[i], tc->grad_sigma,
pyramid2_gradx->img[i],
pyramid2_grady->img[i]);
@@ -1372,11 +1372,11 @@ void KLTTrackFeatures(
xloc *= subsampling; yloc *= subsampling;
xlocout *= subsampling; ylocout *= subsampling;
- val = _trackFeature(xloc, yloc,
+ val = _trackFeature(xloc, yloc,
&xlocout, &ylocout,
- pyramid1->img[r],
- pyramid1_gradx->img[r], pyramid1_grady->img[r],
- pyramid2->img[r],
+ pyramid1->img[r],
+ pyramid1_gradx->img[r], pyramid1_grady->img[r],
+ pyramid2->img[r],
pyramid2_gradx->img[r], pyramid2_grady->img[r],
tc->window_width, tc->window_height,
tc->step_factor,
@@ -1449,7 +1449,7 @@ void KLTTrackFeatures(
if (tc->affineConsistencyCheck >= 0 && val == KLT_TRACKED) { /*for affine mapping*/
int border = 2; /* add border for interpolation */
-#ifdef DEBUG_AFFINE_MAPPING
+#ifdef DEBUG_AFFINE_MAPPING
glob_index = indx;
#endif
@@ -1467,10 +1467,10 @@ void KLTTrackFeatures(
/* affine tracking */
val = _am_trackFeatureAffine(featurelist->feature[indx]->aff_x, featurelist->feature[indx]->aff_y,
&xlocout, &ylocout,
- featurelist->feature[indx]->aff_img,
- featurelist->feature[indx]->aff_img_gradx,
+ featurelist->feature[indx]->aff_img,
+ featurelist->feature[indx]->aff_img_gradx,
featurelist->feature[indx]->aff_img_grady,
- pyramid2->img[0],
+ pyramid2->img[0],
pyramid2_gradx->img[0], pyramid2_grady->img[0],
tc->affine_window_width, tc->affine_window_height,
tc->step_factor,
@@ -1478,14 +1478,14 @@ void KLTTrackFeatures(
tc->min_determinant,
tc->min_displacement,
tc->affine_min_displacement,
- tc->affine_max_residue,
+ tc->affine_max_residue,
tc->lighting_insensitive,
tc->affineConsistencyCheck,
tc->affine_max_displacement_differ,
&featurelist->feature[indx]->aff_Axx,
&featurelist->feature[indx]->aff_Ayx,
&featurelist->feature[indx]->aff_Axy,
- &featurelist->feature[indx]->aff_Ayy
+ &featurelist->feature[indx]->aff_Ayy
);
featurelist->feature[indx]->val = val;
if(val != KLT_TRACKED){
@@ -1538,5 +1538,3 @@ void KLTTrackFeatures(
}
}
-
-
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index b58f0f866..9addfdce9 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -611,7 +611,9 @@ ColorToningParams::LabCorrectionRegion::LabCorrectionRegion():
a(0),
b(0),
saturation(0),
- lightness(0),
+ slope(1),
+ offset(0),
+ power(1),
hueMask{
FCT_MinMaxCPoints,
0.166666667,
@@ -644,7 +646,9 @@ ColorToningParams::LabCorrectionRegion::LabCorrectionRegion():
1.,
0.35,
0.35
- }
+ },
+ maskBlur(0),
+ channel(ColorToningParams::LabCorrectionRegion::CHAN_ALL)
{
}
@@ -654,10 +658,14 @@ bool ColorToningParams::LabCorrectionRegion::operator==(const LabCorrectionRegio
return a == other.a
&& b == other.b
&& saturation == other.saturation
- && lightness == other.lightness
+ && slope == other.slope
+ && offset == other.offset
+ && power == other.power
&& hueMask == other.hueMask
&& chromaticityMask == other.chromaticityMask
- && lightnessMask == other.lightnessMask;
+ && lightnessMask == other.lightnessMask
+ && maskBlur == other.maskBlur
+ && channel == other.channel;
}
@@ -3479,10 +3487,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
putToKeyfile("ColorToning", Glib::ustring("LabRegionA_") + n, l.a, keyFile);
putToKeyfile("ColorToning", Glib::ustring("LabRegionB_") + n, l.b, keyFile);
putToKeyfile("ColorToning", Glib::ustring("LabRegionSaturation_") + n, l.saturation, keyFile);
- putToKeyfile("ColorToning", Glib::ustring("LabRegionLightness_") + n, l.lightness, keyFile);
+ putToKeyfile("ColorToning", Glib::ustring("LabRegionSlope_") + n, l.slope, keyFile);
+ putToKeyfile("ColorToning", Glib::ustring("LabRegionOffset_") + n, l.offset, keyFile);
+ putToKeyfile("ColorToning", Glib::ustring("LabRegionPower_") + n, l.power, keyFile);
putToKeyfile("ColorToning", Glib::ustring("LabRegionHueMask_") + n, l.hueMask, keyFile);
putToKeyfile("ColorToning", Glib::ustring("LabRegionChromaticityMask_") + n, l.chromaticityMask, keyFile);
putToKeyfile("ColorToning", Glib::ustring("LabRegionLightnessMask_") + n, l.lightnessMask, keyFile);
+ putToKeyfile("ColorToning", Glib::ustring("LabRegionMaskBlur_") + n, l.maskBlur, keyFile);
+ putToKeyfile("ColorToning", Glib::ustring("LabRegionChannel_") + n, l.channel, keyFile);
}
}
saveToKeyfile(!pedited || pedited->colorToning.labregionsShowMask, "ColorToning", "LabRegionsShowMask", colorToning.labregionsShowMask, keyFile);
@@ -4869,7 +4881,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
found = true;
done = false;
}
- if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionLightness_") + n, pedited, cur.lightness, pedited->colorToning.labregions)) {
+ if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionSlope_") + n, pedited, cur.slope, pedited->colorToning.labregions)) {
+ found = true;
+ done = false;
+ }
+ if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionOffset_") + n, pedited, cur.offset, pedited->colorToning.labregions)) {
+ found = true;
+ done = false;
+ }
+ if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionPower_") + n, pedited, cur.power, pedited->colorToning.labregions)) {
found = true;
done = false;
}
@@ -4885,6 +4905,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
found = true;
done = false;
}
+ if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionMaskBlur_") + n, pedited, cur.maskBlur, pedited->colorToning.labregions)) {
+ found = true;
+ done = false;
+ }
+ if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionChannel_") + n, pedited, cur.channel, pedited->colorToning.labregions)) {
+ found = true;
+ done = false;
+ }
if (!done) {
lg.emplace_back(cur);
}
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 81416b169..79f3fc7ec 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -454,13 +454,18 @@ struct ColorToningParams {
static const double LABGRID_CORR_SCALE;
struct LabCorrectionRegion {
+ enum { CHAN_ALL = -1, CHAN_R, CHAN_G, CHAN_B };
double a;
double b;
double saturation;
- double lightness;
+ double slope;
+ double offset;
+ double power;
std::vector hueMask;
std::vector chromaticityMask;
std::vector lightnessMask;
+ double maskBlur;
+ int channel;
LabCorrectionRegion();
bool operator==(const LabCorrectionRegion &other) const;
diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc
index 80796d0ae..55d9f3c79 100644
--- a/rtgui/batchtoolpanelcoord.cc
+++ b/rtgui/batchtoolpanelcoord.cc
@@ -107,7 +107,7 @@ void BatchToolPanelCoordinator::initSession ()
// compare all the ProcParams and describe which parameters has different (i.e. inconsistent) values in pparamsEdited
pparamsEdited.initFrom (initialPP);
- crop->setDimensions (100000, 100000);
+ //crop->setDimensions (100000, 100000);
/* if (!selected.empty()) {
pparams = selected[0]->getProcParams ();
@@ -126,6 +126,10 @@ void BatchToolPanelCoordinator::initSession ()
pparams = selected[0]->getProcParams ();
coarse->initBatchBehavior ();
+
+ int w,h;
+ selected[0]->getOriginalSize(w,h);
+ crop->setDimensions (w, h);
if (selected.size() == 1) {
diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc
index 3ec149a0a..ec89118df 100644
--- a/rtgui/colortoning.cc
+++ b/rtgui/colortoning.cc
@@ -361,14 +361,19 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR
EvLabRegionAB = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_AB");
EvLabRegionSaturation = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_SATURATION");
EvLabRegionLightness = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS");
+ EvLabRegionSlope = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_SLOPE");
+ EvLabRegionOffset = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_OFFSET");
+ EvLabRegionPower = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_POWER");
EvLabRegionHueMask = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_HUEMASK");
EvLabRegionChromaticityMask = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK");
EvLabRegionLightnessMask = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK");
+ EvLabRegionMaskBlur = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR");
EvLabRegionShowMask = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK");
+ EvLabRegionChannel = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_COLORTONING_LABREGION_CHANNEL");
labRegionBox = Gtk::manage(new Gtk::VBox());
labRegionList = Gtk::manage(new Gtk::ListViewText(3));
- labRegionList->set_size_request(-1, 100);
+ labRegionList->set_size_request(-1, 150);
labRegionList->set_can_focus(false);
labRegionList->set_column_title(0, "#");
labRegionList->set_column_title(1, M("TP_COLORTONING_LABREGION_LIST_TITLE"));
@@ -394,6 +399,10 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR
labRegionDown->add(*Gtk::manage(new RTImage("arrow-down-small.png")));
labRegionDown->signal_clicked().connect(sigc::mem_fun(*this, &ColorToning::labRegionDownPressed));
add_button(labRegionDown, vb);
+ labRegionCopy = Gtk::manage(new Gtk::Button());
+ labRegionCopy->add(*Gtk::manage(new RTImage("arrow-right-small.png")));
+ labRegionCopy->signal_clicked().connect(sigc::mem_fun(*this, &ColorToning::labRegionCopyPressed));
+ add_button(labRegionCopy, vb);
hb->pack_start(*vb, Gtk::PACK_SHRINK);
labRegionBox->pack_start(*hb, true, true);
@@ -403,9 +412,33 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR
labRegionSaturation = Gtk::manage(new Adjuster(M("TP_COLORTONING_LABREGION_SATURATION"), -100, 100, 1, 0));
labRegionSaturation->setAdjusterListener(this);
labRegionBox->pack_start(*labRegionSaturation);
- labRegionLightness = Gtk::manage(new Adjuster(M("TP_COLORTONING_LABREGION_LIGHTNESS"), -100, 100, 1, 0));
- labRegionLightness->setAdjusterListener(this);
- labRegionBox->pack_start(*labRegionLightness);
+
+ labRegionSlope = Gtk::manage(new Adjuster(M("TP_COLORTONING_LABREGION_SLOPE"), 0.1, 4.0, 0.001, 1));
+ labRegionSlope->setLogScale(4, 0.1);
+ labRegionSlope->setAdjusterListener(this);
+ labRegionBox->pack_start(*labRegionSlope);
+ labRegionOffset = Gtk::manage(new Adjuster(M("TP_COLORTONING_LABREGION_OFFSET"), -0.1, 0.1, 0.001, 0));
+ labRegionOffset->setAdjusterListener(this);
+ labRegionBox->pack_start(*labRegionOffset);
+ labRegionPower = Gtk::manage(new Adjuster(M("TP_COLORTONING_LABREGION_POWER"), 0.1, 4.0, 0.001, 1));
+ labRegionPower->setAdjusterListener(this);
+ labRegionPower->setLogScale(4, 0.1);
+ labRegionBox->pack_start(*labRegionPower);
+
+ hb = Gtk::manage(new Gtk::HBox());
+ labRegionChannel = Gtk::manage(new MyComboBoxText());
+ labRegionChannel->append(M("TP_COLORTONING_LABREGION_CHANNEL_ALL"));
+ labRegionChannel->append(M("TP_COLORTONING_LABREGION_CHANNEL_R"));
+ labRegionChannel->append(M("TP_COLORTONING_LABREGION_CHANNEL_G"));
+ labRegionChannel->append(M("TP_COLORTONING_LABREGION_CHANNEL_B"));
+ labRegionChannel->set_active(0);
+ labRegionChannel->signal_changed().connect(sigc::mem_fun(*this, &ColorToning::labRegionChannelChanged));
+
+ hb->pack_start(*Gtk::manage(new Gtk::Label(M("TP_COLORTONING_LABREGION_CHANNEL") + ": ")), Gtk::PACK_SHRINK);
+ hb->pack_start(*labRegionChannel);
+ labRegionBox->pack_start(*hb);
+
+ labRegionBox->pack_start(*Gtk::manage(new Gtk::HSeparator()));
CurveEditorGroup *labRegionEditorG = Gtk::manage(new CurveEditorGroup(options.lastColorToningCurvesDir, M("TP_COLORTONING_LABREGION_MASK")));
labRegionEditorG->setCurveListener(this);
@@ -440,11 +473,22 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR
labRegionEditorG->show();
labRegionBox->pack_start(*labRegionEditorG, Gtk::PACK_SHRINK, 2);
+ labRegionMaskBlur = Gtk::manage(new Adjuster(M("TP_COLORTONING_LABREGION_MASKBLUR"), -10, 100, 0.1, 0));
+ labRegionMaskBlur->setLogScale(10, 0);
+ labRegionMaskBlur->setAdjusterListener(this);
+ labRegionBox->pack_start(*labRegionMaskBlur);
+
labRegionShowMask = Gtk::manage(new Gtk::CheckButton(M("TP_COLORTONING_LABREGION_SHOWMASK")));
labRegionShowMask->signal_toggled().connect(sigc::mem_fun(*this, &ColorToning::labRegionShowMaskChanged));
labRegionBox->pack_start(*labRegionShowMask, Gtk::PACK_SHRINK, 4);
pack_start(*labRegionBox, Gtk::PACK_EXPAND_WIDGET, 4);
+
+ labRegionSaturation->delay = options.adjusterMaxDelay;
+ labRegionSlope->delay = options.adjusterMaxDelay;
+ labRegionOffset->delay = options.adjusterMaxDelay;
+ labRegionPower->delay = options.adjusterMaxDelay;
+ labRegionMaskBlur->delay = options.adjusterMaxDelay;
//------------------------------------------------------------------------
show_all();
@@ -1335,8 +1379,14 @@ void ColorToning::adjusterChanged(Adjuster* a, double newval)
listener->panelChanged (EvColorToningStrength, a->getTextValue());
} else if (a == labRegionSaturation) {
listener->panelChanged(EvLabRegionSaturation, a->getTextValue());
- } else if (a == labRegionLightness) {
- listener->panelChanged(EvLabRegionLightness, a->getTextValue());
+ } else if (a == labRegionSlope) {
+ listener->panelChanged(EvLabRegionSlope, a->getTextValue());
+ } else if (a == labRegionOffset) {
+ listener->panelChanged(EvLabRegionOffset, a->getTextValue());
+ } else if (a == labRegionPower) {
+ listener->panelChanged(EvLabRegionPower, a->getTextValue());
+ } else if (a == labRegionMaskBlur) {
+ listener->panelChanged(EvLabRegionMaskBlur, a->getTextValue());
}
}
@@ -1395,10 +1445,14 @@ void ColorToning::labRegionGet(int idx)
double la, lb;
labRegionAB->getParams(la, lb, r.a, r.b);
r.saturation = labRegionSaturation->getValue();
- r.lightness = labRegionLightness->getValue();
+ r.slope = labRegionSlope->getValue();
+ r.offset = labRegionOffset->getValue();
+ r.power = labRegionPower->getValue();
r.hueMask = labRegionHueMask->getCurve();
r.chromaticityMask = labRegionChromaticityMask->getCurve();
r.lightnessMask = labRegionLightnessMask->getCurve();
+ r.maskBlur = labRegionMaskBlur->getValue();
+ r.channel = labRegionChannel->get_active_row_number() - 1;
}
@@ -1462,6 +1516,21 @@ void ColorToning::labRegionDownPressed()
}
+void ColorToning::labRegionCopyPressed()
+{
+ if (labRegionSelected < int(labRegionData.size())) {
+ auto r = labRegionData[labRegionSelected];
+ labRegionData.push_back(r);
+ labRegionSelected = labRegionData.size()-1;
+ labRegionPopulateList();
+
+ if (listener) {
+ listener->panelChanged(EvLabRegionList, M("HISTORY_CHANGED"));
+ }
+ }
+}
+
+
void ColorToning::labRegionShowMaskChanged()
{
if (listener) {
@@ -1479,13 +1548,26 @@ void ColorToning::labRegionPopulateList()
for (size_t i = 0; i < labRegionData.size(); ++i) {
auto &r = labRegionData[i];
auto j = labRegionList->append(std::to_string(i+1));
- labRegionList->set_text(j, 1, Glib::ustring::compose("a=%1 b=%2 s=%3 l=%4", round_ab(r.a), round_ab(r.b), r.saturation, r.lightness));
+ labRegionList->set_text(j, 1, Glib::ustring::compose("a=%1 b=%2 S=%3\ns=%4 o=%5 p=%6", round_ab(r.a), round_ab(r.b), r.saturation, r.slope, r.offset, r.power));
+ const char *ch = "";
+ switch (r.channel) {
+ case rtengine::ColorToningParams::LabCorrectionRegion::CHAN_R:
+ ch = "\n[Red]"; break;
+ case rtengine::ColorToningParams::LabCorrectionRegion::CHAN_G:
+ ch = "\n[Green]"; break;
+ case rtengine::ColorToningParams::LabCorrectionRegion::CHAN_B:
+ ch = "\n[Blue]"; break;
+ default:
+ ch = "";
+ }
labRegionList->set_text(
j, 2, Glib::ustring::compose(
- "%1%2%3",
+ "%1%2%3%4%5",
hasMask(dflt.hueMask, r.hueMask) ? "H" : "",
hasMask(dflt.chromaticityMask, r.chromaticityMask) ? "C" : "",
- hasMask(dflt.lightnessMask, r.lightnessMask) ? "L" : ""));
+ hasMask(dflt.lightnessMask, r.lightnessMask) ? "L" : "",
+ r.maskBlur ? Glib::ustring::compose(" b=%1", r.maskBlur) : "",
+ ch));
}
}
@@ -1501,18 +1583,34 @@ void ColorToning::labRegionShow(int idx, bool list_only)
if (!list_only) {
labRegionAB->setParams(0, 0, r.a, r.b, false);
labRegionSaturation->setValue(r.saturation);
- labRegionLightness->setValue(r.lightness);
+ labRegionSlope->setValue(r.slope);
+ labRegionOffset->setValue(r.offset);
+ labRegionPower->setValue(r.power);
labRegionHueMask->setCurve(r.hueMask);
labRegionChromaticityMask->setCurve(r.chromaticityMask);
labRegionLightnessMask->setCurve(r.lightnessMask);
+ labRegionMaskBlur->setValue(r.maskBlur);
+ labRegionChannel->set_active(r.channel+1);
+ }
+ labRegionList->set_text(idx, 1, Glib::ustring::compose("a=%1 b=%2 S=%3\ns=%4 o=%5 p=%6", round_ab(r.a), round_ab(r.b), r.saturation, r.slope, r.offset, r.power));
+ const char *ch = "";
+ switch (r.channel) {
+ case rtengine::ColorToningParams::LabCorrectionRegion::CHAN_R:
+ ch = "\n[Red]"; break;
+ case rtengine::ColorToningParams::LabCorrectionRegion::CHAN_G:
+ ch = "\n[Green]"; break;
+ case rtengine::ColorToningParams::LabCorrectionRegion::CHAN_B:
+ ch = "\n[Blue]"; break;
+ default:
+ ch = "";
}
- labRegionList->set_text(idx, 1, Glib::ustring::compose("a=%1 b=%2 s=%3 l=%4", round_ab(r.a), round_ab(r.b), r.saturation, r.lightness));
labRegionList->set_text(
idx, 2, Glib::ustring::compose(
- "%1%2%3",
+ "%1%2%3%4%5",
hasMask(dflt.hueMask, r.hueMask) ? "H" : "",
hasMask(dflt.chromaticityMask, r.chromaticityMask) ? "C" : "",
- hasMask(dflt.lightnessMask, r.lightnessMask) ? "L" : ""));
+ hasMask(dflt.lightnessMask, r.lightnessMask) ? "L" : "",
+ r.maskBlur ? Glib::ustring::compose(" b=%1", r.maskBlur) : "", ch));
Gtk::TreePath pth;
pth.push_back(idx);
labRegionList->get_selection()->select(pth);
@@ -1522,6 +1620,14 @@ void ColorToning::labRegionShow(int idx, bool list_only)
}
+void ColorToning::labRegionChannelChanged()
+{
+ if (listener) {
+ listener->panelChanged(EvLabRegionChannel, labRegionChannel->get_active_text());
+ }
+}
+
+
void ColorToning::setEditProvider(EditDataProvider *provider)
{
labRegionHueMask->setEditProvider(provider);
diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h
index acf3fa8b5..29a71b03b 100644
--- a/rtgui/colortoning.h
+++ b/rtgui/colortoning.h
@@ -67,7 +67,9 @@ private:
void labRegionRemovePressed();
void labRegionUpPressed();
void labRegionDownPressed();
+ void labRegionCopyPressed();
void labRegionShowMaskChanged();
+ void labRegionChannelChanged();
void labRegionPopulateList();
void labRegionShow(int idx, bool list_only=false);
void labRegionGet(int idx);
@@ -130,10 +132,15 @@ private:
rtengine::ProcEvent EvLabRegionAB;
rtengine::ProcEvent EvLabRegionSaturation;
rtengine::ProcEvent EvLabRegionLightness;
+ rtengine::ProcEvent EvLabRegionSlope;
+ rtengine::ProcEvent EvLabRegionOffset;
+ rtengine::ProcEvent EvLabRegionPower;
rtengine::ProcEvent EvLabRegionHueMask;
rtengine::ProcEvent EvLabRegionChromaticityMask;
rtengine::ProcEvent EvLabRegionLightnessMask;
+ rtengine::ProcEvent EvLabRegionMaskBlur;
rtengine::ProcEvent EvLabRegionShowMask;
+ rtengine::ProcEvent EvLabRegionChannel;
Gtk::VBox *labRegionBox;
Gtk::ListViewText *labRegionList;
@@ -141,12 +148,17 @@ private:
Gtk::Button *labRegionRemove;
Gtk::Button *labRegionUp;
Gtk::Button *labRegionDown;
+ Gtk::Button *labRegionCopy;
LabGrid *labRegionAB;
Adjuster *labRegionSaturation;
- Adjuster *labRegionLightness;
+ Adjuster *labRegionSlope;
+ Adjuster *labRegionOffset;
+ Adjuster *labRegionPower;
+ MyComboBoxText *labRegionChannel;
FlatCurveEditor *labRegionHueMask;
FlatCurveEditor *labRegionChromaticityMask;
FlatCurveEditor *labRegionLightnessMask;
+ Adjuster *labRegionMaskBlur;
Gtk::CheckButton *labRegionShowMask;
std::vector labRegionData;
int labRegionSelected;
diff --git a/rtgui/crop.cc b/rtgui/crop.cc
index d5b246107..2484b9060 100644
--- a/rtgui/crop.cc
+++ b/rtgui/crop.cc
@@ -99,89 +99,129 @@ Crop::Crop():
maxw = 3000;
maxh = 2000;
- Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
+ methodgrid = Gtk::manage(new Gtk::Grid());
+ methodgrid->get_style_context()->add_class("grid-spacing");
+ setExpandAlignProperties(methodgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
- hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_X") + ": ")));
+ Gtk::Label* xlab = Gtk::manage (new Gtk::Label (M("TP_CROP_X") + ":"));
+ setExpandAlignProperties(xlab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
+
x = Gtk::manage (new MySpinButton ());
- x->set_size_request (60, -1);
- hb1->pack_start (*x);
+ setExpandAlignProperties(x, true, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
+ x->set_width_chars(6);
- hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_Y") + ": ")));
+ Gtk::Label* ylab = Gtk::manage (new Gtk::Label (M("TP_CROP_Y") + ":"));
+ setExpandAlignProperties(ylab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
+
y = Gtk::manage (new MySpinButton ());
- y->set_size_request (60, -1);
- hb1->pack_start (*y);
-
- pack_start (*hb1, Gtk::PACK_SHRINK, 2);
-
- Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ());
-
- hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_W") + ": ")));
+ setExpandAlignProperties(y, true, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
+ y->set_width_chars(6);
+
+ Gtk::Label* wlab = Gtk::manage (new Gtk::Label (M("TP_CROP_W") + ":"));
+ setExpandAlignProperties(wlab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
+
w = Gtk::manage (new MySpinButton ());
- w->set_size_request (60, -1);
- hb2->pack_start (*w);
+ setExpandAlignProperties(w, true, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
+ w->set_width_chars(6);
- hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_H") + ": ")));
+ Gtk::Label* hlab = Gtk::manage (new Gtk::Label (M("TP_CROP_H") + ":"));
+ setExpandAlignProperties(hlab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
+
h = Gtk::manage (new MySpinButton ());
- h->set_size_request (60, -1);
- hb2->pack_start (*h);
-
- pack_start (*hb2, Gtk::PACK_SHRINK, 4);
+ setExpandAlignProperties(h, true, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
+ h->set_width_chars(6);
selectCrop = Gtk::manage (new Gtk::Button (M("TP_CROP_SELECTCROP")));
+ setExpandAlignProperties(selectCrop, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
selectCrop->get_style_context()->add_class("independent");
selectCrop->set_image (*Gtk::manage (new RTImage ("crop-small.png")));
- pack_start (*selectCrop, Gtk::PACK_SHRINK, 2);
+ resetCrop = Gtk::manage (new Gtk::Button (M("TP_CROP_RESETCROP")));
+ setExpandAlignProperties(resetCrop, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
+ resetCrop->get_style_context()->add_class("independent");
+ resetCrop->set_image (*Gtk::manage (new RTImage ("undo-small.png")));
+
+ methodgrid->attach (*xlab, 0, 0, 1, 1);
+ methodgrid->attach (*x, 1, 0, 1, 1);
+ methodgrid->attach (*ylab, 2, 0, 1, 1);
+ methodgrid->attach (*y, 3, 0, 1, 1);
+ methodgrid->attach (*wlab, 0, 1, 1, 1);
+ methodgrid->attach (*w, 1, 1, 1, 1);
+ methodgrid->attach (*hlab, 2, 1, 1, 1);
+ methodgrid->attach (*h, 3, 1, 1, 1);
+ methodgrid->attach (*selectCrop, 0, 2, 2, 1);
+ methodgrid->attach (*resetCrop, 2, 2, 2, 1);
+ pack_start (*methodgrid, Gtk::PACK_EXPAND_WIDGET, 0 );
+
+ Gtk::HSeparator* methodseparator = Gtk::manage (new Gtk::HSeparator());
+ methodseparator->get_style_context()->add_class("grid-row-separator");
+ pack_start (*methodseparator, Gtk::PACK_SHRINK, 0);
- Gtk::HBox* hb3 = Gtk::manage (new Gtk::HBox ());
+ Gtk::Grid* settingsgrid = Gtk::manage(new Gtk::Grid());
+ settingsgrid->get_style_context()->add_class("grid-spacing");
+ setExpandAlignProperties(settingsgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
fixr = Gtk::manage (new Gtk::CheckButton (M("TP_CROP_FIXRATIO")));
+ setExpandAlignProperties(fixr, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
fixr->set_active (1);
- hb3->pack_start (*fixr, Gtk::PACK_SHRINK, 4);
-
ratio = Gtk::manage (new MyComboBoxText ());
- hb3->pack_start (*ratio, Gtk::PACK_EXPAND_WIDGET, 4);
+ setExpandAlignProperties(ratio, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
orientation = Gtk::manage (new MyComboBoxText ());
- hb3->pack_start (*orientation);
+ setExpandAlignProperties(orientation, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
- pack_start (*hb3, Gtk::PACK_SHRINK, 4);
-
- Gtk::HBox* hb31 = Gtk::manage (new Gtk::HBox ());
-
- hb31->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_GUIDETYPE"))), Gtk::PACK_SHRINK, 4);
+ Gtk::Label* guidelab = Gtk::manage (new Gtk::Label (M("TP_CROP_GUIDETYPE")));
+ setExpandAlignProperties(guidelab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
+
guide = Gtk::manage (new MyComboBoxText ());
- hb31->pack_start (*guide);
+ setExpandAlignProperties(guide, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
+
+ settingsgrid->attach (*fixr, 0, 0, 1, 1);
+ settingsgrid->attach (*ratio, 1, 0, 1, 1);
+ settingsgrid->attach (*orientation, 2, 0, 1, 1);
+ settingsgrid->attach (*guidelab, 0, 1, 1, 1);
+ settingsgrid->attach (*guide, 1, 1, 2, 1);
+ pack_start (*settingsgrid, Gtk::PACK_SHRINK, 0 );
- pack_start (*hb31, Gtk::PACK_SHRINK, 4);
- // ppibox START
- ppibox = Gtk::manage (new Gtk::VBox());
- ppibox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2);
+ // ppigrid START
+ ppigrid = Gtk::manage(new Gtk::Grid());
+ ppigrid->get_style_context()->add_class("grid-spacing");
+ ppigrid->set_column_homogeneous (true);
+ setExpandAlignProperties(ppigrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
- Gtk::HBox* hb4 = Gtk::manage (new Gtk::HBox ());
- hb4->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_PPI"))));
+ Gtk::HSeparator* ppiseparator = Gtk::manage (new Gtk::HSeparator());
+ ppiseparator->get_style_context()->add_class("grid-row-separator");
+
+ Gtk::Grid* ppisubgrid = Gtk::manage(new Gtk::Grid());
+ ppisubgrid->get_style_context()->add_class("grid-spacing");
+ setExpandAlignProperties(ppisubgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
+
+ Gtk::Label* ppilab = Gtk::manage (new Gtk::Label (M("TP_CROP_PPI")));
+ setExpandAlignProperties(ppilab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
+
ppi = Gtk::manage (new MySpinButton ());
- ppi->set_size_request (60, -1);
- hb4->pack_start (*ppi);
-
- sizebox = Gtk::manage (new Gtk::VBox());
+ setExpandAlignProperties(ppi, true, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
+ ppi->set_width_chars(6);
+
+ ppisubgrid->attach (*ppilab, 0, 0, 1, 1);
+ ppisubgrid->attach (*ppi, 1, 0, 1, 1);
sizecm = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " cm x " + M("GENERAL_NA") + " cm"));
+ setExpandAlignProperties(sizecm, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
+
sizein = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " in x " + M("GENERAL_NA") + " in"));
-
- sizebox->pack_start (*sizecm, Gtk::PACK_SHRINK, 4);
- sizebox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 6);
- sizebox->pack_start (*sizein, Gtk::PACK_SHRINK, 4);
- sizebox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 6);
- sizebox->pack_start (*hb4, Gtk::PACK_SHRINK, 2);
-
- ppibox->pack_start (*sizebox, Gtk::PACK_SHRINK, 1);
- pack_start (*ppibox, Gtk::PACK_SHRINK, 0);
+ setExpandAlignProperties(sizein, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
+
+ ppigrid->attach (*ppiseparator, 0, 0, 2, 1);
+ ppigrid->attach (*sizecm, 1, 1, 1, 1);
+ ppigrid->attach (*sizein, 1, 2, 1, 1);
+ ppigrid->attach (*ppisubgrid, 0, 1, 1, 2);
+ pack_start (*ppigrid, Gtk::PACK_SHRINK, 0 );
ppi->set_value (300);
- // ppibox END
+ // ppigrid END
// Populate the combobox
for (const auto& crop_ratio : crop_ratios) {
@@ -241,6 +281,7 @@ Crop::Crop():
oconn = orientation->signal_changed().connect( sigc::mem_fun(*this, &Crop::ratioChanged) );
gconn = guide->signal_changed().connect( sigc::mem_fun(*this, &Crop::notifyListener) );
selectCrop->signal_pressed().connect( sigc::mem_fun(*this, &Crop::selectPressed) );
+ resetCrop->signal_pressed().connect( sigc::mem_fun(*this, &Crop::doresetCrop) );
ppi->signal_value_changed().connect( sigc::mem_fun(*this, &Crop::refreshSize) );
nx = ny = nw = nh = 0;
@@ -482,6 +523,23 @@ void Crop::selectPressed ()
}
}
+void Crop::doresetCrop ()
+{
+ xDirty = true;
+ yDirty = true;
+ wDirty = true;
+ hDirty = true;
+
+ int X = 0;
+ int Y = 0;
+ int W = maxw;
+ int H = maxh;
+ cropResized (X, Y, W, H);
+ idle_register.add(notifyListenerUI, this);
+
+ refreshSpins();
+}
+
void Crop::notifyListener ()
{
@@ -1296,5 +1354,7 @@ void Crop::setBatchMode (bool batchMode)
ratio->append (M("GENERAL_UNCHANGED"));
orientation->append (M("GENERAL_UNCHANGED"));
guide->append (M("GENERAL_UNCHANGED"));
- removeIfThere (this, ppibox);
+ removeIfThere (this, ppigrid);
+ removeIfThere (methodgrid, selectCrop);
+ removeIfThere (methodgrid, resetCrop);
}
diff --git a/rtgui/crop.h b/rtgui/crop.h
index 289954398..a16683d1b 100644
--- a/rtgui/crop.h
+++ b/rtgui/crop.h
@@ -51,6 +51,7 @@ public:
void ratioFixedChanged (); // The toggle button
void refreshSize ();
void selectPressed ();
+ void doresetCrop ();
void setDimensions (int mw, int mh);
void enabledChanged () override;
void positionChanged ();
@@ -102,7 +103,9 @@ private:
MyComboBoxText* ratio;
MyComboBoxText* orientation;
MyComboBoxText* guide;
+
Gtk::Button* selectCrop;
+ Gtk::Button* resetCrop;
CropPanelListener* clistener;
int opt;
MySpinButton* x;
@@ -112,8 +115,9 @@ private:
MySpinButton* ppi;
Gtk::Label* sizecm;
Gtk::Label* sizein;
- Gtk::VBox* ppibox;
- Gtk::VBox* sizebox;
+ Gtk::Grid* ppigrid;
+ Gtk::Grid* methodgrid;
+
int maxw, maxh;
double nx, ny;
int nw, nh;
diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc
index 374b755ae..45372f1f5 100644
--- a/rtgui/cropwindow.cc
+++ b/rtgui/cropwindow.cc
@@ -44,7 +44,7 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet
crop_custom_ratio(0.f)
{
initZoomSteps();
-
+
Glib::RefPtr context = parent->get_pango_context () ;
Pango::FontDescription fontd = context->get_font_description ();
fontd.set_weight (Pango::WEIGHT_BOLD);
@@ -351,7 +351,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
if ((bstate & GDK_SHIFT_MASK) && cropHandler.cropParams.w > 0 && cropHandler.cropParams.h > 0) {
crop_custom_ratio = float(cropHandler.cropParams.w) / float(cropHandler.cropParams.h);
}
-
+
if (iarea->getToolMode () == TMColorPicker) {
if (hoveredPicker) {
if ((bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) {
@@ -1385,7 +1385,7 @@ void CropWindow::expose (Cairo::RefPtr cr)
}
}
bool useBgColor = (state == SNormal || state == SDragPicker || state == SDeletePicker || state == SEditDrag1);
-
+
if (cropHandler.cropPixbuf) {
imgW = cropHandler.cropPixbuf->get_width ();
imgH = cropHandler.cropPixbuf->get_height ();
@@ -1653,7 +1653,7 @@ void CropWindow::expose (Cairo::RefPtr cr)
const int shThreshold = options.shadowThreshold;
const float ShawdowFac = 64.f / (options.shadowThreshold + 1);
const float HighlightFac = 64.f / (256 - options.highlightThreshold);
- const bool showclippedAny = (!showR && !showG && !showB && !showL); // will show clipping if any (all) of RGB chanels is (shadow) clipped
+ const bool showclippedAny = (!showR && !showG && !showB && !showL); // will show clipping if any (all) of RGB channels is (shadow) clipped
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc
index 1f46d60e7..f44e682f2 100644
--- a/rtgui/editorpanel.cc
+++ b/rtgui/editorpanel.cc
@@ -1640,6 +1640,10 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event)
iareapanel->imageArea->previewModePanel->toggleB();
return true;
+ case GDK_KEY_p: //preview mode Sharpening Contrast mask
+ iareapanel->imageArea->indClippedPanel->toggleSharpMask();
+ return true;
+
case GDK_KEY_v: //preview mode Luminosity
iareapanel->imageArea->previewModePanel->toggleL();
return true;
diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc
index 60b45519a..584412120 100644
--- a/rtgui/iccprofilecreator.cc
+++ b/rtgui/iccprofilecreator.cc
@@ -833,23 +833,29 @@ void ICCProfileCreator::savePressed()
} else if (gammaPreset == "sRGB_g2.4_s12.92") {
sGammaPreset = "sRGB_g=2.4_s=12.92310";
ga[0] = 2.40; //sRGB 2.4 12.92 - RT default as Lightroom
- ga[1] = 0.947858;
- ga[2] = 0.052142;
- ga[3] = 0.077399;
- ga[4] = 0.039293;
+ ga[1] = 0.947867;
+ ga[2] = 0.052133;
+ ga[3] = 0.077381;
+ ga[4] = 0.039286;
+ //g3 = 0.00340
+ //g4 = 0.0550
+ //g5 = 0.449842
presetGamma = 2.4;
presetSlope = 12.92310;
} else if (gammaPreset == "BT709_g2.2_s4.5") {
sGammaPreset = "BT709_g=2.2_s=4.5";
- ga[0] = 2.22; //BT709 2.2 4.5 - my preferred as D.Coffin
+ ga[0] = 2.22; //BT709 2.22 4.5 - my preferred as D.Coffin
ga[1] = 0.909995;
ga[2] = 0.090005;
ga[3] = 0.222222;
ga[4] = 0.081071;
- presetGamma = 2.2;
+ //g3=0.018016
+ //g4=0.098907
+ //g5=0.517448
+ presetGamma = 2.22;
presetSlope = 4.5;
-
+
} else if (gammaPreset == "linear_g1.0") {
sGammaPreset = "Linear_g=1.0";
ga[0] = 1.0; //gamma=1 linear : for high dynamic images (cf D.Coffin...)
@@ -1125,7 +1131,7 @@ void ICCProfileCreator::savePressed()
//calculate XYZ matrix for each primaries and each temp (D50, D65...)
- // reduce coordonate of primaries
+ // reduce coordinate of primaries
//printf("p0=%f p1=%f p2=%f p3=%f p4=%f p5=%f \n", p[0], p[1], p[2], p[3],p[4], p[5]);
double Xr = p[0] / p[1];
double Yr = 1.0;
diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc
index 4b5b21dcc..4d744edcb 100644
--- a/rtgui/thumbnail.cc
+++ b/rtgui/thumbnail.cc
@@ -618,6 +618,11 @@ void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& pparams, i
}
}
+void Thumbnail::getOriginalSize (int& w, int& h)
+{
+ w = tw;
+ h = th;
+}
rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale)
{
diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h
index ae627c22f..28762e505 100644
--- a/rtgui/thumbnail.h
+++ b/rtgui/thumbnail.h
@@ -114,6 +114,7 @@ public:
rtengine::IImage8* upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale);
void getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams = nullptr);
void getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h);
+ void getOriginalSize (int& w, int& h);
const Glib::ustring& getExifString () const;
const Glib::ustring& getDateTimeString () const;