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 * For a LUT(500), it will return 500
* @return number of element in the array * @return number of element in the array
*/ */
int getSize() unsigned int getSize() const
{ {
return size; return size;
} }
@ -274,6 +274,20 @@ public:
return *this; 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 // use with integer indices
T& operator[](int index) const T& operator[](int index) const
{ {
@ -526,79 +540,59 @@ public:
upperBound = 0; upperBound = 0;
maxs = 0; maxs = 0;
} }
};
// create an identity LUT (LUT(x) = x) or a scaled identity LUT (LUT(x) = x / divisor)
void makeIdentity(float divisor = 1.f)
// 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()
{ {
if (createArray) { if(divisor == 1.f) {
this->operator () (501, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); for(unsigned int i = 0; i < size; i++) {
} data[i] = i;
}
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;
} }
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 { } 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_ */ #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) static inline double simplebasecurve (double x, double b, double sr)
{ {
// a = 1, D = 1, hr = 0 (unused for a = D = 1) // 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 m = 0.5;//midpoint
double slope = 1.0 + b; //slope of straight line between (0,-b) and (1,1) double slope = 1.0 + b; //slope of straight line between (0,-b) and (1,1)
double y = -b + m * slope; //value at midpoint double y = -b + m * slope; //value at midpoint
@ -175,7 +177,7 @@ protected:
double y = (m - b) * slope; double y = (m - b) * slope;
if (x <= m) { 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 { } else {
return y + (x - m) * slope; 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) 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) 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) static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level)
{ {
if (comp > 0.0) { if (comp > 0.0) {
@ -276,37 +283,30 @@ public:
LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2, LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2,
int skip = 1); 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); 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 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 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, 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 curveToning ( const std::vector<double>& curvePoints, LUTf & ToningCurve, 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 complexsgnCurve ( float adjustr, bool & autili, bool & butili, bool & ccutili, bool & clcutili, double saturation, double rstprotection, const std::vector<double>& acurvePoints, 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, 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); 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); 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 ( static void curveLightBrightColor (
procparams::ColorAppearanceParams::eTCModeId curveMode, const std::vector<double>& curvePoints, const std::vector<double>& curvePoints,
procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2, const std::vector<double>& curvePoints2,
procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector<double>& curvePoints3, const std::vector<double>& curvePoints3,
LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram, const LUTu & histogram, LUTu & outBeforeCCurveHistogram,
LUTu & histogramC, LUTu & outBeforeCCurveHistogramC, const LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,
ColorAppearance & outColCurve1, ColorAppearance & outColCurve1,
ColorAppearance & outColCurve2, ColorAppearance & outColCurve2,
ColorAppearance & outColCurve3, ColorAppearance & outColCurve3,
@ -358,11 +358,11 @@ protected:
} }
static inline double p01 (double x, double prot) 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) 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) static inline double pfull (double x, double prot, double sh, double hl)
{ {
@ -464,7 +464,7 @@ public:
virtual ~ToneCurve() {}; virtual ~ToneCurve() {};
void Reset(); 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 operator bool (void) const
{ {
return lutToneCurve; return lutToneCurve;
@ -688,7 +688,7 @@ public:
virtual ~ColorAppearance() {}; virtual ~ColorAppearance() {};
void Reset(); void Reset();
void Set(Curve *pCurve); void Set(const Curve &pCurve);
operator bool (void) const operator bool (void) const
{ {
return lutColCurve; return lutColCurve;

View File

@ -1011,7 +1011,7 @@ DCPProfile::DCPProfile(Glib::ustring fname)
// Create the curve // Create the curve
DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS); DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS);
toneCurve.Set((Curve*)&rawCurve); toneCurve.Set(rawCurve);
hasToneCurve = true; hasToneCurve = true;
} }
} else if (tag == NULL) { } else if (tag == NULL) {
@ -1031,7 +1031,7 @@ DCPProfile::DCPProfile(Glib::ustring fname)
} }
DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS); DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS);
toneCurve.Set((Curve*)&rawCurve); toneCurve.Set(rawCurve);
hasToneCurve = true; 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); gamtab = &(Color::gammatab_24_17a);
} else { } else {
gamtab = new LUTf(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW); gamtab = new LUTf(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW);
gamtab->makeIdentity(65535.f);
for(int i = 0; i < 65536; i++) {
(*gamtab)[i] = (float)i / 65535.f;
}
} }

