Merge branch 'dev' into hidpi-icons

This commit is contained in:
Hombre
2019-01-02 18:06:44 +01:00
14 changed files with 179 additions and 58 deletions

View File

@@ -16,11 +16,12 @@ The most useful feedback is based on the latest development code, and in the cas
- Announce and discuss your plans in GitHub before starting work.
- Work in a new branch. Fork if necessary.
- Keep branches small so that completed and working features can be merged into the "dev" branch often, and so that they can be abandoned if they head in the wrong direction.
- Use C++11
- Use C++11.
- The naming isn't homogeneous throughout the code but here is a rough guideline:
- *Types* (classes, structs, enums, typedefs...) should be named with `UpperCamelCase`
- *Functions* and *methods* should be named with `lowerCamelCase`
- *Variables* should be either named with `lowerCamelCase` or better with `lower_underscores` to avoid conflicts
- *Enum values* should be named with `UPPER_UNDERSCORES`
- Most important: Be consistent, even when not sticking to the rules
- *Identifiers* (variables, functions, methods, keys, enums, etc.) should be clear and unambiguous. Make them as long as necessary to ensure that your code is understandable to others.
- *Types* (classes, structs, enums, typedefs...) should be named with `UpperCamelCase`.
- *Functions* and *methods* should be named with `lowerCamelCase`.
- *Variables* should be either named with `lowerCamelCase` or better with `lower_underscores` to avoid conflicts.
- *Enum values* should be named with `UPPER_UNDERSCORES`.
- Be consistent, even when not sticking to the rules.
- Code may be run through astyle version 3 or newer. If using astyle, it is important that the astyle changes go into their own commit, so that style changes are not mixed with actual code changes. Command: `astyle --options=rawtherapee.astylerc code.cc`

View File

@@ -775,6 +775,7 @@ HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations
HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift
HISTORY_MSG_RAW_BORDER;Raw border
HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling
HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius
HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold
HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace
HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
@@ -2035,6 +2036,7 @@ TP_SHARPENEDGE_LABEL;Edges
TP_SHARPENEDGE_PASSES;Iterations
TP_SHARPENEDGE_THREE;Luminance only
TP_SHARPENING_AMOUNT;Amount
TP_SHARPENING_BLUR;Blur radius
TP_SHARPENING_CONTRAST;Contrast threshold
TP_SHARPENING_EDRADIUS;Radius
TP_SHARPENING_EDTOLERANCE;Edge tolerance

View File

@@ -396,6 +396,7 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * ncie, double radius, int thres
}
}
} // end of ab channel averaging
}
#ifdef _OPENMP
#pragma omp parallel for
#endif
@@ -418,7 +419,6 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * ncie, double radius, int thres
}
}
}
}
// CIECAM02 hot/bad pixel filter
void ImProcFunctions::Badpixelscam(CieImage * ncie, double radius, int thresh, int mode, float chrom, bool hotbad)

View File

