Merge branch 'dev' into spot-removal-tool
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "procparams.h"
|
||||
#include "tweakoperator.h"
|
||||
#include "refreshmap.h"
|
||||
#include "guidedfilter.h"
|
||||
|
||||
#include "../rtgui/options.h"
|
||||
|
||||
@@ -44,6 +45,22 @@
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
using rtengine::Coord2D;
|
||||
Coord2D translateCoord(const rtengine::ImProcFunctions& ipf, int fw, int fh, int x, int y) {
|
||||
|
||||
const std::vector<Coord2D> points = {Coord2D(x, y)};
|
||||
|
||||
std::vector<Coord2D> red;
|
||||
std::vector<Coord2D> green;
|
||||
std::vector<Coord2D> blue;
|
||||
ipf.transCoord(fw, fh, points, red, green, blue);
|
||||
|
||||
return green[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace rtengine
|
||||
{
|
||||
@@ -57,11 +74,12 @@ ImProcCoordinator::ImProcCoordinator() :
|
||||
fattal_11_dcrop_cache(nullptr),
|
||||
previmg(nullptr),
|
||||
workimg(nullptr),
|
||||
ncie (nullptr),
|
||||
imgsrc (nullptr),
|
||||
lastAwbEqual (0.),
|
||||
lastAwbTempBias (0.0),
|
||||
monitorIntent (RI_RELATIVE),
|
||||
ncie(nullptr),
|
||||
imgsrc(nullptr),
|
||||
lastAwbEqual(0.),
|
||||
lastAwbTempBias(0.0),
|
||||
lastAwbauto(""),
|
||||
monitorIntent(RI_RELATIVE),
|
||||
softProof(false),
|
||||
gamutCheck(false),
|
||||
sharpMask(false),
|
||||
@@ -197,12 +215,12 @@ ImProcCoordinator::~ImProcCoordinator()
|
||||
|
||||
imgsrc->decreaseRef();
|
||||
|
||||
if(customTransformIn) {
|
||||
if (customTransformIn) {
|
||||
cmsDeleteTransform(customTransformIn);
|
||||
customTransformIn = nullptr;
|
||||
}
|
||||
|
||||
if(customTransformOut) {
|
||||
if (customTransformOut) {
|
||||
cmsDeleteTransform(customTransformOut);
|
||||
customTransformOut = nullptr;
|
||||
}
|
||||
@@ -257,11 +275,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
MyMutex::MyLock processingLock(mProcessing);
|
||||
|
||||
bool highDetailNeeded = options.prevdemo == PD_Sidecar ? true : (todo & M_HIGHQUAL);
|
||||
// printf("metwb=%s \n", params->wb.method.c_str());
|
||||
|
||||
// Check if any detail crops need high detail. If not, take a fast path short cut
|
||||
if (!highDetailNeeded) {
|
||||
for (size_t i = 0; i < crops.size(); i++) {
|
||||
if (crops[i]->get_skip() == 1) { // skip=1 -> full resolution
|
||||
if (crops[i]->get_skip() == 1) { // skip=1 -> full resolution
|
||||
highDetailNeeded = true;
|
||||
break;
|
||||
}
|
||||
@@ -278,7 +297,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
RAWParams rp = params->raw;
|
||||
ColorManagementParams cmp = params->icm;
|
||||
LCurveParams lcur = params->labCurve;
|
||||
|
||||
|
||||
if (!highDetailNeeded) {
|
||||
// if below 100% magnification, take a fast path
|
||||
if (rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::NONE) && rp.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)) {
|
||||
@@ -305,9 +324,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
imgsrc->setCurrentFrame(params->raw.bayersensor.imageNum);
|
||||
|
||||
imgsrc->preprocess(rp, params->lensProf, params->coarse);
|
||||
|
||||
if (flatFieldAutoClipListener && rp.ff_AutoClipControl) {
|
||||
flatFieldAutoClipListener->flatFieldAutoClipValueChanged(imgsrc->getFlatFieldAutoClipValue());
|
||||
}
|
||||
|
||||
imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw);
|
||||
|
||||
highDetailPreprocessComputed = highDetailNeeded;
|
||||
@@ -321,7 +342,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
)
|
||||
&& params->filmNegative.enabled
|
||||
) {
|
||||
imgsrc->filmNegativeProcess(params->filmNegative);
|
||||
std::array<float, 3> filmBaseValues = {
|
||||
static_cast<float>(params->filmNegative.redBase),
|
||||
static_cast<float>(params->filmNegative.greenBase),
|
||||
static_cast<float>(params->filmNegative.blueBase)
|
||||
};
|
||||
imgsrc->filmNegativeProcess(params->filmNegative, filmBaseValues);
|
||||
if (filmNegListener && params->filmNegative.redBase <= 0.f) {
|
||||
filmNegListener->filmBaseValuesChanged(filmBaseValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,8 +382,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
printf("Demosaic X-Trans image with using method: %s\n", rp.xtranssensor.method.c_str());
|
||||
}
|
||||
}
|
||||
if(imgsrc->getSensorType() == ST_BAYER) {
|
||||
if(params->raw.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) {
|
||||
|
||||
if (imgsrc->getSensorType() == ST_BAYER) {
|
||||
if (params->raw.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) {
|
||||
imgsrc->setBorder(params->raw.bayersensor.border);
|
||||
} else {
|
||||
imgsrc->setBorder(std::max(params->raw.bayersensor.border, 2));
|
||||
@@ -362,6 +392,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
} else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) {
|
||||
imgsrc->setBorder(params->raw.xtranssensor.border);
|
||||
}
|
||||
|
||||
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicAutoContrast : params->raw.xtranssensor.dualDemosaicAutoContrast;
|
||||
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicContrast : params->raw.xtranssensor.dualDemosaicContrast;
|
||||
imgsrc->demosaic(rp, autoContrast, contrastThreshold, params->pdsharpening.enabled);
|
||||
@@ -369,7 +400,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) {
|
||||
bayerAutoContrastListener->autoContrastChanged(contrastThreshold);
|
||||
} else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) {
|
||||
xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0);
|
||||
|
||||
xtransAutoContrastListener->autoContrastChanged(contrastThreshold);
|
||||
}
|
||||
// if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag
|
||||
todo |= (M_INIT | M_CSHARP);
|
||||
@@ -407,6 +439,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
}
|
||||
}
|
||||
|
||||
if (todo & (M_INIT | M_LINDENOISE | M_HDR)) {
|
||||
if (params->wb.method == "autitcgreen") {
|
||||
imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw);
|
||||
}
|
||||
}
|
||||
|
||||
if ((todo & (M_RETINEX | M_INIT)) && params->retinex.enabled) {
|
||||
bool dehacontlutili = false;
|
||||
bool mapcontlutili = false;
|
||||
@@ -423,6 +461,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
}
|
||||
}
|
||||
|
||||
const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen");
|
||||
if (settings->verbose) {
|
||||
printf("automethod=%s \n", params->wb.method.c_str());
|
||||
}
|
||||
if (todo & (M_INIT | M_LINDENOISE | M_HDR)) {
|
||||
MyMutex::MyLock initLock(minit); // Also used in crop window
|
||||
|
||||
@@ -434,28 +476,53 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
}
|
||||
|
||||
currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method);
|
||||
float studgood = 1000.f;
|
||||
|
||||
if (!params->wb.enabled) {
|
||||
currWB = ColorTemp();
|
||||
} else if (params->wb.method == "Camera") {
|
||||
currWB = imgsrc->getWB();
|
||||
} else if (params->wb.method == "Auto") {
|
||||
if (lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias) {
|
||||
lastAwbauto = ""; //reinitialize auto
|
||||
} else if (autowb) {
|
||||
if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) {
|
||||
double rm, gm, bm;
|
||||
imgsrc->getAutoWBMultipliers(rm, gm, bm);
|
||||
double tempitc = 5000.f;
|
||||
double greenitc = 1.;
|
||||
currWBitc = imgsrc->getWB();
|
||||
double tempref = currWBitc.getTemp() * (1. + params->wb.tempBias);
|
||||
double greenref = currWBitc.getGreen();
|
||||
if (settings->verbose && params->wb.method == "autitcgreen") {
|
||||
printf("tempref=%f greref=%f\n", tempref, greenref);
|
||||
}
|
||||
|
||||
imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw);
|
||||
|
||||
if (params->wb.method == "autitcgreen") {
|
||||
params->wb.temperature = tempitc;
|
||||
params->wb.green = greenitc;
|
||||
currWB = ColorTemp(params->wb.temperature, params->wb.green, 1., params->wb.method);
|
||||
currWB.getMultipliers(rm, gm, bm);
|
||||
}
|
||||
|
||||
if (rm != -1.) {
|
||||
autoWB.update(rm, gm, bm, params->wb.equal, params->wb.tempBias);
|
||||
double bias = params->wb.tempBias;
|
||||
|
||||
if (params->wb.method == "autitcgreen") {
|
||||
bias = 0.;
|
||||
}
|
||||
|
||||
autoWB.update(rm, gm, bm, params->wb.equal, bias);
|
||||
lastAwbEqual = params->wb.equal;
|
||||
lastAwbTempBias = params->wb.tempBias;
|
||||
lastAwbauto = params->wb.method;
|
||||
} else {
|
||||
lastAwbEqual = -1.;
|
||||
lastAwbTempBias = 0.0;
|
||||
lastAwbauto = "";
|
||||
autoWB.useDefaults(params->wb.equal);
|
||||
}
|
||||
|
||||
//double rr,gg,bb;
|
||||
//autoWB.getMultipliers(rr,gg,bb);
|
||||
|
||||
|
||||
}
|
||||
|
||||
currWB = autoWB;
|
||||
@@ -466,9 +533,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
params->wb.green = currWB.getGreen();
|
||||
}
|
||||
|
||||
if (params->wb.method == "Auto" && awbListener && params->wb.enabled) {
|
||||
awbListener->WBChanged(params->wb.temperature, params->wb.green);
|
||||
}
|
||||
if (autowb && awbListener && params->wb.method == "autitcgreen") {
|
||||
awbListener->WBChanged(params->wb.temperature, params->wb.green, studgood);
|
||||
}
|
||||
|
||||
if (autowb && awbListener && params->wb.method == "autold") {
|
||||
awbListener->WBChanged(params->wb.temperature, params->wb.green, -1.f);
|
||||
}
|
||||
|
||||
/*
|
||||
GammaValues g_a;
|
||||
@@ -592,7 +663,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
}
|
||||
|
||||
// Remove transformation if unneeded
|
||||
bool needstransform = ipf.needsTransform();
|
||||
bool needstransform = ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData());
|
||||
|
||||
if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled))) {
|
||||
// Forking the image
|
||||
@@ -653,7 +724,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
}
|
||||
}
|
||||
|
||||
if (todo & (M_AUTOEXP | M_RGBCURVE)) {
|
||||
if (todo & (M_AUTOEXP | M_RGBCURVE)) {
|
||||
if (params->icm.workingTRC == "Custom") { //exec TRC IN free
|
||||
if (oprevi == orig_prev) {
|
||||
oprevi = new Imagefloat(pW, pH);
|
||||
@@ -665,17 +736,21 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1") {
|
||||
const int cw = oprevi->getWidth();
|
||||
const int ch = oprevi->getHeight();
|
||||
|
||||
// put gamma TRC to 1
|
||||
if(customTransformIn) {
|
||||
if (customTransformIn) {
|
||||
cmsDeleteTransform(customTransformIn);
|
||||
customTransformIn = nullptr;
|
||||
}
|
||||
|
||||
ipf.workingtrc(oprevi, oprevi, cw, ch, -5, params->icm.workingProfile, 2.4, 12.92310, customTransformIn, true, false, true);
|
||||
|
||||
//adjust TRC
|
||||
if(customTransformOut) {
|
||||
if (customTransformOut) {
|
||||
cmsDeleteTransform(customTransformOut);
|
||||
customTransformOut = nullptr;
|
||||
}
|
||||
|
||||
ipf.workingtrc(oprevi, oprevi, cw, ch, 5, params->icm.workingProfile, params->icm.workingTRCGamma, params->icm.workingTRCSlope, customTransformOut, false, true, true);
|
||||
}
|
||||
}
|
||||
@@ -683,7 +758,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
|
||||
|
||||
if ((todo & M_RGBCURVE) || (todo & M_CROP)) {
|
||||
// if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped);
|
||||
// if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped);
|
||||
|
||||
//complexCurve also calculated pre-curves histogram depending on crop
|
||||
CurveFactory::complexCurve(params->toneCurve.expcomp, params->toneCurve.black / 65535.0,
|
||||
@@ -777,12 +852,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
DCPProfileApplyState as;
|
||||
DCPProfile *dcpProf = imgsrc->getDCP(params->icm, as);
|
||||
|
||||
ipf.rgbProc (oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, params->toneCurve.saturation,
|
||||
ipf.rgbProc(oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, params->toneCurve.saturation,
|
||||
rCurve, gCurve, bCurve, colourToningSatLimit, colourToningSatLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, as, histToneCurve);
|
||||
|
||||
if (params->blackwhite.enabled && params->blackwhite.autoc && abwListener) {
|
||||
if (settings->verbose) {
|
||||
printf("ImProcCoordinator / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", bwAutoR, bwAutoG, bwAutoB);
|
||||
printf("ImProcCoordinator / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", static_cast<double>(bwAutoR), static_cast<double>(bwAutoG), static_cast<double>(bwAutoB));
|
||||
}
|
||||
|
||||
abwListener->BWChanged((float) rrm, (float) ggm, (float) bbm);
|
||||
@@ -862,17 +937,220 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
wavcontlutili = false;
|
||||
CurveFactory::curveWavContL(wavcontlutili, params->wavelet.wavclCurve, wavclCurve, scale == 1 ? 1 : 16);
|
||||
|
||||
|
||||
if ((params->wavelet.enabled)) {
|
||||
WaveletParams WaveParams = params->wavelet;
|
||||
WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
|
||||
|
||||
WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
|
||||
int kall = 0;
|
||||
ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
|
||||
LabImage *unshar = nullptr;
|
||||
Glib::ustring provis;
|
||||
LabImage *provradius = nullptr;
|
||||
bool procont = WaveParams.expcontrast;
|
||||
bool prochro = WaveParams.expchroma;
|
||||
bool proedge = WaveParams.expedge;
|
||||
bool profin = WaveParams.expfinal;
|
||||
bool proton = WaveParams.exptoning;
|
||||
bool pronois = WaveParams.expnoise;
|
||||
|
||||
if(WaveParams.showmask) {
|
||||
// WaveParams.showmask = false;
|
||||
// WaveParams.expclari = true;
|
||||
}
|
||||
|
||||
if (WaveParams.softrad > 0.f) {
|
||||
provradius = new LabImage(pW, pH);
|
||||
provradius->CopyFrom(nprevl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") {
|
||||
unshar = new LabImage(pW, pH);
|
||||
provis = params->wavelet.CLmethod;
|
||||
params->wavelet.CLmethod = "all";
|
||||
ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
|
||||
|
||||
unshar->CopyFrom(nprevl);
|
||||
|
||||
params->wavelet.CLmethod = provis;
|
||||
|
||||
WaveParams.expcontrast = false;
|
||||
WaveParams.expchroma = false;
|
||||
WaveParams.expedge = false;
|
||||
WaveParams.expfinal = false;
|
||||
WaveParams.exptoning = false;
|
||||
WaveParams.expnoise = false;
|
||||
}
|
||||
|
||||
ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
|
||||
|
||||
|
||||
if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") {
|
||||
WaveParams.expcontrast = procont;
|
||||
WaveParams.expchroma = prochro;
|
||||
WaveParams.expedge = proedge;
|
||||
WaveParams.expfinal = profin;
|
||||
WaveParams.exptoning = proton;
|
||||
WaveParams.expnoise = pronois;
|
||||
|
||||
if (WaveParams.softrad > 0.f) {
|
||||
|
||||
array2D<float> ble(pW, pH);
|
||||
array2D<float> guid(pW, pH);
|
||||
Imagefloat *tmpImage = nullptr;
|
||||
tmpImage = new Imagefloat(pW, pH);
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int ir = 0; ir < pH; ir++)
|
||||
for (int jr = 0; jr < pW; jr++) {
|
||||
float X, Y, Z;
|
||||
float L = provradius->L[ir][jr];
|
||||
float a = provradius->a[ir][jr];
|
||||
float b = provradius->b[ir][jr];
|
||||
Color::Lab2XYZ(L, a, b, X, Y, Z);
|
||||
|
||||
guid[ir][jr] = Y / 32768.f;
|
||||
float La = nprevl->L[ir][jr];
|
||||
float aa = nprevl->a[ir][jr];
|
||||
float ba = nprevl->b[ir][jr];
|
||||
Color::Lab2XYZ(La, aa, ba, X, Y, Z);
|
||||
tmpImage->r(ir, jr) = X;
|
||||
tmpImage->g(ir, jr) = Y;
|
||||
tmpImage->b(ir, jr) = Z;
|
||||
ble[ir][jr] = Y / 32768.f;
|
||||
}
|
||||
|
||||
double epsilmax = 0.0001;
|
||||
double epsilmin = 0.00001;
|
||||
double aepsil = (epsilmax - epsilmin) / 90.f;
|
||||
double bepsil = epsilmax - 100.f * aepsil;
|
||||
double epsil = aepsil * WaveParams.softrad + bepsil;
|
||||
|
||||
float blur = 10.f / scale * (0.0001f + 0.8f * WaveParams.softrad);
|
||||
// rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh);
|
||||
rtengine::guidedFilter(guid, ble, ble, blur, epsil, false);
|
||||
|
||||
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int ir = 0; ir < pH; ir++)
|
||||
for (int jr = 0; jr < pW; jr++) {
|
||||
float X = tmpImage->r(ir, jr);
|
||||
float Y = 32768.f * ble[ir][jr];
|
||||
float Z = tmpImage->b(ir, jr);
|
||||
float L, a, b;
|
||||
Color::XYZ2Lab(X, Y, Z, L, a, b);
|
||||
nprevl->L[ir][jr] = L;
|
||||
}
|
||||
|
||||
delete tmpImage;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") {
|
||||
float mL = (float)(WaveParams.mergeL / 100.f);
|
||||
float mC = (float)(WaveParams.mergeC / 100.f);
|
||||
float mL0;
|
||||
float mC0;
|
||||
float background = 0.f;
|
||||
int show = 0;
|
||||
|
||||
|
||||
|
||||
if ((WaveParams.CLmethod == "one" || WaveParams.CLmethod == "inf") && WaveParams.Backmethod == "black") {
|
||||
mL0 = mC0 = 0.f;
|
||||
mL = - 1.5f * mL;
|
||||
mC = -mC;
|
||||
background = 12000.f;
|
||||
show = 0;
|
||||
} else if (WaveParams.CLmethod == "sup" && WaveParams.Backmethod == "resid") {
|
||||
mL0 = mL;
|
||||
mC0 = mC;
|
||||
background = 0.f;
|
||||
show = 0;
|
||||
} else {
|
||||
mL0 = mL = mC0 = mC = 0.f;
|
||||
background = 0.f;
|
||||
show = 0;
|
||||
}
|
||||
float indic = 1.f;
|
||||
|
||||
if(WaveParams.showmask){
|
||||
mL0 = mC0 = -1.f;
|
||||
indic = -1.f;
|
||||
mL = fabs(mL);
|
||||
mC = fabs(mC);
|
||||
show = 1;
|
||||
}
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int x = 0; x < pH; x++)
|
||||
for (int y = 0; y < pW; y++) {
|
||||
nprevl->L[x][y] = LIM((1.f + mL0) * (unshar->L[x][y]) + show * background - mL * indic * nprevl->L[x][y], 0.f, 32768.f);
|
||||
nprevl->a[x][y] = (1.f + mC0) * (unshar->a[x][y]) - mC * indic * nprevl->a[x][y];
|
||||
nprevl->b[x][y] = (1.f + mC0) * (unshar->b[x][y]) - mC * indic * nprevl->b[x][y];
|
||||
}
|
||||
|
||||
delete unshar;
|
||||
unshar = NULL;
|
||||
/*
|
||||
if (WaveParams.softrad > 0.f) {
|
||||
array2D<float> ble(pW, pH);
|
||||
array2D<float> guid(pW, pH);
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int ir = 0; ir < pH; ir++)
|
||||
for (int jr = 0; jr < pW; jr++) {
|
||||
ble[ir][jr] = (nprevl->L[ir][jr] - provradius->L[ir][jr]) / 32768.f;
|
||||
guid[ir][jr] = provradius->L[ir][jr] / 32768.f;
|
||||
}
|
||||
double epsilmax = 0.001;
|
||||
double epsilmin = 0.0001;
|
||||
double aepsil = (epsilmax - epsilmin) / 90.f;
|
||||
double bepsil = epsilmax - 100.f * aepsil;
|
||||
double epsil = aepsil * WaveParams.softrad + bepsil;
|
||||
|
||||
float blur = 10.f / scale * (0.001f + 0.8f * WaveParams.softrad);
|
||||
// rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh);
|
||||
rtengine::guidedFilter(guid, ble, ble, blur, epsil, false);
|
||||
|
||||
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
|
||||
for (int ir = 0; ir < pH; ir++)
|
||||
for (int jr = 0; jr < pW; jr++) {
|
||||
nprevl->L[ir][jr] = provradius->L[ir][jr] + 32768.f * ble[ir][jr];
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (WaveParams.softrad > 0.f) {
|
||||
|
||||
delete provradius;
|
||||
provradius = NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ipf.softLight(nprevl);
|
||||
ipf.softLight(nprevl);
|
||||
|
||||
if (params->colorappearance.enabled) {
|
||||
// L histo and Chroma histo for ciecam
|
||||
@@ -919,7 +1197,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
double E_V = fcomp + log2(double ((fnum * fnum) / fspeed / (fiso / 100.f)));
|
||||
E_V += params->toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += log2(params->raw.expos); // exposure raw white point ; log2 ==> linear to EV
|
||||
adap = powf(2.f, E_V - 3.f); // cd / m2
|
||||
adap = pow(2.0, E_V - 3.0); // cd / m2
|
||||
// end calculation adaptation scene luminosity
|
||||
}
|
||||
|
||||
@@ -945,17 +1223,23 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
|
||||
ipf.ciecam_02float(ncie, float (adap), pW, 2, nprevl, params.get(), customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0 , scale, execsharp, d, dj, yb, 1);
|
||||
|
||||
if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled) {
|
||||
if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) {
|
||||
acListener->autoCamChanged(100.* (double)d, 100.* (double)dj);
|
||||
}
|
||||
|
||||
if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled) {
|
||||
if (params->colorappearance.autoadapscen && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) {
|
||||
acListener->adapCamChanged(adap); //real value of adapt scene
|
||||
}
|
||||
|
||||
if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled) {
|
||||
if (params->colorappearance.autoybscen && acListener && params->colorappearance.enabled && !params->colorappearance.presetcat02) {
|
||||
acListener->ybCamChanged((int) yb); //real value Yb scene
|
||||
}
|
||||
|
||||
if (params->colorappearance.enabled && params->colorappearance.presetcat02 && params->colorappearance.autotempout) {
|
||||
// acListener->wbCamChanged(params->wb.temperature, params->wb.green); //real temp and tint
|
||||
acListener->wbCamChanged(params->wb.temperature, 1.f); //real temp and tint = 1.
|
||||
}
|
||||
|
||||
} else {
|
||||
// CIECAM is disabled, we free up its image buffer to save some space
|
||||
if (ncie) {
|
||||
@@ -1024,6 +1308,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
hListener->histogramChanged(histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRedRaw, histGreenRaw, histBlueRaw, histChroma, histLRETI);
|
||||
}
|
||||
}
|
||||
|
||||
if (orig_prev != oprevi) {
|
||||
delete oprevi;
|
||||
oprevi = nullptr;
|
||||
@@ -1210,18 +1495,27 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, dou
|
||||
{
|
||||
|
||||
if (imgsrc) {
|
||||
if (lastAwbEqual != equal || lastAwbTempBias != tempBias) {
|
||||
if (lastAwbEqual != equal || lastAwbTempBias != tempBias || lastAwbauto != params->wb.method) {
|
||||
// Issue 2500 MyMutex::MyLock lock(minit); // Also used in crop window
|
||||
double rm, gm, bm;
|
||||
imgsrc->getAutoWBMultipliers(rm, gm, bm);
|
||||
params->wb.method = "autold";//same result as before muliple Auto WB
|
||||
|
||||
// imgsrc->getAutoWBMultipliers(rm, gm, bm);
|
||||
double tempitc = 5000.;
|
||||
double greenitc = 1.;
|
||||
float studgood = 1000.f;
|
||||
double tempref, greenref;
|
||||
imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw);
|
||||
|
||||
if (rm != -1) {
|
||||
autoWB.update(rm, gm, bm, equal, tempBias);
|
||||
lastAwbEqual = equal;
|
||||
lastAwbTempBias = tempBias;
|
||||
lastAwbauto = params->wb.method;
|
||||
} else {
|
||||
lastAwbEqual = -1.;
|
||||
autoWB.useDefaults(equal);
|
||||
lastAwbauto = "";
|
||||
lastAwbTempBias = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -1284,27 +1578,22 @@ bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB,
|
||||
{
|
||||
MyMutex::MyLock lock(mProcessing);
|
||||
|
||||
const auto xlate =
|
||||
[this](int x, int y) -> Coord2D
|
||||
{
|
||||
const std::vector<Coord2D> points = {Coord2D(x, y)};
|
||||
|
||||
std::vector<Coord2D> red;
|
||||
std::vector<Coord2D> green;
|
||||
std::vector<Coord2D> blue;
|
||||
ipf.transCoord(fw, fh, points, red, green, blue);
|
||||
|
||||
return green[0];
|
||||
};
|
||||
|
||||
const int tr = getCoarseBitMask(params->coarse);
|
||||
|
||||
const Coord2D p1 = xlate(xA, yA);
|
||||
const Coord2D p2 = xlate(xB, yB);
|
||||
const Coord2D p1 = translateCoord(ipf, fw, fh, xA, yA);
|
||||
const Coord2D p2 = translateCoord(ipf, fw, fh, xB, yB);
|
||||
|
||||
return imgsrc->getFilmNegativeExponents(p1, p2, tr, params->filmNegative, newExps);
|
||||
}
|
||||
|
||||
bool ImProcCoordinator::getRawSpotValues(int x, int y, int spotSize, std::array<float, 3>& rawValues)
|
||||
{
|
||||
MyMutex::MyLock lock(mProcessing);
|
||||
|
||||
return imgsrc->getRawSpotValues(translateCoord(ipf, fw, fh, x, y), spotSize,
|
||||
getCoarseBitMask(params->coarse), params->filmNegative, rawValues);
|
||||
}
|
||||
|
||||
void ImProcCoordinator::getAutoCrop(double ratio, int &x, int &y, int &w, int &h)
|
||||
{
|
||||
|
||||
@@ -1398,7 +1687,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a
|
||||
|
||||
if (validParams->wb.method == "Camera") {
|
||||
currWB = imgsrc->getWB();
|
||||
} else if (validParams->wb.method == "Auto") {
|
||||
} else if (validParams->wb.method == "autold") {
|
||||
if (lastAwbEqual != validParams->wb.equal || lastAwbTempBias != validParams->wb.tempBias) {
|
||||
double rm, gm, bm;
|
||||
imgsrc->getAutoWBMultipliers(rm, gm, bm);
|
||||
@@ -1424,7 +1713,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a
|
||||
imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw);
|
||||
ImProcFunctions ipf(&ppar, true);
|
||||
|
||||
if (ipf.needsTransform()) {
|
||||
if (ipf.needsTransform(fW, fH, imgsrc->getRotateDegree(), imgsrc->getMetaData())) {
|
||||
Imagefloat* trImg = new Imagefloat(fW, fH);
|
||||
ipf.transform(im, trImg, 0, 0, 0, 0, fW, fH, fW, fH,
|
||||
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true);
|
||||
|
Reference in New Issue
Block a user