View File

@ -301,10 +301,10 @@ double DiagonalCurve::getVal (double t) const
} }
// do a binary search for the right interval: // 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) { 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) { if (x[k] > t) {
k_hi = k; k_hi = k;
@ -323,7 +323,7 @@ double DiagonalCurve::getVal (double t) const
else { // if (kind==Spline) { else { // if (kind==Spline) {
double a = (x[k_hi] - t) / h; double a = (x[k_hi] - t) / h;
double b = (t - x[k_lo]) / 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); return CLIPD(r);
} }

View File

@ -40,7 +40,7 @@ ImProcCoordinator::ImProcCoordinator ()
tonecurve(65536, 0), //,1); 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), 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), 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_acurve(65536, 0),
chroma_bcurve(65536, 0), chroma_bcurve(65536, 0),
satcurve(65536, 0), satcurve(65536, 0),
@ -53,7 +53,7 @@ ImProcCoordinator::ImProcCoordinator ()
NoiseCCcurve(65536, 0), NoiseCCcurve(65536, 0),
vhist16(65536), vhist16bw(65536), vhist16(65536), vhist16bw(65536),
lhist16(65536), lhist16Cropped(65536), lhist16(65536), lhist16Cropped(65536),
lhist16CAM(65536), lhist16CroppedCAM(65536), lhist16CAM(65536),
lhist16CCAM(65536), lhist16CCAM(65536),
lhist16RETI(65536), lhist16RETI(65536),
histCropped(65536), histCropped(65536),
@ -465,12 +465,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
opautili = false; opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
bool clctoningutili = false; if(params.colorToning.enabled) {
bool llctoningutili = false; CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); // clToningcurve.dump("CLToning3");
// clToningcurve.dump("CLToning3"); CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); }
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1); 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) { if(params.colorappearance.enabled) {
//L histo and Chroma histo for ciecam //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 // 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); params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
lhist16CAM.clear(); lhist16CAM.clear();
lhist16CroppedCAM.clear();
lhist16CCAM.clear(); lhist16CCAM.clear();
for (int x = 0; x < pH; x++) if(!params.colorappearance.datacie) {
for (int y = 0; y < pW; y++) { for (int x = 0; x < pH; x++)
pos = CLIP((int)(nprevl->L[x][y])); for (int y = 0; y < pW; y++) {
int pos = CLIP((int)(nprevl->L[x][y]));
if(!params.colorappearance.datacie) { int posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y]));
posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y]));
lhist16CAM[pos]++; lhist16CAM[pos]++;
lhist16CCAM[posc]++; lhist16CCAM[posc]++;
}
if (y >= y1 && y < y2 && x >= x1 && x < x2) {
lhist16CroppedCAM[pos]++;
}
} }
}
LUTu dummy; CurveFactory::curveLightBrightColor (params.colorappearance.curve, params.colorappearance.curve2, params.colorappearance.curve3,
CurveFactory::curveLightBrightColor ( lhist16CAM, histLCAM, lhist16CCAM, histCCAM,
params.colorappearance.curveMode, params.colorappearance.curve, customColCurve1, customColCurve2, customColCurve3, 1);
params.colorappearance.curveMode2, params.colorappearance.curve2,
params.colorappearance.curveMode3, params.colorappearance.curve3,
lhist16CAM, lhist16CroppedCAM, histLCAM,
lhist16CCAM, histCCAM,
customColCurve1,
customColCurve2,
customColCurve3,
scale == 1 ? 1 : 1
);
float fnum = imgsrc->getMetaData()->getFNumber (); // F number float fnum = imgsrc->getMetaData()->getFNumber (); // F number
float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO
float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed

View File

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

View File