@@ -159,7 +159,7 @@ extern const Settings* settings;
void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, int W, int H, const SharpeningParams &sharpenParam)
{
if (sharpenParam.deconvamount < 1) {
if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) {
return;
}
BENCHFUN
@@ -177,11 +177,31 @@ BENCHFUN
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
float contrast = sharpenParam.contrast / 100.f;
buildBlendMask(luminance, blend, W, H, contrast, sharpenParam.deconvamount / 100.f);
buildBlendMask(luminance, blend, W, H, contrast, 1.f);
JaggedArray<float>* blurbuffer = nullptr;
if (sharpenParam.blurradius >= 0.25f) {
blurbuffer = new JaggedArray<float>(W, H);
JaggedArray<float> &blur = *blurbuffer;
#ifdef _OPENMP
#pragma omp parallel
#endif
{
gaussianBlur(tmpI, blur, W, H, sharpenParam.blurradius);
#ifdef _OPENMP
#pragma omp for
#endif
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
blur[i][j] = intp(blend[i][j], luminance[i][j], std::max(blur[i][j], 0.0f));
}
}
}
}
const float damping = sharpenParam.deconvdamping / 5.0;
const bool needdamp = sharpenParam.deconvdamping > 0;
const double sigma = sharpenParam.deconvradius / scale;
const float amount = sharpenParam.deconvamount / 100.f;
#ifdef _OPENMP
#pragma omp parallel
@@ -205,10 +225,23 @@ BENCHFUN
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
luminance[i][j] = intp(blend[i][j], max(tmpI[i][j], 0.0f), luminance[i][j]);
luminance[i][j] = intp(blend[i][j] * amount, max(tmpI[i][j], 0.0f), luminance[i][j]);
}
}
if (sharpenParam.blurradius >= 0.25f) {
JaggedArray<float> &blur = *blurbuffer;
#ifdef _OPENMP
#pragma omp for
#endif
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
luminance[i][j] = intp(blend[i][j], luminance[i][j], max(blur[i][j], 0.0f));
}
}
}
} // end parallel
delete blurbuffer;
}
void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpenParam, bool showMask)
@@ -224,7 +257,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
float contrast = sharpenParam.contrast / 100.f;
buildBlendMask(lab->L, blend, W, H, contrast, sharpenParam.method == "rld" ? sharpenParam.deconvamount / 100.f : 1.f);
buildBlendMask(lab->L, blend, W, H, contrast, 1.f);
#ifdef _OPENMP
#pragma omp parallel for
#endif
@@ -261,6 +294,26 @@ BENCHFUN
float contrast = sharpenParam.contrast / 100.f;
buildBlendMask(lab->L, blend, W, H, contrast);
JaggedArray<float> blur(W, H);
if (sharpenParam.blurradius >= 0.25f) {
#ifdef _OPENMP
#pragma omp parallel
#endif
{
gaussianBlur(lab->L, blur, W, H, sharpenParam.blurradius);
#ifdef _OPENMP
#pragma omp for
#endif
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
blur[i][j] = intp(blend[i][j], lab->L[i][j], std::max(blur[i][j], 0.0f));
}
}
}
}
#ifdef _OPENMP
#pragma omp parallel
#endif
@@ -322,6 +375,18 @@ BENCHFUN
delete [] b3;
}
if (sharpenParam.blurradius >= 0.25f) {
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
lab->L[i][j] = intp(blend[i][j], lab->L[i][j], max(blur[i][j], 0.0f));
}
}
}
}
// To the extent possible under law, Manuel Llorens <manuelllorens@gmail.com>

View File

