From 8af91ce74c971185e2b7e84060158625dd38dba0 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 30 Jan 2018 10:06:20 +0100 Subject: [PATCH 01/12] faster histogram matching by using the processing pipeline in the thumbnail --- rtengine/histmatching.cc | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 56fe21d80..1870d3180 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -208,26 +208,35 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) PreviewProps pp(cx, cy, fw, fh, skip); ColorTemp currWB = getWB(); - std::unique_ptr image(new Imagefloat(int(fw / skip), int(fh / skip))); { - RawImageSource rsrc; - rsrc.load(getFileName()); - rsrc.preprocess(neutral.raw, neutral.lensProf, neutral.coarse, false); - rsrc.demosaic(neutral.raw); - rsrc.getImage(currWB, TR_NONE, image.get(), pp, neutral.toneCurve, neutral.raw); + RawMetaDataLocation rml; + eSensorType sensor_type; + double scale; + int w = fw / skip, h = fh / skip; + std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, false)); + target.reset(thumb->processImage(neutral, sensor_type, fh / skip, TI_Nearest, getMetaData(), scale, false)); } + + // std::unique_ptr image(new Imagefloat(int(fw / skip), int(fh / skip))); + // { + // RawImageSource rsrc; + // rsrc.load(getFileName()); + // rsrc.preprocess(neutral.raw, neutral.lensProf, neutral.coarse, false); + // rsrc.demosaic(neutral.raw); + // rsrc.getImage(currWB, TR_NONE, image.get(), pp, neutral.toneCurve, neutral.raw); + // } // this could probably be made faster -- ideally we would need to just // perform the transformation from camera space to the output space // (taking gamma into account), but I couldn't find anything // ready-made, so for now this will do. Remember the famous quote: // "premature optimization is the root of all evil" :-) - convertColorSpace(image.get(), neutral.icm, currWB); - ImProcFunctions ipf(&neutral); - LabImage tmplab(image->getWidth(), image->getHeight()); - ipf.rgb2lab(*image, tmplab, neutral.icm.working); - image.reset(ipf.lab2rgbOut(&tmplab, 0, 0, tmplab.W, tmplab.H, neutral.icm)); - target.reset(image->to8()); + // convertColorSpace(image.get(), neutral.icm, currWB); + // ImProcFunctions ipf(&neutral); + // LabImage tmplab(image->getWidth(), image->getHeight()); + // ipf.rgb2lab(*image, tmplab, neutral.icm.working); + // image.reset(ipf.lab2rgbOut(&tmplab, 0, 0, tmplab.W, tmplab.H, neutral.icm)); + // target.reset(image->to8()); if (settings->verbose) { std::cout << "histogram matching: generated neutral rendering" << std::endl; From 71a3af0c86a50e78cffce57be653a7d6d3c972c8 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 30 Jan 2018 10:06:57 +0100 Subject: [PATCH 02/12] improve generated curve in histogram matching on underexposed pictures --- rtengine/histmatching.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 1870d3180..6728e70ee 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -120,6 +120,15 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) curve.pop_back(); curve.pop_back(); } + // remove the plateau at the end (if any) + size_t j = curve.size() / 2; + for (; j > 1; --j) { + if (std::abs(curve[2*(j-1)-1] - curve.back()) > 0.01) { + break; + } + } + curve.resize(2*j); + curve.push_back(1.0); curve.push_back(1.0); From 5effd15bb3663363c1498247d8436d746975d74e Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 30 Jan 2018 10:24:19 +0100 Subject: [PATCH 03/12] histmatching: fix cropping of the target (broken by recent refactoring) --- rtengine/histmatching.cc | 67 +++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 6728e70ee..9128aa75e 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -194,58 +194,47 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) std::unique_ptr target; { - int tw = source->getWidth(), th = source->getHeight(); - float thumb_ratio = float(std::max(tw, th)) / float(std::min(tw, th)); - float target_ratio = float(std::max(fw, fh)) / float(std::min(fw, fh)); + RawMetaDataLocation rml; + eSensorType sensor_type; + double scale; + int w = fw / skip, h = fh / skip; + std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, false)); + target.reset(thumb->processImage(neutral, sensor_type, fh / skip, TI_Nearest, getMetaData(), scale, false)); + + int sw = source->getWidth(), sh = source->getHeight(); + int tw = target->getWidth(), th = target->getHeight(); + float thumb_ratio = float(std::max(sw, sh)) / float(std::min(sw, sh)); + float target_ratio = float(std::max(tw, th)) / float(std::min(tw, th)); int cx = 0, cy = 0; if (std::abs(thumb_ratio - target_ratio) > 0.01) { if (thumb_ratio > target_ratio) { // crop the height - int ch = fh - (fw * float(th) / float(tw)); + int ch = th - (tw * float(sh) / float(sw)); cy += ch / 2; - fh -= ch; + th -= ch; } else { // crop the width - int cw = fw - (fh * float(tw) / float(th)); + int cw = tw - (th * float(sw) / float(sh)); cx += cw / 2; - fw -= cw; + tw -= cw; } if (settings->verbose) { - std::cout << "histogram matching: cropping target to get an aspect ratio of " << std::fixed << std::setprecision(2) << thumb_ratio << ":1, new full size is " << fw << "x" << fh << std::endl; + std::cout << "histogram matching: cropping target to get an aspect ratio of " << std::fixed << std::setprecision(2) << thumb_ratio << ":1, new size is " << tw << "x" << th << std::endl; } - } - PreviewProps pp(cx, cy, fw, fh, skip); - ColorTemp currWB = getWB(); - { - RawMetaDataLocation rml; - eSensorType sensor_type; - double scale; - int w = fw / skip, h = fh / skip; - std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, false)); - target.reset(thumb->processImage(neutral, sensor_type, fh / skip, TI_Nearest, getMetaData(), scale, false)); + Image8 *tmp = new Image8(tw, th); +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < th; ++y) { + for (int x = 0; x < tw; ++x) { + tmp->r(y, x) = target->r(y+cy, x+cx); + tmp->g(y, x) = target->g(y+cy, x+cx); + tmp->b(y, x) = target->b(y+cy, x+cx); + } + } + target.reset(tmp); } - - // std::unique_ptr image(new Imagefloat(int(fw / skip), int(fh / skip))); - // { - // RawImageSource rsrc; - // rsrc.load(getFileName()); - // rsrc.preprocess(neutral.raw, neutral.lensProf, neutral.coarse, false); - // rsrc.demosaic(neutral.raw); - // rsrc.getImage(currWB, TR_NONE, image.get(), pp, neutral.toneCurve, neutral.raw); - // } - - // this could probably be made faster -- ideally we would need to just - // perform the transformation from camera space to the output space - // (taking gamma into account), but I couldn't find anything - // ready-made, so for now this will do. Remember the famous quote: - // "premature optimization is the root of all evil" :-) - // convertColorSpace(image.get(), neutral.icm, currWB); - // ImProcFunctions ipf(&neutral); - // LabImage tmplab(image->getWidth(), image->getHeight()); - // ipf.rgb2lab(*image, tmplab, neutral.icm.working); - // image.reset(ipf.lab2rgbOut(&tmplab, 0, 0, tmplab.W, tmplab.H, neutral.icm)); - // target.reset(image->to8()); if (settings->verbose) { std::cout << "histogram matching: generated neutral rendering" << std::endl; From ffbd97960f3f2eb4903cb45771dfad4dc19e7dd4 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 30 Jan 2018 10:47:18 +0100 Subject: [PATCH 04/12] histmatching: make sure we use an sRGB profile for generating the target rendering --- rtengine/histmatching.cc | 1 + rtengine/improcfun.h | 2 +- rtengine/iplab2rgb.cc | 4 ++-- rtengine/rtthumbnail.cc | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 9128aa75e..87eb672c8 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -171,6 +171,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) ProcParams neutral; neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST); neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST); + neutral.icm.output = "sRGB"; std::unique_ptr source; { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 83ffc12d6..8204516fd 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -348,7 +348,7 @@ public: void localContrast(LabImage *lab); void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); - Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm); + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool consider_histogram_settings=true); Imagefloat* lab2rgbOut (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, GammaValues *ga = nullptr); // CieImage *ciec; diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index ba2fe6ffb..27d9982fb 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -122,7 +122,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) // // If output profile used, divide by 327.68 then apply the "profile" profile (eventually with a standard gamma) // otherwise divide by 327.68, convert to xyz and apply the RGB transform, before converting with gamma2curve -Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm) +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool consider_histogram_settings) { //gamutmap(lab); @@ -147,7 +147,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, bool standard_gamma; - if(settings->HistogramWorking) { + if(settings->HistogramWorking && consider_histogram_settings) { profile = icm.working; standard_gamma = true; } else { diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 1a8d18897..2dcb6b9e0 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -137,6 +137,7 @@ extern Options options; namespace rtengine { + using namespace procparams; Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode) @@ -1303,7 +1304,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT readyImg = new Image8 (fw, fh); ipf.lab2monitorRgb (labView, readyImg); } else { - readyImg = ipf.lab2rgb(labView, 0, 0, fw, fh, params.icm); + readyImg = ipf.lab2rgb(labView, 0, 0, fw, fh, params.icm, false); } delete labView; delete baseImg; From c04150be35bbbc4591944593d438ed39ea4bca0c Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 30 Jan 2018 15:27:56 +0100 Subject: [PATCH 05/12] histmatching: slightly improved match for the shadows part of the tone curve --- rtengine/histmatching.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 87eb672c8..60cbda287 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -86,12 +86,19 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) curve.clear(); const int npoints = 8; - int idx = 1; + int idx = 15; for (; idx < int(mapping.size()); ++idx) { if (mapping[idx] >= idx) { break; } } + if (idx == int(mapping.size())) { + for (idx = 1; idx < int(mapping.size()); ++idx) { + if (mapping[idx] >= idx) { + break; + } + } + } int step = max(int(mapping.size())/npoints, 1); auto coord = [](int v) -> double { return double(v)/255.0; }; From fdde31839d954f1b89cad8aba7467da839727825 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 31 Jan 2018 08:29:19 +0100 Subject: [PATCH 06/12] incorporated Floessie's feedback --- rtengine/histmatching.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 60cbda287..33ef70c58 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -28,7 +28,6 @@ #include "improcfun.h" #include "StopWatch.h" #include -#include namespace rtengine { @@ -99,7 +98,7 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) } } } - int step = max(int(mapping.size())/npoints, 1); + int step = std::max(int(mapping.size())/npoints, 1); auto coord = [](int v) -> double { return double(v)/255.0; }; auto doit = @@ -207,6 +206,13 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) double scale; int w = fw / skip, h = fh / skip; std::unique_ptr thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, false)); + if (!thumb) { + if (settings->verbose) { + std::cout << "histogram matching: raw decoding failed, generating a neutral curve" << std::endl; + } + histMatchingCache = outCurve; + return; + } target.reset(thumb->processImage(neutral, sensor_type, fh / skip, TI_Nearest, getMetaData(), scale, false)); int sw = source->getWidth(), sh = source->getHeight(); @@ -227,7 +233,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) tw -= cw; } if (settings->verbose) { - std::cout << "histogram matching: cropping target to get an aspect ratio of " << std::fixed << std::setprecision(2) << thumb_ratio << ":1, new size is " << tw << "x" << th << std::endl; + std::cout << "histogram matching: cropping target to get an aspect ratio of " << round(thumb_ratio * 100)/100.0 << ":1, new size is " << tw << "x" << th << std::endl; } Image8 *tmp = new Image8(tw, th); From 79324ed5d017bea74eeb85436c61284d87bd4dd6 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 31 Jan 2018 10:34:50 +0100 Subject: [PATCH 07/12] more fine-tuning of the histogram matching make sure we do not place curve points in regions of the histogram that are outside the dynamic range of the input images -- that would be wild guessing, better to just leave this to the spline interpolation --- rtengine/histmatching.cc | 69 +++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index 33ef70c58..b17eff5f5 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -36,20 +36,36 @@ extern const Settings *settings; namespace { -std::vector getCdf(const IImage8 &img) +struct CdfInfo { + std::vector cdf; + int min_val; + int max_val; + + CdfInfo(): cdf(256), min_val(-1), max_val(-1) {} +}; + + +CdfInfo getCdf(const IImage8 &img) { - std::vector ret(256); + CdfInfo ret; + for (int y = 0; y < img.getHeight(); ++y) { for (int x = 0; x < img.getWidth(); ++x) { int lum = LIM(0, int(Color::rgbLuminance(float(img.r(y, x)), float(img.g(y, x)), float(img.b(y, x)))), 255); - ++ret[lum]; + ++ret.cdf[lum]; } } int sum = 0; - for (size_t i = 0; i < ret.size(); ++i) { - sum += ret[i]; - ret[i] = sum; + for (size_t i = 0; i < ret.cdf.size(); ++i) { + if (ret.cdf[i] > 0) { + if (ret.min_val < 0) { + ret.min_val = i; + } + ret.max_val = i; + } + sum += ret.cdf[i]; + ret.cdf[i] = sum; } return ret; @@ -105,12 +121,15 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) [&](int start, int stop, int step, bool addstart) -> void { int prev = start; - if (addstart) { + if (addstart && mapping[start] >= 0) { curve.push_back(coord(start)); curve.push_back(coord(mapping[start])); } for (int i = start; i < stop; ++i) { int v = mapping[i]; + if (v < 0) { + continue; + } bool change = i > 0 && v != mapping[i-1]; int diff = i - prev; if ((change && std::abs(diff - step) <= 1) || diff > step * 2) { @@ -120,20 +139,22 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) } } }; - doit(0, idx, idx > step ? step : idx / 2, true); - doit(idx, int(mapping.size()), step, idx - step > step / 2); + + curve.push_back(0.0); + curve.push_back(0.0); + + int start = 0; + while (start < idx && (mapping[start] < 0 || start < idx / 2)) { + ++start; + } + + doit(start, idx, idx > step ? step : idx / 2, true); + doit(idx, int(mapping.size()), step, idx - step > step / 2 && std::abs(curve[curve.size()-2] - coord(idx)) > 0.01); + if (curve.size() > 2 && (1 - curve[curve.size()-2] <= step / (256.0 * 3))) { curve.pop_back(); curve.pop_back(); } - // remove the plateau at the end (if any) - size_t j = curve.size() / 2; - for (; j > 1; --j) { - if (std::abs(curve[2*(j-1)-1] - curve.back()) > 0.01) { - break; - } - } - curve.resize(2*j); curve.push_back(1.0); curve.push_back(1.0); @@ -259,14 +280,18 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) target->resizeImgTo(source->getWidth(), source->getHeight(), TI_Nearest, tmp); target.reset(tmp); } - std::vector scdf = getCdf(*source); - std::vector tcdf = getCdf(*target); + CdfInfo scdf = getCdf(*source); + CdfInfo tcdf = getCdf(*target); std::vector mapping; int j = 0; - for (size_t i = 0; i < tcdf.size(); ++i) { - j = findMatch(tcdf[i], scdf, j); - mapping.push_back(j); + for (int i = 0; i < int(tcdf.cdf.size()); ++i) { + j = findMatch(tcdf.cdf[i], scdf.cdf, j); + if (i >= tcdf.min_val && i <= tcdf.max_val && j >= scdf.min_val && j <= scdf.max_val) { + mapping.push_back(j); + } else { + mapping.push_back(-1); + } } mappingToCurve(mapping, outCurve); From 34bd19f4bfb25ec52df785e55feabca9dd817124 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 31 Jan 2018 15:17:23 +0100 Subject: [PATCH 08/12] Updated mime-types --- rtdata/icons/mime-types | 11 +++++++---- rtdata/icons/rawtherapee.desktop.in | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/rtdata/icons/mime-types b/rtdata/icons/mime-types index c232119ee..505b00140 100644 --- a/rtdata/icons/mime-types +++ b/rtdata/icons/mime-types @@ -9,10 +9,14 @@ image/x-canon-cr2; image/x-canon-crf; image/x-canon-crw; image/x-fuji-raf; +image/x-hasselblad-3fr; +image/x-hasselblad-fff; image/x-jpg; image/x-kodak-dcr; image/x-kodak-k25; image/x-kodak-kdc; +image/x-leaf-mos; +image/x-leica-rwl; image/x-mamiya-mef; image/x-minolta-mrw; image/x-nikon-nef; @@ -22,15 +26,14 @@ image/x-panasonic-raw; image/x-panasonic-rw2; image/x-pentax-pef; image/x-pentax-raw; +image/x-phaseone-iiq; image/x-raw; image/x-rwz; image/x-samsung-srw; +image/x-sigma-x3f; +image/x-sony-arq; image/x-sony-arw; image/x-sony-sr2; image/x-sony-srf; -image/x-hasselblad-3fr; -image/x-hasselblad-fff; -image/x-leaf-mos; -image/x-phaseone-iiq; image/x-tif; inode/directory; diff --git a/rtdata/icons/rawtherapee.desktop.in b/rtdata/icons/rawtherapee.desktop.in index a573f19d3..c3d26c980 100644 --- a/rtdata/icons/rawtherapee.desktop.in +++ b/rtdata/icons/rawtherapee.desktop.in @@ -13,6 +13,6 @@ Comment[pl]=Zaawansowany program do wywoływania zdjęć typu raw Icon=rawtherapee Exec=rawtherapee %f Terminal=false -MimeType=image/jpeg;image/png;image/tiff;image/x-adobe-dng;image/x-canon-cr2;image/x-canon-crf;image/x-canon-crw;image/x-fuji-raf;image/x-jpg;image/x-kodak-dcr;image/x-kodak-k25;image/x-kodak-kdc;image/x-mamiya-mef;image/x-minolta-mrw;image/x-nikon-nef;image/x-nikon-nrw;image/x-olympus-orf;image/x-panasonic-raw;image/x-panasonic-rw2;image/x-pentax-pef;image/x-pentax-raw;image/x-raw;image/x-rwz;image/x-samsung-srw;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-hasselblad-3fr;image/x-hasselblad-fff;image/x-leaf-mos;image/x-phaseone-iiq;image/x-tif; +MimeType=image/jpeg;image/png;image/tiff;image/x-adobe-dng;image/x-canon-cr2;image/x-canon-crf;image/x-canon-crw;image/x-fuji-raf;image/x-hasselblad-3fr;image/x-hasselblad-fff;image/x-jpg;image/x-kodak-dcr;image/x-kodak-k25;image/x-kodak-kdc;image/x-leaf-mos;image/x-leica-rwl;image/x-mamiya-mef;image/x-minolta-mrw;image/x-nikon-nef;image/x-nikon-nrw;image/x-olympus-orf;image/x-panasonic-raw;image/x-panasonic-rw2;image/x-pentax-pef;image/x-pentax-raw;image/x-phaseone-iiq;image/x-raw;image/x-rwz;image/x-samsung-srw;image/x-sigma-x3f;image/x-sony-arq;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-tif; Categories=Photography;Graphics;2DGraphics;RasterGraphics;GTK; Keywords=raw;photography;develop;pp3;graphics; From b09aeaa6ae9552dada335b4d049a382f70c730ad Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 31 Jan 2018 17:06:39 +0100 Subject: [PATCH 09/12] avoid one useless copy if no cropping is required --- rtengine/histmatching.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index b17eff5f5..e496f6f82 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -257,18 +257,20 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) std::cout << "histogram matching: cropping target to get an aspect ratio of " << round(thumb_ratio * 100)/100.0 << ":1, new size is " << tw << "x" << th << std::endl; } - Image8 *tmp = new Image8(tw, th); + if (cx || cy) { + Image8 *tmp = new Image8(tw, th); #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int y = 0; y < th; ++y) { - for (int x = 0; x < tw; ++x) { - tmp->r(y, x) = target->r(y+cy, x+cx); - tmp->g(y, x) = target->g(y+cy, x+cx); - tmp->b(y, x) = target->b(y+cy, x+cx); + for (int y = 0; y < th; ++y) { + for (int x = 0; x < tw; ++x) { + tmp->r(y, x) = target->r(y+cy, x+cx); + tmp->g(y, x) = target->g(y+cy, x+cx); + tmp->b(y, x) = target->b(y+cy, x+cx); + } } + target.reset(tmp); } - target.reset(tmp); } if (settings->verbose) { From 74e31dff45293ca5e8ce3fe22c1d870eca290b65 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 31 Jan 2018 18:09:28 +0100 Subject: [PATCH 10/12] histmatching: dynamically adjust the skip factor according to the side of the embedded thumbnail with large the embedded thumbnails we should skip less to improve the quality of the matching --- rtengine/histmatching.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index e496f6f82..e326a3f7d 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -189,7 +189,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) int fw, fh; getFullSize(fw, fh, TR_NONE); - int skip = 10; + int skip = 3; if (settings->verbose) { std::cout << "histogram matching: full raw image size is " << fw << "x" << fh << std::endl; @@ -213,6 +213,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) histMatchingCache = outCurve; return; } + skip = LIM(5, skip * fh / h, 10); // adjust the skip factor -- the larger the thumbnail, the less we should skip to get a good match source.reset(thumb->quickProcessImage(neutral, fh / skip, TI_Nearest)); if (settings->verbose) { From 7dd598d9b7acc3b52a867351aa36e3d9d077a956 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 31 Jan 2018 21:24:56 +0100 Subject: [PATCH 11/12] bug fixes by heckflosse --- rtengine/histmatching.cc | 2 +- rtengine/rtthumbnail.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index e326a3f7d..aaeada81a 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -213,7 +213,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) histMatchingCache = outCurve; return; } - skip = LIM(5, skip * fh / h, 10); // adjust the skip factor -- the larger the thumbnail, the less we should skip to get a good match + skip = LIM(skip * fh / h, 6, 10); // adjust the skip factor -- the larger the thumbnail, the less we should skip to get a good match source.reset(thumb->quickProcessImage(neutral, fh / skip, TI_Nearest)); if (settings->verbose) { diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 2dcb6b9e0..5318c5eaa 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -466,8 +466,8 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati skip--; } - if (skip < 1) { - skip = 1; + if (skip < 2) { + skip = 2; } int hskip = skip, vskip = skip; From adb13928391c2af2bc9f1e7a58cabd93a3112684 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 31 Jan 2018 21:34:10 +0100 Subject: [PATCH 12/12] renamed formal parameters of LIM from (a, b, c) to (val, low, high) --- rtengine/rt_math.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h index 787e2e63f..ca93619ee 100644 --- a/rtengine/rt_math.h +++ b/rtengine/rt_math.h @@ -74,9 +74,9 @@ constexpr const T& max(const T& a, const T& b, const ARGS&... args) } template -constexpr const T& LIM(const T& a, const T& b, const T& c) +constexpr const T& LIM(const T& val, const T& low, const T& high) { - return max(b, min(a, c)); + return max(low, min(val, high)); } template