@ -37,7 +37,8 @@
#include "improccoordinator.h" #include "improccoordinator.h"
#include "clutstore.h" #include "clutstore.h"
#include "ciecam02.h" #include "ciecam02.h"
#define BENCHMARK
#include "StopWatch.h"
#ifdef _OPENMP #ifdef _OPENMP
#include <omp.h> #include <omp.h>
#endif #endif
@ -1722,27 +1723,28 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
LUTu hist16Q; LUTu hist16Q;
if (needJ) { if (needJ) {
hist16J (65536); hist16J (32768);
hist16J.clear(); hist16J.clear();
} }
if (needQ) { if (needQ) {
hist16Q (65536); hist16Q (32768);
hist16Q.clear(); 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 hist16Jthr;
LUTu hist16Qthr; LUTu hist16Qthr;
if (needJ) { if (needJ) {
hist16Jthr (65536); hist16Jthr (32768);
hist16Jthr.clear(); hist16Jthr.clear();
} }
if (needQ) { if (needQ) {
hist16Qthr(65536); hist16Qthr(32768);
hist16Qthr.clear(); 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 i = 0; i < height; i++)
for (int j = 0; j < width; j++) { //rough correspondence between L and J for (int j = 0; j < width; j++) { //rough correspondence between L and J
float currL = lab->L[i][j] / 327.68f; 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 > 50.f) {
if(currL > 85.f) { if(currL > 70.f) {
koef = 0.97f; if(currL > 80.f) {
} else if(currL > 80.f) { if(currL > 85.f) {
koef = 0.93f; koef = 0.97f;
} else if(currL > 70.f) { } else {
koef = 0.87f; koef = 0.93f;
} else if(currL > 60.f) { }
koef = 0.85f; } else {
} else if(currL > 50.f) { koef = 0.87f;
koef = 0.8f; }
} else if(currL > 40.f) { } else {
koef = 0.75f; 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) { 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) { 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 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 #pragma omp critical
{ {
if(needJ) if(needJ)
for(int i = 0; i < 65536; i++) { hist16J += hist16Jthr;
hist16J[i] += hist16Jthr[i];
}
if(needQ) if(needQ)
for(int i = 0; i < 65536; i++) { hist16Q += hist16Qthr;
hist16Q[i] += hist16Qthr[i];
}
} }
} }
@ -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, 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) 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; Imagefloat *tmpImage = NULL;
// NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this // 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; 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)) { if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled)) {
tmpImage = new Imagefloat(working->width, working->height); tmpImage = new Imagefloat(working->width, working->height);
} }
@ -3387,15 +3388,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
int W = working->width; int W = working->width;
int H = working->height; int H = working->height;
#define TS 112 #define TS 112
#ifdef _OPENMP #ifdef _OPENMP
@ -3592,9 +3584,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (editID == EUID_ToneCurve1) { // filling the pipette buffer if (editID == EUID_ToneCurve1) { // filling the pipette buffer
for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f); editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f); editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[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 if (editID == EUID_ToneCurve2) { // filling the pipette buffer
for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f); editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f); editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[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) { if (editID == EUID_RGB_R) {
for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) { 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) { } else if (editID == EUID_RGB_G) {
for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) { 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) { } else if (editID == EUID_RGB_B) {
for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) { 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) { if (editID == EUID_BlackWhiteBeforeCurve) {
for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * TS + tj] = CLIP(fGammaLUTf[rtemp[ti * TS + tj]] / 65535.f); editIFloatTmpR[ti * TS + tj] = Color::gamma2curve[rtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpG[ti * TS + tj] = CLIP(fGammaLUTf[gtemp[ti * TS + tj]] / 65535.f); editIFloatTmpG[ti * TS + tj] = Color::gamma2curve[gtemp[ti * TS + tj]] / 65535.f;
editIFloatTmpB[ti * TS + tj] = CLIP(fGammaLUTf[btemp[ti * TS + tj]] / 65535.f); editIFloatTmpB[ti * TS + tj] = Color::gamma2curve[btemp[ti * TS + tj]] / 65535.f;
} }
} }
} else if (editID == EUID_BlackWhiteLuminance) { } else if (editID == EUID_BlackWhiteLuminance) {
@ -4402,9 +4394,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
float fx, fy, fz; float fx, fy, fz;
fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF)); fx = (x < 65535.0f ? Color::cachef[x] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF)); fy = (y < 65535.0f ? Color::cachef[y] : 327.68f * std::cbrt(y / MAXVALF));
fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / 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->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68;
lab->a[i][j] = (500.0f * (fx - fy) ); 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 i = 0; i < tH; i++) {
for (int j = 0; j < tW; j++) { 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) 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 W = lold->W;
int H = lold->H; int H = lold->H;
// lhskcurve.dump("lh_curve"); // lhskcurve.dump("lh_curve");

View File

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

View File

@ -4311,7 +4311,7 @@ BENCHFUN
#pragma omp parallel #pragma omp parallel
#endif #endif
{ {
LUTu tmphistogram(65536 >> histcompr); LUTu tmphistogram(histogram.getSize());
tmphistogram.clear(); tmphistogram.clear();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for nowait #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); 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]; LUTu hist[4];
hist[0](65536); hist[0](histoSize);
hist[0].clear(); hist[0].clear();
if (ri->get_colors() > 1) { if (ri->get_colors() > 1) {
hist[1](65536); hist[1](histoSize);
hist[1].clear(); hist[1].clear();
hist[2](65536); hist[2](histoSize);
hist[2].clear(); hist[2].clear();
} }
if (fourColours) { if (fourColours) {
hist[3](65536); hist[3](histoSize);
hist[3].clear(); hist[3].clear();
} }
@ -4391,15 +4392,15 @@ BENCHFUN
{ {
// we need one LUT per color and thread, which corresponds to 1 MB per thread // we need one LUT per color and thread, which corresponds to 1 MB per thread
LUTu tmphist[4]; LUTu tmphist[4];
tmphist[0](65536); tmphist[0](histoSize);
tmphist[0].clear(); tmphist[0].clear();
if (ri->get_colors() > 1) { if (ri->get_colors() > 1) {
tmphist[1](65536); tmphist[1](histoSize);
tmphist[1].clear(); tmphist[1].clear();
tmphist[2](65536); tmphist[2](histoSize);
tmphist[2].clear(); tmphist[2].clear();
if (fourColours) { if (fourColours) {
tmphist[3](65536); tmphist[3](histoSize);
tmphist[3].clear(); tmphist[3].clear();
} }
} }

View File

@ -38,6 +38,8 @@
#include "../rtgui/ppversion.h" #include "../rtgui/ppversion.h"
#include "improccoordinator.h" #include "improccoordinator.h"
#include <locale.h> #include <locale.h>
#define BENCHMARK
#include "StopWatch.h"
extern Options options; 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, 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) 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 // check if the WB's equalizer value has changed
if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4)) { if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4)) {
wbEqual = params.wb.equal; wbEqual = params.wb.equal;
@ -923,7 +926,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
} else { } else {
StdImageSource::colorSpaceConversion (baseImg, params.icm, embProfile, thumbImg->getSampleFormat()); StdImageSource::colorSpaceConversion (baseImg, params.icm, embProfile, thumbImg->getSampleFormat());
} }
int fw = baseImg->width; int fw = baseImg->width;
int fh = baseImg->height; int fh = baseImg->height;
//ColorTemp::CAT02 (baseImg, &params) ;//perhaps not good! //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 black = params.toneCurve.black;
int hlcompr = params.toneCurve.hlcompr; int hlcompr = params.toneCurve.hlcompr;
int hlcomprthresh = params.toneCurve.hlcomprthresh; int hlcomprthresh = params.toneCurve.hlcomprthresh;
if (params.toneCurve.autoexp && aeHistogram) { 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, 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); //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 curve1 (65536);
LUTf curve2 (65536); LUTf curve2 (65536);
LUTf curve (65536); LUTf curve (65536);
LUTf satcurve (65536); LUTf satcurve (65536);
LUTf lhskcurve (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 clcurve (65536);
LUTf clToningcurve (65536); LUTf clToningcurve;
LUTf cl2Toningcurve (65536); LUTf cl2Toningcurve;
LUTf rCurve (65536); LUTf rCurve (65536);
LUTf gCurve (65536); LUTf gCurve (65536);
@ -1003,7 +1006,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ColorAppearance customColCurve3; ColorAppearance customColCurve3;
ToneCurve customToneCurvebw1; ToneCurve customToneCurvebw1;
ToneCurve customToneCurvebw2; ToneCurve customToneCurvebw2;
CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh,
params.toneCurve.shcompr, bright, contr, params.toneCurve.shcompr, bright, contr,
params.toneCurve.curveMode, params.toneCurve.curve, 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.rcurve, rCurve, 16);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16); CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = { double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]}, {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.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
//params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili); //params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili);
bool clctoningutili = false; if(params.colorToning.enabled) {
bool llctoningutili = false; clToningcurve (65536);
CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); cl2Toningcurve (65536);
CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
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); CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16);
double rrm, ggm, bbm; double rrm, ggm, bbm;
float autor, autog, autob; float autor, autog, autob;
float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; 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); LabImage* labView = new LabImage (fw, fh);
DCPProfile *dcpProf = NULL; DCPProfile *dcpProf = NULL;
if (isRaw) { if (isRaw) {
cmsHPROFILE dummy; cmsHPROFILE dummy;
RawImageSource::findInputProfile(params.icm.input, NULL, camName, &dcpProf, 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); 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); 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 // freeing up some memory
@ -1100,7 +1100,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
hist16[CLIP((int)((labView->L[i][j])))]++; 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]))]++; hist16C[CLIP((int)sqrt(labView->a[i][j]*labView->a[i][j] + labView->b[i][j]*labView->b[i][j]))]++;
} }
// luminance processing // luminance processing
// ipf.EPDToneMap(labView,0,6); // ipf.EPDToneMap(labView,0,6);
@ -1110,9 +1109,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
bool ccutili = false; bool ccutili = false;
bool cclutili = false; bool cclutili = false;
bool clcutili = false; bool clcutili = false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, 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); 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.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); 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);} //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) { 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; int begh = 0, endh = labView->H;
bool execsharp = false; bool execsharp = false;
float d; float d;