@@ -1079,6 +1079,7 @@ void ColorToningParams::getCurves(ColorGradientCurve& colorCurveLUT, OpacityCurv
SharpeningParams::SharpeningParams() :
enabled(false),
contrast(20.0),
blurradius(0.2),
radius(0.5),
amount(200),
threshold(20, 80, 2000, 1200, false),
@@ -1100,6 +1101,7 @@ bool SharpeningParams::operator ==(const SharpeningParams& other) const
return
enabled == other.enabled
&& contrast == other.contrast
&& blurradius == other.blurradius
&& radius == other.radius
&& amount == other.amount
&& threshold == other.threshold
@@ -3022,6 +3024,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->sharpening.contrast, "Sharpening", "Contrast", sharpening.contrast, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.method, "Sharpening", "Method", sharpening.method, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.radius, "Sharpening", "Radius", sharpening.radius, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.blurradius, "Sharpening", "BlurRadius", sharpening.blurradius, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.amount, "Sharpening", "Amount", sharpening.amount, keyFile);
saveToKeyfile(!pedited || pedited->sharpening.threshold, "Sharpening", "Threshold", sharpening.threshold.toVector(), keyFile);
saveToKeyfile(!pedited || pedited->sharpening.edgesonly, "Sharpening", "OnlyEdges", sharpening.edgesonly, keyFile);
@@ -3908,6 +3911,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
}
}
assignFromKeyfile(keyFile, "Sharpening", "Radius", pedited, sharpening.radius, pedited->sharpening.radius);
assignFromKeyfile(keyFile, "Sharpening", "BlurRadius", pedited, sharpening.blurradius, pedited->sharpening.blurradius);
assignFromKeyfile(keyFile, "Sharpening", "Amount", pedited, sharpening.amount, pedited->sharpening.amount);
if (keyFile.has_key("Sharpening", "Threshold")) {

View File

@@ -493,6 +493,7 @@ struct ColorToningParams {
struct SharpeningParams {
bool enabled;
double contrast;
double blurradius;
double radius;
int amount;
Threshold<int> threshold;

View File

@@ -1427,5 +1427,21 @@ static INLINE void vconvertrgbrgbrgbrgb2rrrrggggbbbb (const float * src, vfloat
bv = _mm_setr_ps(src[2],src[5],src[8],src[11]);
}
#if defined( __SSE4_1__ ) && defined( __x86_64__ )
static INLINE vfloat vceilf(vfloat x) {
return _mm_round_ps(x, _MM_FROUND_TO_POS_INF |_MM_FROUND_NO_EXC);
}
#else
static INLINE vfloat vceilf(vfloat x) {
__m128i zerov = _mm_setzero_si128();
zerov = _mm_cmpeq_epi32(zerov, zerov);
const vfloat onev = (vfloat)_mm_slli_epi32(_mm_srli_epi32(zerov, 25), 23); //create vector 1.0f
const vfloat xi = _mm_cvtepi32_ps(_mm_cvttps_epi32(x));
return xi + _mm_and_ps(_mm_cmplt_ps(xi, x), onev);
}
#endif
#endif // __SSE2__
#endif // SLEEFSSEAVX

View File

@@ -960,59 +960,62 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab)
#undef CLIP
void RawImageSource::fast_xtrans_interpolate (const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue)
{
// if (settings->verbose) {
// printf("fast X-Trans interpolation...\n");
// }
double progress = 0.0;
const bool plistenerActive = plistener;
if (plistenerActive) {
if (plistener) {
plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans"));
plistener->setProgress (progress);
plistener->setProgress(0.0);
}
const int height = H, width = W;
xtransborder_interpolate(1, red, green, blue);
int xtrans[6][6];
ri->getXtransMatrix(xtrans);
#pragma omp parallel for
for(int row = 1; row < height - 1; row++) {
for(int col = 1; col < width - 1; col++) {
float sum[3] = {0.f};
const float weight[3][3] = {
{0.25f, 0.5f, 0.25f},
{0.5f, 0.f, 0.5f},
{0.25f, 0.5f, 0.25f}
};
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic, 16)
#endif
for (int row = 1; row < H - 1; ++row) {
for (int col = 1; col < W - 1; ++col) {
float sum[3] = {};
for (int v = -1; v <= 1; v++) {
for (int h = -1; h <= 1; h++) {
sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)];
sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)] * weight[v + 1][h + 1];
}
}
switch(fcol(row, col)) {
case 0:
case 0: // red pixel
red[row][col] = rawData[row][col];
green[row][col] = sum[1] * 0.2f;
blue[row][col] = sum[2] * 0.33333333f;
green[row][col] = sum[1] * 0.5f;
blue[row][col] = sum[2];
break;
case 1:
red[row][col] = sum[0] * 0.5f;
case 1: // green pixel
green[row][col] = rawData[row][col];
blue[row][col] = sum[2] * 0.5f;
if (fcol(row, col - 1) == fcol(row, col + 1)) { // Solitary green pixel always has exactly two direct red and blue neighbors in 3x3 grid
red[row][col] = sum[0];
blue[row][col] = sum[2];
} else { // Non solitary green pixel always has one direct and one diagonal red and blue neighbor in 3x3 grid
red[row][col] = sum[0] * 1.3333333f;
blue[row][col] = sum[2] * 1.3333333f;
}
break;
case 2:
red[row][col] = sum[0] * 0.33333333f;
green[row][col] = sum[1] * 0.2f;
case 2: // blue pixel
red[row][col] = sum[0];
green[row][col] = sum[1] * 0.5f;
blue[row][col] = rawData[row][col];
break;
}
}
}
if (plistenerActive) {
if (plistener) {
plistener->setProgress (1.0);
}
}

View File

@@ -1083,6 +1083,10 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
history->resetSnapShotNumber();
navigator->setInvalid(ipc->getFullWidth(),ipc->getFullHeight());
// When passing a photo as an argument to the RawTherapee executable, the user wants
// this auto-loaded photo's thumbnail to be selected and visible in the Filmstrip.
EditorPanel::syncFileBrowser();
}
void EditorPanel::close ()

