Speedup for thumbnail processing

This commit is contained in:
heckflosse 2016-05-01 00:16:06 +02:00
parent e61e488346
commit 2dd2f5ca17
14 changed files with 427 additions and 800 deletions

View File

@ -215,7 +215,7 @@ public:
* For a LUT(500), it will return 500
* @return number of element in the array
*/
int getSize()
unsigned int getSize() const
{
return size;
}
@ -274,6 +274,20 @@ public:
return *this;
}
// mutliply all elements of LUT with a constant float value
LUT<float> & operator*=(float factor)
{
#ifdef _OPENMP
#pragma omp simd
#endif
for(unsigned int i = 0; i < this->size; i++) {
data[i] *= factor;
}
return *this;
}
// use with integer indices
T& operator[](int index) const
{
@ -526,79 +540,59 @@ public:
upperBound = 0;
maxs = 0;
}
};
// TODO: HOMBRE: HueLUT is actually unused, could we delete this class now that LUT::getVal01 has been created?
/** @brief LUT subclass handling hue values specifically.
The array has a fixed size of float values and have to be in the [0.; 1.] range in both axis (no error checking implemented) */
class HueLUT : public LUTf
{
public:
HueLUT() : LUTf() {}
explicit HueLUT(bool createArray) : LUTf()
// create an identity LUT (LUT(x) = x) or a scaled identity LUT (LUT(x) = x / divisor)
void makeIdentity(float divisor = 1.f)
{
if (createArray) {
this->operator () (501, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
}
}
void create()
{
this->operator () (501, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
}
// use with integer indices
float& operator[](int index) const
{
return data[ rtengine::LIM<int>(index, 0, upperBound) ];
}
// use with float indices in the [0.;1.] range
float operator[](float index) const
{
int idx = int(index * 500.f); // don't use floor! The difference in negative space is no problems here
if (index < 0.f) {
return data[0];
} else if (index > 1.f) {
return data[upperBound];
}
float balance = index - float(idx / 500.f);
float h1 = data[idx];
float h2 = data[idx + 1];
if (h1 == h2) {
return h1;
}
if ((h1 > h2) && (h1 - h2 > 0.5f)) {
h1 -= 1.f;
float value = h1 + balance * (h2 - h1);
if (value < 0.f) {
value += 1.f;
if(divisor == 1.f) {
for(unsigned int i = 0; i < size; i++) {
data[i] = i;
}
return value;
} else if (h2 - h1 > 0.5f) {
h2 -= 1.f;
float value = h1 + balance * (h2 - h1);
if (value < 0.f) {
value += 1.f;
}
return value;
} else {
return h1 + balance * (h2 - h1);
for(unsigned int i = 0; i < size; i++) {
data[i] = i / divisor;
}
}
}
};
// compress a LUT with size y into a LUT with size y (y<x)
void compressTo(LUT<T> &dest, unsigned int numVals) const
{
numVals = std::min(numVals, size);
float divisor = numVals - 1;
float mult = (dest.size - 1) / divisor;
for (unsigned int i = 0; i < numVals; i++) {
int hi = (int)(mult * i);
dest.data[hi] += this->data[i] ;
}
}
// compress a LUT with size y into a LUT with size y (y<x) by using the passTrough LUT to calculate indexes
void compressTo(LUT<T> &dest, unsigned int numVals, const LUT<float> &passThrough) const
{
if(passThrough) {
numVals = std::min(numVals, size);
numVals = std::min(numVals, passThrough.getSize());
float mult = dest.size - 1;
for (int i = 0; i < numVals; i++) {
int hi = (int)(mult * passThrough[i]);
dest[hi] += this->data[i] ;
}
}
}
void makeConstant(float value, unsigned int numVals = 0)
{
numVals = numVals == 0 ? size : numVals;
numVals = std::min(numVals, size);
for(unsigned int i = 0; i < numVals; i++) {
data[i] = value;
}
}
};
#endif /* LUT_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -159,7 +159,9 @@ protected:
static inline double simplebasecurve (double x, double b, double sr)
{
// a = 1, D = 1, hr = 0 (unused for a = D = 1)
if (b < 0) {
if (b == 0.0) {
return x;
} else if (b < 0) {
double m = 0.5;//midpoint
double slope = 1.0 + b; //slope of straight line between (0,-b) and (1,1)
double y = -b + m * slope; //value at midpoint
@ -175,7 +177,7 @@ protected:
double y = (m - b) * slope;
if (x <= m) {
return b == 0 ? x * slope : clower (x / m, slope * m / y, sr) * y;
return clower (x / m, slope * m / y, sr) * y;
} else {
return y + (x - m) * slope;
}
@ -238,13 +240,18 @@ public:
}
static inline float gamma (float x, float gamma, float start, float slope, float mul, float add)
{
return (x <= start ? x*slope : expf(logf(x) / gamma) * mul - add);
return (x <= start ? x*slope : xexpf(xlogf(x) / gamma) * mul - add);
}
static inline float igamma (float x, float gamma, float start, float slope, float mul, float add)
{
return (x <= start * slope ? x / slope : expf(logf((x + add) / mul) * gamma) );
return (x <= start * slope ? x / slope : xexpf(xlogf((x + add) / mul) * gamma) );
}
#ifdef __SSE2__
static inline vfloat igamma (vfloat x, vfloat gamma, vfloat start, vfloat slope, vfloat mul, vfloat add)
{
return (x <= start * slope ? x / slope : xexpf(xlogf((x + add) / mul) * gamma) );
}
#endif
static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level)
{
if (comp > 0.0) {
@ -276,37 +283,30 @@ public:
LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2,
int skip = 1);
static void curveBW (const std::vector<double>& curvePointsbw, const std::vector<double>& curvePointsbw2, LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,
static void curveBW (const std::vector<double>& curvePointsbw, const std::vector<double>& curvePointsbw2, const LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,
ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip);
static void curveCL ( bool & clcutili, const std::vector<double>& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip);
static void curveCL ( bool & clcutili, const std::vector<double>& clcurvePoints, LUTf & clCurve, const LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip);
static void curveWavContL ( bool & wavcontlutili, const std::vector<double>& wavclcurvePoints, LUTf & wavclCurve,/* LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip);
static void curveDehaContL ( bool & dehacontlutili, const std::vector<double>& dehaclcurvePoints, LUTf & dehaclCurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram);
static void mapcurve ( bool & mapcontlutili, const std::vector<double>& mapcurvePoints, LUTf & mapcurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram);
static void curveDehaContL ( bool & dehacontlutili, const std::vector<double>& dehaclcurvePoints, LUTf & dehaclCurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram);
static void mapcurve ( bool & mapcontlutili, const std::vector<double>& mapcurvePoints, LUTf & mapcurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram);
static void curveToningCL ( bool & clctoningutili, const std::vector<double>& clcurvePoints, LUTf & clToningCurve, int skip);
static void curveToningLL ( bool & llctoningutili, const std::vector<double>& llcurvePoints, LUTf & llToningCurve, int skip);
static void denoiseCC ( bool & ccdenoiseutili, const std::vector<double>& cccurvePoints, LUTf & NoiseCCcurve, int skip);
static void curveToning ( const std::vector<double>& curvePoints, LUTf & ToningCurve, int skip);
static void complexsgnCurve ( float adjustr, bool & autili, bool & butili, bool & ccutili, bool & clcutili, double saturation, double rstprotection, const std::vector<double>& acurvePoints,
const std::vector<double>& bcurvePoints, const std::vector<double>& cccurvePoints, const std::vector<double>& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve,
LUTu & histogramC, LUTu & histogramLC, LUTu & outBeforeCCurveHistogram, LUTu & outBeforeLCurveHistogram, ///for chroma
const LUTu & histogramC, const LUTu & histogramLC, LUTu & outBeforeCCurveHistogram, LUTu & outBeforeLCurveHistogram, ///for chroma
int skip = 1);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped,
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, const LUTu & histogram, LUTu & histogramCropped,
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili);
static void updatechroma (
const std::vector<double>& cccurvePoints,
LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma
int skip = 1);
static void curveLightBrightColor (
procparams::ColorAppearanceParams::eTCModeId curveMode, const std::vector<double>& curvePoints,
procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector<double>& curvePoints3,
LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram,
LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,
const std::vector<double>& curvePoints,
const std::vector<double>& curvePoints2,
const std::vector<double>& curvePoints3,
const LUTu & histogram, LUTu & outBeforeCCurveHistogram,
const LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,
ColorAppearance & outColCurve1,
ColorAppearance & outColCurve2,
ColorAppearance & outColCurve3,
@ -358,11 +358,11 @@ protected:
}
static inline double p01 (double x, double prot)
{
return x <= 0.5 ? CurveFactory::clower (x * 2, 2.0, prot) / 2.0 : 0.5 + CurveFactory::cupper ((x - 0.5) * 2, 2.0, prot) / 2.0;
return x <= 0.5 ? CurveFactory::clower (x * 2, 2.0, prot) * 0.5 : 0.5 + CurveFactory::cupper ((x - 0.5) * 2, 2.0, prot) * 0.5;
}
static inline double p10 (double x, double prot)
{
return x <= 0.5 ? CurveFactory::cupper (x * 2, 2.0, prot) / 2.0 : 0.5 + CurveFactory::clower ((x - 0.5) * 2, 2.0, prot) / 2.0;
return x <= 0.5 ? CurveFactory::cupper (x * 2, 2.0, prot) * 0.5 : 0.5 + CurveFactory::clower ((x - 0.5) * 2, 2.0, prot) * 0.5;
}
static inline double pfull (double x, double prot, double sh, double hl)
{
@ -464,7 +464,7 @@ public:
virtual ~ToneCurve() {};
void Reset();
void Set(Curve *pCurve, float gamma = 0, float start = 0, float slope = 0, float mul = 0, float add = 0);
void Set(const Curve &pCurve, float gamma = 0, float start = 0, float slope = 0, float mul = 0, float add = 0);
operator bool (void) const
{
return lutToneCurve;
@ -688,7 +688,7 @@ public:
virtual ~ColorAppearance() {};
void Reset();
void Set(Curve *pCurve);
void Set(const Curve &pCurve);
operator bool (void) const
{
return lutColCurve;

View File

@ -1011,7 +1011,7 @@ DCPProfile::DCPProfile(Glib::ustring fname)
// Create the curve
DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS);
toneCurve.Set((Curve*)&rawCurve);
toneCurve.Set(rawCurve);
hasToneCurve = true;
}
} else if (tag == NULL) {
@ -1031,7 +1031,7 @@ DCPProfile::DCPProfile(Glib::ustring fname)
}
DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS);
toneCurve.Set((Curve*)&rawCurve);
toneCurve.Set(rawCurve);
hasToneCurve = true;
}
}

View File

@ -1414,10 +1414,7 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i
gamtab = &(Color::gammatab_24_17a);
} else {
gamtab = new LUTf(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW);
for(int i = 0; i < 65536; i++) {
(*gamtab)[i] = (float)i / 65535.f;
}
gamtab->makeIdentity(65535.f);
}

View File

@ -301,10 +301,10 @@ double DiagonalCurve::getVal (double t) const
}
// do a binary search for the right interval:
int k_lo = 0, k_hi = N - 1;
unsigned int k_lo = 0, k_hi = N - 1;
while (k_hi - k_lo > 1) {
int k = (k_hi + k_lo) / 2;
unsigned int k = (k_hi + k_lo) / 2;
if (x[k] > t) {
k_hi = k;
@ -323,7 +323,7 @@ double DiagonalCurve::getVal (double t) const
else { // if (kind==Spline) {
double a = (x[k_hi] - t) / h;
double b = (t - x[k_lo]) / h;
double r = a * y[k_lo] + b * y[k_hi] + ((a * a * a - a) * ypp[k_lo] + (b * b * b - b) * ypp[k_hi]) * (h * h) / 6.0;
double r = a * y[k_lo] + b * y[k_hi] + ((a * a * a - a) * ypp[k_lo] + (b * b * b - b) * ypp[k_hi]) * (h * h) * 0.1666666666666666666666666666666;
return CLIPD(r);
}

View File

@ -40,7 +40,7 @@ ImProcCoordinator::ImProcCoordinator ()
tonecurve(65536, 0), //,1);
chaut(0.f), redaut(0.f), blueaut(0.f), maxredaut(0.f), maxblueaut(0.f), minredaut(0.f), minblueaut(0.f), nresi(0.f),
chromina(0.f), sigma(0.f), lumema(0.f),
lumacurve(65536, 0),
lumacurve(32770, 0), // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation
chroma_acurve(65536, 0),
chroma_bcurve(65536, 0),
satcurve(65536, 0),
@ -53,7 +53,7 @@ ImProcCoordinator::ImProcCoordinator ()
NoiseCCcurve(65536, 0),
vhist16(65536), vhist16bw(65536),
lhist16(65536), lhist16Cropped(65536),
lhist16CAM(65536), lhist16CroppedCAM(65536),
lhist16CAM(65536),
lhist16CCAM(65536),
lhist16RETI(65536),
histCropped(65536),
@ -465,12 +465,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
bool clctoningutili = false;
bool llctoningutili = false;
CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
// clToningcurve.dump("CLToning3");
CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
if(params.colorToning.enabled) {
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
// clToningcurve.dump("CLToning3");
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
}
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1);
@ -698,39 +697,24 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
if(params.colorappearance.enabled) {
//L histo and Chroma histo for ciecam
// histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C
int x1, y1, x2, y2, pos, posc;
int x1, y1, x2, y2;
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
lhist16CAM.clear();
lhist16CroppedCAM.clear();
lhist16CCAM.clear();
for (int x = 0; x < pH; x++)
for (int y = 0; y < pW; y++) {
pos = CLIP((int)(nprevl->L[x][y]));
if(!params.colorappearance.datacie) {
posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y]));
if(!params.colorappearance.datacie) {
for (int x = 0; x < pH; x++)
for (int y = 0; y < pW; y++) {
int pos = CLIP((int)(nprevl->L[x][y]));
int posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y]));
lhist16CAM[pos]++;
lhist16CCAM[posc]++;
}
if (y >= y1 && y < y2 && x >= x1 && x < x2) {
lhist16CroppedCAM[pos]++;
}
}
}
LUTu dummy;
CurveFactory::curveLightBrightColor (
params.colorappearance.curveMode, params.colorappearance.curve,
params.colorappearance.curveMode2, params.colorappearance.curve2,
params.colorappearance.curveMode3, params.colorappearance.curve3,
lhist16CAM, lhist16CroppedCAM, histLCAM,
lhist16CCAM, histCCAM,
customColCurve1,
customColCurve2,
customColCurve3,
scale == 1 ? 1 : 1
);
CurveFactory::curveLightBrightColor (params.colorappearance.curve, params.colorappearance.curve2, params.colorappearance.curve3,
lhist16CAM, histLCAM, lhist16CCAM, histCCAM,
customColCurve1, customColCurve2, customColCurve3, 1);
float fnum = imgsrc->getMetaData()->getFNumber (); // F number
float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO
float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed

View File

@ -108,7 +108,7 @@ protected:
LUTu vhist16, vhist16bw;
LUTu lhist16, lhist16Cropped;
LUTu lhist16CAM, lhist16CroppedCAM;
LUTu lhist16CAM;
LUTu lhist16CCAM;
LUTu lhist16RETI;
LUTu histCropped;

View File

@ -37,7 +37,8 @@
#include "improccoordinator.h"
#include "clutstore.h"
#include "ciecam02.h"
#define BENCHMARK
#include "StopWatch.h"
#ifdef _OPENMP
#include <omp.h>
#endif
@ -1722,27 +1723,28 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
LUTu hist16Q;
if (needJ) {
hist16J (65536);
hist16J (32768);
hist16J.clear();
}
if (needQ) {
hist16Q (65536);
hist16Q (32768);
hist16Q.clear();
}
#pragma omp parallel
const int numThreads = min(max(width*height / 65536,1),omp_get_max_threads());
#pragma omp parallel num_threads(numThreads) if(numThreads>1)
{
LUTu hist16Jthr;
LUTu hist16Qthr;
if (needJ) {
hist16Jthr (65536);
hist16Jthr (32768);
hist16Jthr.clear();
}
if (needQ) {
hist16Qthr(65536);
hist16Qthr(32768);
hist16Qthr.clear();
}
@ -1751,37 +1753,48 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++) { //rough correspondence between L and J
float currL = lab->L[i][j] / 327.68f;
float koef = 1.0f; //rough correspondence between L and J
float koef; //rough correspondence between L and J
// if (currL>95.f) koef=1.f;
if(currL > 85.f) {
koef = 0.97f;
} else if(currL > 80.f) {
koef = 0.93f;
} else if(currL > 70.f) {
koef = 0.87f;
} else if(currL > 60.f) {
koef = 0.85f;
} else if(currL > 50.f) {
koef = 0.8f;
} else if(currL > 40.f) {
koef = 0.75f;
if(currL > 50.f) {
if(currL > 70.f) {
if(currL > 80.f) {
if(currL > 85.f) {
koef = 0.97f;
} else {
koef = 0.93f;
}
} else {
koef = 0.87f;
}
} else {
if (currL > 60.f) {
koef = 0.85f;
} else {
koef = 0.8f;
}
}
} else {
if(currL > 10.f) {
if(currL > 20.f) {
if(currL > 40.f) {
koef = 0.75f;
} else {
koef = 0.7f;
}
} else {
koef = 0.9f;
}
} else {
koef = 1.0;
}
}
// else if(currL>30.f) koef=0.7f;
else if(currL > 20.f) {
koef = 0.7f;
} else if(currL > 10.f) {
koef = 0.9f;
}
// else if(currL>0.f) koef=1.0f;
if (needJ) {
hist16Jthr[CLIP((int)((koef * lab->L[i][j])))]++; //evaluate histogram luminance L # J
hist16Jthr[(int)((koef * lab->L[i][j]))]++; //evaluate histogram luminance L # J
}
if (needQ) {
hist16Qthr[CLIP((int) (sqrtf((koef * (lab->L[i][j])) * 32768.f)))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L
hist16Qthr[(int) (sqrtf((koef * (lab->L[i][j])) * 32768.f))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L
}
sum += koef * lab->L[i][j]; //evaluate mean J to calculate Yb
@ -1790,14 +1803,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
#pragma omp critical
{
if(needJ)
for(int i = 0; i < 65536; i++) {
hist16J[i] += hist16Jthr[i];
}
hist16J += hist16Jthr;
if(needQ)
for(int i = 0; i < 65536; i++) {
hist16Q[i] += hist16Qthr[i];
}
hist16Q += hist16Qthr;
}
}
@ -3077,7 +3086,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve, LUTf & cl2Toningcurve,
const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf)
{
LUTf fGammaLUTf;
Imagefloat *tmpImage = NULL;
// NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this
@ -3373,13 +3381,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
}
bool hasgammabw = gammabwr != 1.f || gammabwg != 1.f || gammabwb != 1.f;
fGammaLUTf(65535);
#pragma omp parallel for
for (int i = 0; i < 65536; i++) {
fGammaLUTf[i] = CurveFactory::gamma2 (float(i) / 65535.f) * 65535.f;
}
if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled)) {
tmpImage = new Imagefloat(working->width, working->height);
}
@ -3387,15 +3388,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
int W = working->width;
int H = working->height;
#define TS 112
#ifdef _OPENMP
@ -3592,9 +3584,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (editID == EUID_ToneCurve1) { // filling the pipette buffer
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f);
editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f);
editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[ti * TS + tj]] / 65535.f);
editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpB[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65535.f;
}
}
}
@ -3663,9 +3655,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (editID == EUID_ToneCurve2) { // filling the pipette buffer
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f);
editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f);
editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[ti * TS + tj]] / 65535.f);
editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpB[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65535.f;
}
}
}
@ -3722,19 +3714,19 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (editID == EUID_RGB_R) {
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editWhateverTmp[ti * TS + tj] = fGammaLUTf[rtemp[ti * TS + tj]] / 65536.f;
editWhateverTmp[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65536.f;
}
}
} else if (editID == EUID_RGB_G) {
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editWhateverTmp[ti * TS + tj] = fGammaLUTf[gtemp[ti * TS + tj]] / 65536.f;
editWhateverTmp[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65536.f;
}
}
} else if (editID == EUID_RGB_B) {
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editWhateverTmp[ti * TS + tj] = fGammaLUTf[btemp[ti * TS + tj]] / 65536.f;
editWhateverTmp[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65536.f;
}
}
}
@ -4167,9 +4159,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (editID == EUID_BlackWhiteBeforeCurve) {
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f);
editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f);
editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[ti * TS + tj]] / 65535.f);
editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpB[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65535.f;
}
}
} else if (editID == EUID_BlackWhiteLuminance) {
@ -4402,9 +4394,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
float fx, fy, fz;
fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF));
fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF));
fx = (x < 65535.0f ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF));
fz = (z < 65535.0f ? Color::cachef[z] : 327.68f * std::cbrt(z / MAXVALF));
lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68;
lab->a[i][j] = (500.0f * (fx - fy) );
@ -4560,7 +4552,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
for (int i = 0; i < tH; i++) {
for (int j = 0; j < tW; j++) {
editWhatever->v(i, j) = CLIP(fGammaLUTf[tmpImage->r(i, j)] / 65535.f); // assuming that r=g=b
editWhatever->v(i, j) = Color::gamma2curve[tmpImage->r(i, j)] / 65535.f; // assuming that r=g=b
}
}
}
@ -5527,6 +5519,7 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & cur
SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve, LUTf & lhskcurve, LUTf & clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLLCurve, LUTu &histLCurve)
{
int W = lold->W;
int H = lold->H;
// lhskcurve.dump("lh_curve");

View File

@ -120,15 +120,8 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext
rtengine::Image8 *output = NULL;
const unsigned char *data = NULL;
int fw, fh;
LUTf cdcurve;
bool dehacontlutili = false;
procparams::ProcParams params;
/*rtengine::RAWParams raw;
rtengine::LensProfParams lensProf;
rtengine::procparams::ToneCurveParams toneCurve;
rtengine::procparams::ColorManagementParams icm;
rtengine::CoarseTransformParams coarse;*/
ColorTemp wb = rawImage.getWB ();
rawImage.getFullSize (fw, fh, TR_NONE);
PreviewProps pp (0, 0, fw, fh, 1);

View File

@ -4311,7 +4311,7 @@ BENCHFUN
#pragma omp parallel
#endif
{
LUTu tmphistogram(65536 >> histcompr);
LUTu tmphistogram(histogram.getSize());
tmphistogram.clear();
#ifdef _OPENMP
#pragma omp for nowait
@ -4366,17 +4366,18 @@ BENCHFUN
const bool fourColours = ri->getSensorType() == ST_BAYER && ((mult[1] != mult[3] || cblacksom[1] != cblacksom[3]) || FC(0,0) == 3 || FC(0,1) == 3 || FC(1,0) == 3 || FC(1,1) == 3);
constexpr int histoSize = 65536;
LUTu hist[4];
hist[0](65536);
hist[0](histoSize);
hist[0].clear();
if (ri->get_colors() > 1) {
hist[1](65536);
hist[1](histoSize);
hist[1].clear();
hist[2](65536);
hist[2](histoSize);
hist[2].clear();
}
if (fourColours) {
hist[3](65536);
hist[3](histoSize);
hist[3].clear();
}
@ -4391,15 +4392,15 @@ BENCHFUN
{
// we need one LUT per color and thread, which corresponds to 1 MB per thread
LUTu tmphist[4];
tmphist[0](65536);
tmphist[0](histoSize);
tmphist[0].clear();
if (ri->get_colors() > 1) {
tmphist[1](65536);
tmphist[1](histoSize);
tmphist[1].clear();
tmphist[2](65536);
tmphist[2](histoSize);
tmphist[2].clear();
if (fourColours) {
tmphist[3](65536);
tmphist[3](histoSize);
tmphist[3].clear();
}
}

View File

@ -38,6 +38,8 @@
#include "../rtgui/ppversion.h"
#include "improccoordinator.h"
#include <locale.h>
#define BENCHMARK
#include "StopWatch.h"
extern Options options;
@ -798,6 +800,7 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int
IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, std::string camName,
double focalLen, double focalLen35mm, float focusDist, float shutter, float fnumber, float iso, std::string expcomp_, double& myscale)
{
BENCHFUN
// check if the WB's equalizer value has changed
if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4)) {
wbEqual = params.wb.equal;
@ -923,7 +926,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
} else {
StdImageSource::colorSpaceConversion (baseImg, params.icm, embProfile, thumbImg->getSampleFormat());
}
int fw = baseImg->width;
int fh = baseImg->height;
//ColorTemp::CAT02 (baseImg, &params) ;//perhaps not good!
@ -972,7 +974,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
int black = params.toneCurve.black;
int hlcompr = params.toneCurve.hlcompr;
int hlcomprthresh = params.toneCurve.hlcomprthresh;
if (params.toneCurve.autoexp && aeHistogram) {
ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh);
//ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr);
@ -981,11 +982,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LUTf curve1 (65536);
LUTf curve2 (65536);
LUTf curve (65536);
LUTf satcurve (65536);
LUTf lhskcurve (65536);
LUTf lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation
LUTf clcurve (65536);
LUTf clToningcurve (65536);
LUTf cl2Toningcurve (65536);
LUTf clToningcurve;
LUTf cl2Toningcurve;
LUTf rCurve (65536);
LUTf gCurve (65536);
@ -1003,7 +1006,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ColorAppearance customColCurve3;
ToneCurve customToneCurvebw1;
ToneCurve customToneCurvebw2;
CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh,
params.toneCurve.shcompr, bright, contr,
params.toneCurve.curveMode, params.toneCurve.curve,
@ -1013,7 +1015,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 16);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
@ -1030,13 +1031,14 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
//params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili);
bool clctoningutili = false;
bool llctoningutili = false;
CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
if(params.colorToning.enabled) {
clToningcurve (65536);
cl2Toningcurve (65536);
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
}
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16);
double rrm, ggm, bbm;
float autor, autog, autob;
float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f;
@ -1066,7 +1068,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LabImage* labView = new LabImage (fw, fh);
DCPProfile *dcpProf = NULL;
if (isRaw) {
cmsHPROFILE dummy;
RawImageSource::findInputProfile(params.icm.input, NULL, camName, &dcpProf, dummy);
@ -1075,7 +1076,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
dcpProf->setStep2ApplyState(params.icm.working, params.icm.toneCurve, params.icm.applyLookTable, params.icm.applyBaselineExposureOffset);
}
}
ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf);
// freeing up some memory
@ -1100,7 +1100,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
hist16[CLIP((int)((labView->L[i][j])))]++;
hist16C[CLIP((int)sqrt(labView->a[i][j]*labView->a[i][j] + labView->b[i][j]*labView->b[i][j]))]++;
}
// luminance processing
// ipf.EPDToneMap(labView,0,6);
@ -1110,9 +1109,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
bool ccutili = false;
bool cclutili = false;
bool clcutili = false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,
hist16, hist16, curve, dummy, 16, utili);
hist16, hist16, lumacurve, dummy, 16, utili);
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 16);
@ -1123,7 +1121,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
//ipf.luminanceCurve (labView, labView, curve);
ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, curve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy);
ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy);
ipf.vibrance(labView);
@ -1133,18 +1131,18 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
//if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);}
CurveFactory::curveLightBrightColor (
params.colorappearance.curveMode, params.colorappearance.curve,
params.colorappearance.curveMode2, params.colorappearance.curve2,
params.colorappearance.curveMode3, params.colorappearance.curve3,
hist16, hist16, dummy,
hist16C, dummy,
customColCurve1,
customColCurve2,
customColCurve3,
16);
if(params.colorappearance.enabled) {
CurveFactory::curveLightBrightColor (
params.colorappearance.curve,
params.colorappearance.curve2,
params.colorappearance.curve3,
hist16, dummy,
hist16C, dummy,
customColCurve1,
customColCurve2,
customColCurve3,
16);
int begh = 0, endh = labView->H;
bool execsharp = false;
float d;

View File

@ -771,10 +771,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf curve (65536, 0);
LUTf satcurve (65536, 0);
LUTf lhskcurve (65536, 0);
LUTf lumacurve(65536, 0);
LUTf lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation
LUTf clcurve (65536, 0);
LUTf clToningcurve (65536, 0);
LUTf cl2Toningcurve (65536, 0);
LUTf clToningcurve;
LUTf cl2Toningcurve;
LUTf wavclCurve (65536, 0);
LUTf rCurve (65536, 0);
@ -814,11 +814,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
bool opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
bool clctoningutili = false;
CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, 1);
bool llctoningutili = false;
CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, 1);
if(params.colorToning.enabled) {
clToningcurve (65536, 0);
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1);
cl2Toningcurve (65536, 0);
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1);
}
LabImage* labView = new LabImage (fw, fh);
@ -894,10 +895,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if(params.labCurve.contrast != 0) { //only use hist16 for contrast
#ifdef _OPENMP
#pragma omp parallel shared(hist16,labView, fh, fw)
#pragma omp parallel
#endif
{
LUTu hist16thr (65536); // one temporary lookup table per thread
LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread
hist16thr.clear();
#ifdef _OPENMP
#pragma omp for schedule(static) nowait
@ -906,19 +907,14 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
for (int i = 0; i < fh; i++)
for (int j = 0; j < fw; j++)
{
hist16thr[CLIP((int)((labView->L[i][j])))]++;
hist16thr[(int)((labView->L[i][j]))]++;
}
#pragma omp critical
{
for(int i = 0; i < 65536; i++)
{
hist16[i] += hist16thr[i];
}
hist16 += hist16thr;
}
}
}
bool utili = false;
@ -935,7 +931,6 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve,
hist16C, hist16C, dummy, dummy,
1);
// ipf.MSR(labView, labView->W, labView->H, 1);
ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy);
@ -1025,10 +1020,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
begh = 0;
endh = fh;
CurveFactory::curveLightBrightColor (
params.colorappearance.curveMode, params.colorappearance.curve,
params.colorappearance.curveMode2, params.colorappearance.curve2,
params.colorappearance.curveMode3, params.colorappearance.curve3,
hist16, hist16, dummy,
params.colorappearance.curve,
params.colorappearance.curve2,
params.colorappearance.curve3,
hist16, dummy,
hist16C, dummy,
customColCurve1,
customColCurve2,

View File

@ -58,7 +58,9 @@ __inline double ldexpk(double x, int q) {
m = (((m + q) >> 9) - m) << 7;
q = q - (m << 2);
u = longBitsToDouble(((int64_t)(m + 0x3ff)) << 52);
x = x * u * u * u * u;
double u2 = u*u;
u2 = u2 * u2;
x = x * u2;
u = longBitsToDouble(((int64_t)(q + 0x3ff)) << 52);
return x * u;
}
@ -1197,7 +1199,7 @@ __inline float xexpf(float d) {
int q = (int)xrintf(d * R_LN2f);
float s, u;
s = mlaf(q, -L2Uf, d);
s = mlaf(q, -L2Lf, s);
@ -1246,7 +1248,7 @@ __inline float xdivf( float d, int n){
uflint.intval -= n << 23; // add n to the exponent
}
return uflint.floatval;
}
}