View File

@ -771,10 +771,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf curve (65536, 0); LUTf curve (65536, 0);
LUTf satcurve (65536, 0); LUTf satcurve (65536, 0);
LUTf lhskcurve (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 clcurve (65536, 0);
LUTf clToningcurve (65536, 0); LUTf clToningcurve;
LUTf cl2Toningcurve (65536, 0); LUTf cl2Toningcurve;
LUTf wavclCurve (65536, 0); LUTf wavclCurve (65536, 0);
LUTf rCurve (65536, 0); LUTf rCurve (65536, 0);
@ -814,11 +814,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
bool opautili = false; bool opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
bool clctoningutili = false; if(params.colorToning.enabled) {
CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, 1); clToningcurve (65536, 0);
bool llctoningutili = false; CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1);
CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, 1); cl2Toningcurve (65536, 0);
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1);
}
LabImage* labView = new LabImage (fw, fh); 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 if(params.labCurve.contrast != 0) { //only use hist16 for contrast
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel shared(hist16,labView, fh, fw) #pragma omp parallel
#endif #endif
{ {
LUTu hist16thr (65536); // one temporary lookup table per thread LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread
hist16thr.clear(); hist16thr.clear();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for schedule(static) nowait #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 i = 0; i < fh; i++)
for (int j = 0; j < fw; j++) for (int j = 0; j < fw; j++)
{ {
hist16thr[CLIP((int)((labView->L[i][j])))]++; hist16thr[(int)((labView->L[i][j]))]++;
} }
#pragma omp critical #pragma omp critical
{ {
for(int i = 0; i < 65536; i++) hist16 += hist16thr;
{
hist16[i] += hist16thr[i];
}
} }
} }
} }
bool utili = false; 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, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve,
hist16C, hist16C, dummy, dummy, hist16C, hist16C, dummy, dummy,
1); 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); 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; begh = 0;
endh = fh; endh = fh;
CurveFactory::curveLightBrightColor ( CurveFactory::curveLightBrightColor (
params.colorappearance.curveMode, params.colorappearance.curve, params.colorappearance.curve,
params.colorappearance.curveMode2, params.colorappearance.curve2, params.colorappearance.curve2,
params.colorappearance.curveMode3, params.colorappearance.curve3, params.colorappearance.curve3,
hist16, hist16, dummy, hist16, dummy,
hist16C, dummy, hist16C, dummy,
customColCurve1, customColCurve1,
customColCurve2, customColCurve2,

View File

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