View File

@@ -580,7 +580,7 @@ int main (int argc, char **argv)
bool Console = true;
for (int i = 1; i < argc; i++)
if (!strcmp (argv[i], "-w") || !strcmp (argv[i], "-R")) {
if (!strcmp (argv[i], "-w") || !strcmp (argv[i], "-R") || !strcmp (argv[i], "-gimp")) {
Console = false;
break;
}

View File

@@ -147,6 +147,7 @@ void ParamsEdited::set(bool v)
sharpening.enabled = v;
sharpening.contrast = v;
sharpening.radius = v;
sharpening.blurradius = v;
sharpening.amount = v;
sharpening.threshold = v;
sharpening.edgesonly = v;
@@ -719,6 +720,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
sharpening.enabled = sharpening.enabled && p.sharpening.enabled == other.sharpening.enabled;
sharpening.contrast = sharpening.contrast && p.sharpening.contrast == other.sharpening.contrast;
sharpening.radius = sharpening.radius && p.sharpening.radius == other.sharpening.radius;
sharpening.blurradius = sharpening.blurradius && p.sharpening.blurradius == other.sharpening.blurradius;
sharpening.amount = sharpening.amount && p.sharpening.amount == other.sharpening.amount;
sharpening.threshold = sharpening.threshold && p.sharpening.threshold == other.sharpening.threshold;
sharpening.edgesonly = sharpening.edgesonly && p.sharpening.edgesonly == other.sharpening.edgesonly;
@@ -1639,6 +1641,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.sharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.radius + mods.sharpening.radius : mods.sharpening.radius;
}
if (sharpening.blurradius) {
toEdit.sharpening.blurradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.blurradius + mods.sharpening.blurradius : mods.sharpening.blurradius;
}
if (sharpening.amount) {
toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount;
}

View File

@@ -209,6 +209,7 @@ class SharpeningParamsEdited
public:
bool enabled;
bool contrast;
bool blurradius;
bool radius;
bool amount;
bool threshold;

View File

