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;