@@ -27,6 +27,7 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI
{
auto m = ProcEventMapper::getInstance();
EvSharpenContrast = m->newEvent(SHARPENING, "HISTORY_MSG_SHARPENING_CONTRAST");
EvSharpenBlur = m->newEvent(SHARPENING, "HISTORY_MSG_SHARPENING_BLUR");
Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
hb->show ();
@@ -34,6 +35,10 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI
contrast->setAdjusterListener (this);
pack_start(*contrast);
contrast->show();
blur = Gtk::manage(new Adjuster (M("TP_SHARPENING_BLUR"), 0.2, 2.0, 0.05, 0.2));
blur->setAdjusterListener (this);
pack_start(*blur);
blur->show();
Gtk::Label* ml = Gtk::manage (new Gtk::Label (M("TP_SHARPENING_METHOD") + ":"));
ml->show ();
@@ -153,6 +158,7 @@ void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited)
if (pedited) {
contrast->setEditedState (pedited->sharpening.contrast ? Edited : UnEdited);
blur->setEditedState (pedited->sharpening.blurradius ? Edited : UnEdited);
amount->setEditedState (pedited->sharpening.amount ? Edited : UnEdited);
radius->setEditedState (pedited->sharpening.radius ? Edited : UnEdited);
threshold->setEditedState (pedited->sharpening.threshold ? Edited : UnEdited);
@@ -182,6 +188,7 @@ void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited)
lastHaloControl = pp->sharpening.halocontrol;
contrast->setValue (pp->sharpening.contrast);
blur->setValue (pp->sharpening.blurradius);
amount->setValue (pp->sharpening.amount);
radius->setValue (pp->sharpening.radius);
threshold->setValue<int>(pp->sharpening.threshold);
@@ -224,6 +231,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited)
{
pp->sharpening.contrast = contrast->getValue ();
pp->sharpening.blurradius = blur->getValue ();
pp->sharpening.amount = (int)amount->getValue();
pp->sharpening.enabled = getEnabled ();
pp->sharpening.radius = radius->getValue ();
@@ -246,6 +254,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited)
if (pedited) {
pedited->sharpening.contrast = contrast->getEditedState ();
pedited->sharpening.blurradius = blur->getEditedState ();
pedited->sharpening.amount = amount->getEditedState ();
pedited->sharpening.radius = radius->getEditedState ();
pedited->sharpening.threshold = threshold->getEditedState ();
@@ -266,6 +275,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited)
void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited)
{
contrast->setDefault (defParams->sharpening.contrast);
blur->setDefault (defParams->sharpening.blurradius);
amount->setDefault (defParams->sharpening.amount);
radius->setDefault (defParams->sharpening.radius);
threshold->setDefault<int> (defParams->sharpening.threshold);
@@ -279,6 +289,7 @@ void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* p
if (pedited) {
contrast->setDefaultEditedState (pedited->sharpening.contrast ? Edited : UnEdited);
blur->setDefaultEditedState (pedited->sharpening.blurradius ? Edited : UnEdited);
amount->setDefaultEditedState (pedited->sharpening.amount ? Edited : UnEdited);
radius->setDefaultEditedState (pedited->sharpening.radius ? Edited : UnEdited);
threshold->setDefaultEditedState (pedited->sharpening.threshold ? Edited : UnEdited);
@@ -291,6 +302,7 @@ void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* p
ddamping->setDefaultEditedState (pedited->sharpening.deconvdamping ? Edited : UnEdited);
} else {
contrast->setDefaultEditedState (Irrelevant);
blur->setDefaultEditedState (Irrelevant);
amount->setDefaultEditedState (Irrelevant);
radius->setDefaultEditedState (Irrelevant);
threshold->setDefaultEditedState (Irrelevant);
@@ -310,7 +322,7 @@ void Sharpening::adjusterChanged(Adjuster* a, double newval)
Glib::ustring costr;
if (a == radius || a == dradius) {
if (a == radius || a == dradius || a == blur) {
costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue());
} else if (a == eradius) {
costr = Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue());
@@ -324,6 +336,8 @@ void Sharpening::adjusterChanged(Adjuster* a, double newval)
listener->panelChanged (EvShrAmount, costr);
} else if (a == radius) {
listener->panelChanged (EvShrRadius, costr);
} else if (a == blur) {
listener->panelChanged (EvSharpenBlur, costr);
} else if (a == eradius) {
listener->panelChanged (EvShrEdgeRadius, costr);
} else if (a == etolerance) {
@@ -487,6 +501,7 @@ void Sharpening::setBatchMode (bool batchMode)
pack_start (*rld);
contrast->showEditedCB ();
blur->showEditedCB ();
radius->showEditedCB ();
amount->showEditedCB ();
threshold->showEditedCB ();
@@ -518,6 +533,7 @@ void Sharpening::setAdjusterBehavior (bool contrastadd, bool radiusadd, bool amo
void Sharpening::trimValues (rtengine::procparams::ProcParams* pp)
{
contrast->trimValue(pp->sharpening.contrast);
blur->trimValue(pp->sharpening.blurradius);
radius->trimValue(pp->sharpening.radius);
dradius->trimValue(pp->sharpening.deconvradius);
amount->trimValue(pp->sharpening.amount);

View File

@@ -29,6 +29,7 @@ class Sharpening : public ToolParamBlock, public ThresholdAdjusterListener, publ
protected:
Adjuster* contrast;
Adjuster* blur;
MyComboBoxText* method;
Adjuster* dradius;
Adjuster* damount;
@@ -55,6 +56,7 @@ protected:
sigc::connection hcConn;
rtengine::ProcEvent EvSharpenContrast;
rtengine::ProcEvent EvSharpenBlur;
public:
Sharpening ();