Speedup for thumbnail and editor processing, also reduced base memory usage a bit

This commit is contained in:
heckflosse 2016-05-06 21:51:57 +02:00
parent aa5072fa0a
commit 6646c2dc5c
11 changed files with 430 additions and 519 deletions

View File

@ -64,10 +64,10 @@
#define LUT_CLIP_ABOVE 2 #define LUT_CLIP_ABOVE 2
#define LUTf LUT<float> #define LUTf LUT<float>
#define LUTi LUT<int> #define LUTi LUT<int32_t>
#define LUTu LUT<unsigned int> #define LUTu LUT<uint32_t>
#define LUTd LUT<double> #define LUTd LUT<double>
#define LUTuc LUT<unsigned char> #define LUTuc LUT<uint8_t>
#include <cstring> #include <cstring>
#ifndef NDEBUG #ifndef NDEBUG
@ -155,41 +155,6 @@ public:
#endif #endif
} }
LUT(int s, T * source, int flags = 0xfffffff)
{
#ifndef NDEBUG
if (s <= 0) {
printf("s<=0!\n");
}
assert (s > 0);
if (!source) {
printf("source is NULL!\n");
}
assert (source != nullptr);
#endif
dirty = false; // Assumption
clip = flags;
data = new T[s];
owner = 1;
size = s;
upperBound = size - 1;
maxs = size - 2;
maxsf = (float)maxs;
#if defined( __SSE2__ ) && defined( __x86_64__ )
maxsv = F2V( size - 2);
sizeiv = _mm_set1_epi32( (int)(size - 1) );
sizev = F2V( size - 1 );
#endif
for (int i = 0; i < s; i++) {
data[i] = source[i];
}
}
LUT() LUT()
{ {
data = nullptr; data = nullptr;
@ -224,7 +189,7 @@ public:
* For a LUT(500), it will return 499, because 500 elements, starting from 0, goes up to 499 * For a LUT(500), it will return 499, because 500 elements, starting from 0, goes up to 499
* @return number of element in the array * @return number of element in the array
*/ */
int getUpperBound() unsigned int getUpperBound() const
{ {
return size > 0 ? upperBound : 0; return size > 0 ? upperBound : 0;
} }
@ -258,7 +223,8 @@ public:
return *this; return *this;
} }
// handy to sum up per thread histograms. #pragma omp simd speeds up the loop by about factor 3 for LUTu (unsigned int). // handy to sum up per thread histograms. #pragma omp simd speeds up the loop by about factor 3 for LUTu (uint32_t).
template<typename U = T, typename = typename std::enable_if<std::is_same<U, std::uint32_t>::value>::type>
LUT<T> & operator+=(LUT<T> &rhs) LUT<T> & operator+=(LUT<T> &rhs)
{ {
if (rhs.size == this->size) { if (rhs.size == this->size) {
@ -274,7 +240,8 @@ public:
return *this; return *this;
} }
// mutliply all elements of LUT with a constant float value // multiply all elements of LUT<float> with a constant float value
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
LUT<float> & operator*=(float factor) LUT<float> & operator*=(float factor)
{ {
#ifdef _OPENMP #ifdef _OPENMP
@ -362,6 +329,7 @@ public:
} }
*/ */
#ifdef __SSE4_1__ #ifdef __SSE4_1__
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
vfloat operator[](vint idxv ) const vfloat operator[](vint idxv ) const
{ {
vfloat tempv, p1v; vfloat tempv, p1v;
@ -401,6 +369,7 @@ public:
return p1v; return p1v;
} }
#else #else
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
vfloat operator[](vint idxv ) const vfloat operator[](vint idxv ) const
{ {
vfloat tempv, p1v; vfloat tempv, p1v;
@ -445,6 +414,7 @@ public:
#endif #endif
// use with float indices // use with float indices
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
T operator[](float index) const T operator[](float index) const
{ {
int idx = (int)index; // don't use floor! The difference in negative space is no problems here int idx = (int)index; // don't use floor! The difference in negative space is no problems here
@ -470,9 +440,10 @@ public:
} }
// Return the value for "index" that is in the [0-1] range. // Return the value for "index" that is in the [0-1] range.
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
T getVal01 (float index) const T getVal01 (float index) const
{ {
index *= float(upperBound); index *= (float)upperBound;
int idx = (int)index; // don't use floor! The difference in negative space is no problems here int idx = (int)index; // don't use floor! The difference in negative space is no problems here
if (index < 0.f) { if (index < 0.f) {
@ -542,6 +513,7 @@ public:
} }
// create an identity LUT (LUT(x) = x) or a scaled identity LUT (LUT(x) = x / divisor) // create an identity LUT (LUT(x) = x) or a scaled identity LUT (LUT(x) = x / divisor)
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
void makeIdentity(float divisor = 1.f) void makeIdentity(float divisor = 1.f)
{ {
if(divisor == 1.f) { if(divisor == 1.f) {
@ -555,9 +527,11 @@ public:
} }
} }
// compress a LUT with size y into a LUT with size y (y<x) // compress a LUT<uint32_t> with size y into a LUT<uint32_t> with size x (y>x)
void compressTo(LUT<T> &dest, unsigned int numVals) const template<typename U = T, typename = typename std::enable_if<std::is_same<U, std::uint32_t>::value>::type>
void compressTo(LUT<T> &dest, unsigned int numVals = 0) const
{ {
numVals = numVals == 0 ? size : numVals;
numVals = std::min(numVals, size); numVals = std::min(numVals, size);
float divisor = numVals - 1; float divisor = numVals - 1;
float mult = (dest.size - 1) / divisor; float mult = (dest.size - 1) / divisor;
@ -568,7 +542,8 @@ public:
} }
} }
// compress a LUT with size y into a LUT with size y (y<x) by using the passTrough LUT to calculate indexes // compress a LUT<uint32_t> with size y into a LUT<uint32_t> with size x (y>x) by using the passTrough LUT to calculate indexes
template<typename U = T, typename = typename std::enable_if<std::is_same<U, std::uint32_t>::value>::type>
void compressTo(LUT<T> &dest, unsigned int numVals, const LUT<float> &passThrough) const void compressTo(LUT<T> &dest, unsigned int numVals, const LUT<float> &passThrough) const
{ {
if(passThrough) { if(passThrough) {
@ -583,15 +558,74 @@ public:
} }
} }
// compute sum and average of a LUT<uint32_t>
template<typename U = T, typename = typename std::enable_if<std::is_same<U, std::uint32_t>::value>::type>
void getSumAndAverage(float &sum, float &avg) const
{
sum = 0.f;
avg = 0.f;
int i = 0;
#ifdef __SSE2__
vfloat iv = _mm_set_ps(3.f, 2.f, 1.f, 0.f);
vfloat fourv = F2V(4.f);
vint sumv = (vint)ZEROV;
vfloat avgv = ZEROV;
for(; i < size - 3; i += 4) {
vint datav = _mm_loadu_si128((__m128i*)&data[i]);
sumv += datav;
avgv += iv * _mm_cvtepi32_ps(datav);
iv += fourv;
}
sum = vhadd(_mm_cvtepi32_ps(sumv));
avg = vhadd(avgv);
#endif
for (; i < size; i++) {
T val = data[i];
sum += val;
avg += i * val;
}
avg /= sum;
}
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
void makeConstant(float value, unsigned int numVals = 0) void makeConstant(float value, unsigned int numVals = 0)
{ {
numVals = numVals == 0 ? size : numVals; numVals = numVals == 0 ? size : numVals;
numVals = std::min(numVals, size); numVals = std::min(numVals, size);
for(unsigned int i = 0; i < numVals; i++) { for(unsigned int i = 0; i < numVals; i++) {
data[i] = value; data[i] = value;
} }
} }
// share the buffer with another LUT, handy for same data but different clip flags
void share(const LUT<T> &source, int flags = 0xfffffff)
{
if (owner && data) {
delete[] data;
}
dirty = false; // Assumption
clip = flags;
data = source.data;
owner = 0;
size = source.getSize();
upperBound = size - 1;
maxs = size - 2;
maxsf = (float)maxs;
#if defined( __SSE2__ ) && defined( __x86_64__ )
maxsv = F2V( size - 2);
sizeiv = _mm_set1_epi32( (int)(size - 1) );
sizev = F2V( size - 1 );
#endif
}
}; };

View File

@ -139,7 +139,6 @@ void Color::init ()
constexpr auto maxindex = 65536; constexpr auto maxindex = 65536;
cachef(maxindex, LUT_CLIP_BELOW); cachef(maxindex, LUT_CLIP_BELOW);
gamma2curve(maxindex, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
gammatab(maxindex, 0); gammatab(maxindex, 0);
gammatabThumb(maxindex, 0); gammatabThumb(maxindex, 0);
@ -185,11 +184,14 @@ void Color::init ()
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp section #pragma omp section
#endif #endif
{
for (int i = 0; i < maxindex; i++) { for (int i = 0; i < maxindex; i++)
gammatab_srgb[i] = gamma2curve[i] = 65535.0 * gamma2(i / 65535.0); // two lookup tables with same content but one clips and one does not clip {
gammatab_srgb[i] = 65535.0 * gamma2(i / 65535.0);
} }
gamma2curve.share(gammatab_srgb, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); // shares the buffer with gammatab_srgb but has different clip flags
}
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp section #pragma omp section
#endif #endif

View File

@ -294,34 +294,20 @@ void CurveFactory::curveBW ( const std::vector<double>& curvePointsbw, const std
} }
// add curve Lab : C=f(L) // add curve Lab : C=f(L)
void CurveFactory::curveCL ( bool & clcutili, const std::vector<double>& clcurvePoints, LUTf & clCurve, const LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip) void CurveFactory::curveCL ( bool & clcutili, const std::vector<double>& clcurvePoints, LUTf & clCurve, int skip)
{ {
bool needed = false; bool needed = false;
DiagonalCurve* dCurve = nullptr; DiagonalCurve* dCurve = nullptr;
if (outBeforeCLurveHistogram) {
outBeforeCLurveHistogram.clear();
}
bool histNeededCL = false;
if (!clcurvePoints.empty() && clcurvePoints[0] != 0) { if (!clcurvePoints.empty() && clcurvePoints[0] != 0) {
dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS / skip); dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS / skip);
if (outBeforeCLurveHistogram) {
histNeededCL = true;
}
if (dCurve && !dCurve->isIdentity()) { if (dCurve && !dCurve->isIdentity()) {
needed = true; needed = true;
clcutili = true; clcutili = true;
} }
} }
if(histNeededCL) {
histogramcl.compressTo(outBeforeCLurveHistogram, 50000);
}
fillCurveArray(dCurve, clCurve, skip, needed); fillCurveArray(dCurve, clCurve, skip, needed);
if (dCurve) { if (dCurve) {
@ -621,34 +607,40 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double
#ifdef __SSE2__ #ifdef __SSE2__
int i = shoulder + 1; int i = shoulder + 1;
if(i&1) { // original formula, slower than optimized formulas below but only used once or none, so I let it as is for reference
if(i & 1) { // original formula, slower than optimized formulas below but only used once or none, so I let it as is for reference
// change to [0,1] range // change to [0,1] range
float val = (float)i - shoulder; float val = (float)i - shoulder;
float R = val * comp / (scalemshoulder); float R = val * comp / (scalemshoulder);
hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision
i++; i++;
} }
vdouble onev = _mm_set1_pd(1.0); vdouble onev = _mm_set1_pd(1.0);
vdouble Rv = _mm_set_pd((i+1-shoulder) * (double)comp/ scalemshoulder,(i-shoulder) * (double)comp/ scalemshoulder); vdouble Rv = _mm_set_pd((i + 1 - shoulder) * (double)comp / scalemshoulder, (i - shoulder) * (double)comp / scalemshoulder);
vdouble incrementv = _mm_set1_pd(2.0 * comp / scalemshoulder); vdouble incrementv = _mm_set1_pd(2.0 * comp / scalemshoulder);
vdouble exp_scalev = _mm_set1_pd(exp_scale); vdouble exp_scalev = _mm_set1_pd(exp_scale);
for (; i < 0x10000; i+=2) {
for (; i < 0x10000; i += 2) {
// change to [0,1] range // change to [0,1] range
vdouble resultv = xlog(onev + Rv * exp_scalev) / Rv; vdouble resultv = xlog(onev + Rv * exp_scalev) / Rv;
vfloat resultfv = _mm_cvtpd_ps(resultv); vfloat resultfv = _mm_cvtpd_ps(resultv);
_mm_store_ss(&hlCurve[i], resultfv); _mm_store_ss(&hlCurve[i], resultfv);
resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1,1,1,1)); resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1, 1, 1, 1));
_mm_store_ss(&hlCurve[i+1], resultfv); _mm_store_ss(&hlCurve[i + 1], resultfv);
Rv += incrementv; Rv += incrementv;
} }
#else #else
float R = comp / scalemshoulder; float R = comp / scalemshoulder;
float increment = R; float increment = R;
for (int i = shoulder + 1; i < 0x10000; i++) { for (int i = shoulder + 1; i < 0x10000; i++) {
// change to [0,1] range // change to [0,1] range
hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision hlCurve[i] = xlog(1.0 + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision
R += increment; R += increment;
} }
#endif #endif
} }
@ -674,8 +666,9 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double
// store result in a temporary array // store result in a temporary array
dcurve[0] = CLIPD(val); dcurve[0] = CLIPD(val);
#ifdef _OPENMP
#pragma omp parallel for //schedule(dynamic,2048) #pragma omp parallel for
#endif
for (int i = 1; i < 0x10000; i++) { for (int i = 1; i < 0x10000; i++) {
float val = i / 65535.f; float val = i / 65535.f;
@ -792,17 +785,21 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double
vfloat mulv = F2V(mul); vfloat mulv = F2V(mul);
vfloat addv = F2V(add); vfloat addv = F2V(add);
vfloat c65535v = F2V(65535.f); vfloat c65535v = F2V(65535.f);
for (int i = 0; i <= 0xffff; i+=4) {
for (int i = 0; i <= 0xffff; i += 4) {
vfloat valv = LVFU(dcurve[i]); vfloat valv = LVFU(dcurve[i]);
valv = igamma (valv, gamma_v, startv, slopev, mulv, addv); valv = igamma (valv, gamma_v, startv, slopev, mulv, addv);
STVFU(outCurve[i],c65535v * valv); STVFU(outCurve[i], c65535v * valv);
} }
#else #else
for (int i = 0; i <= 0xffff; i++) { for (int i = 0; i <= 0xffff; i++) {
float val = dcurve[i]; float val = dcurve[i];
val = igamma (val, gamma_, start, slope, mul, add); val = igamma (val, gamma_, start, slope, mul, add);
outCurve[i] = (65535.f * val); outCurve[i] = (65535.f * val);
} }
#endif #endif
if (histNeeded) { if (histNeeded) {
@ -827,7 +824,7 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void CurveFactory::complexLCurve (double br, double contr, const std::vector<double>& curvePoints, void CurveFactory::complexLCurve (double br, double contr, const std::vector<double>& curvePoints,
const LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve, const LUTu & histogram, LUTf & outCurve,
LUTu & outBeforeCCurveHistogram, int skip, bool & utili) LUTu & outBeforeCCurveHistogram, int skip, bool & utili)
{ {
// curve without contrast // curve without contrast
@ -962,7 +959,7 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vector<dou
if (!curvePoints.empty() && curvePoints[0] != 0) { if (!curvePoints.empty() && curvePoints[0] != 0) {
tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS / skip); tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS / skip);
if (outBeforeCCurveHistogram /*&& histogramCropped*/) { if (outBeforeCCurveHistogram) {
histNeeded = true; histNeeded = true;
} }
} }

View File

@ -286,7 +286,7 @@ public:
static void curveBW (const std::vector<double>& curvePointsbw, const std::vector<double>& curvePointsbw2, const 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, const LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip); static void curveCL ( bool & clcutili, const std::vector<double>& clcurvePoints, LUTf & clCurve, 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, const LUTu & histogram, LUTu & outBeforeCurveHistogram); static void curveDehaContL ( bool & dehacontlutili, const std::vector<double>& dehaclcurvePoints, LUTf & dehaclCurve, int skip, const LUTu & histogram, LUTu & outBeforeCurveHistogram);
@ -298,8 +298,7 @@ public:
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,
const LUTu & histogramC, const 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, const LUTu & histogram, LUTu & histogramCropped, static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, const LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili);
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili);
static void curveLightBrightColor ( static void curveLightBrightColor (
const std::vector<double>& curvePoints, const std::vector<double>& curvePoints,

View File

@ -814,7 +814,7 @@ void Crop::update (int todo)
LUTu dummy; LUTu dummy;
int moderetinex; int moderetinex;
// parent->ipf.MSR(labnCrop, labnCrop->W, labnCrop->H, 1); // parent->ipf.MSR(labnCrop, labnCrop->W, labnCrop->H, 1);
parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy);
parent->ipf.vibrance (labnCrop); parent->ipf.vibrance (labnCrop);
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) {

View File

@ -23,7 +23,9 @@
#include "../rtgui/ppversion.h" #include "../rtgui/ppversion.h"
#include "colortemp.h" #include "colortemp.h"
#include "improcfun.h" #include "improcfun.h"
#ifdef _OPENMP
#include <omp.h>
#endif
namespace rtengine namespace rtengine
{ {
@ -52,12 +54,11 @@ ImProcCoordinator::ImProcCoordinator ()
Noisecurve(65536, 0), Noisecurve(65536, 0),
NoiseCCcurve(65536, 0), NoiseCCcurve(65536, 0),
vhist16(65536), vhist16bw(65536), vhist16(65536), vhist16bw(65536),
lhist16(65536), lhist16Cropped(65536),
lhist16CAM(65536), lhist16CAM(65536),
lhist16CCAM(65536), lhist16CCAM(65536),
lhist16RETI(65536), lhist16RETI(65536),
histCropped(65536), histCropped(65536),
lhist16Clad(65536), lhist16CLlad(65536), lhist16Clad(65536),
lhist16LClad(65536), lhist16LLClad(65536), lhist16LClad(65536), lhist16LLClad(65536),
histRed(256), histRedRaw(256), histRed(256), histRedRaw(256),
histGreen(256), histGreenRaw(256), histGreen(256), histGreenRaw(256),
@ -67,7 +68,6 @@ ImProcCoordinator::ImProcCoordinator ()
histToneCurveBW(256), histToneCurveBW(256),
histLCurve(256), histLCurve(256),
histCCurve(256), histCCurve(256),
histCLurve(256),
histLLCurve(256), histLLCurve(256),
histLCAM(256), histLCAM(256),
@ -366,7 +366,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
*/ */
imgsrc->convertColorSpace(orig_prev, params.icm, currWB); imgsrc->convertColorSpace(orig_prev, params.icm, currWB);
ipf.firstAnalysis (orig_prev, &params, vhist16); ipf.firstAnalysis (orig_prev, params, vhist16);
} }
readyphase++; readyphase++;
@ -450,6 +450,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1);
opautili = false;
if(params.colorToning.enabled) {
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]},
@ -462,16 +465,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
{wiprof[1][0], wiprof[1][1], wiprof[1][2]}, {wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]} {wiprof[2][0], wiprof[2][1], wiprof[2][2]}
}; };
opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
if(params.colorToning.enabled) {
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
// clToningcurve.dump("CLToning3");
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); 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);
if(params.blackwhite.enabled) {
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1);
}
float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f;
float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f);
@ -559,31 +560,39 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
} }
// compute L channel histogram // compute L channel histogram
int x1, y1, x2, y2, pos; 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);
lhist16.clear();
lhist16Cropped.clear();
lhist16Clad.clear();
lhist16CLlad.clear();
lhist16LLClad.clear();
for (int x = 0; x < pH; x++)
for (int y = 0; y < pW; y++) {
pos = CLIP((int)(oprevl->L[x][y]));
lhist16[pos]++;
if (y >= y1 && y < y2 && x >= x1 && x < x2) {
lhist16Cropped[pos]++;
}
}
} }
readyphase++; readyphase++;
if ((todo & M_LUMACURVE) || (todo & M_CROP)) { if (todo & (M_LUMACURVE | M_CROP)) {
LUTu lhist16(32768);
lhist16.clear();
#ifdef _OPENMP
const int numThreads = min(max(pW * pH / (int)lhist16.getSize(), 1), omp_get_max_threads());
#pragma omp parallel num_threads(numThreads) if(numThreads>1)
#endif
{
LUTu lhist16thr(lhist16.getSize());
lhist16thr.clear();
#ifdef _OPENMP
#pragma omp for nowait
#endif
for (int x = 0; x < pH; x++)
for (int y = 0; y < pW; y++) {
int pos = (int)(oprevl->L[x][y]);
lhist16thr[pos]++;
}
#ifdef _OPENMP
#pragma omp critical
#endif
lhist16 += lhist16thr;
}
utili = false; utili = false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped, CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lumacurve, histLCurve, scale == 1 ? 1 : 16, utili);
lumacurve, histLCurve, scale == 1 ? 1 : 16, utili);
} }
if (todo & M_LUMACURVE) { if (todo & M_LUMACURVE) {
@ -593,7 +602,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
cclutili = false; cclutili = false;
clcutili = false; clcutili = false;
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, lhist16CLlad, histCLurve, scale == 1 ? 1 : 16); CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, scale == 1 ? 1 : 16);
float adjustr = 1.0f; float adjustr = 1.0f;
@ -605,6 +614,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
else if (params.icm.working=="BestRGB") {adjustr = adjustbg = 1.4f;} else if (params.icm.working=="BestRGB") {adjustr = adjustbg = 1.4f;}
else if (params.icm.working=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;} else if (params.icm.working=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;}
*/ */
lhist16LLClad.clear();
lhist16Clad.clear();
CurveFactory::complexsgnCurve (adjustr, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, CurveFactory::complexsgnCurve (adjustr, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, params.labCurve.lccurve, chroma_acurve, chroma_bcurve, satcurve, lhskcurve,
lhist16Clad, lhist16LLClad, histCCurve, histLLCurve, scale == 1 ? 1 : 16); lhist16Clad, lhist16LLClad, histCCurve, histLLCurve, scale == 1 ? 1 : 16);
@ -615,8 +627,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
progress ("Applying Color Boost...", 100 * readyphase / numofphases); progress ("Applying Color Boost...", 100 * readyphase / numofphases);
// ipf.MSR(nprevl, nprevl->W, nprevl->H, 1); // ipf.MSR(nprevl, nprevl->W, nprevl->H, 1);
ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLLCurve, histLCurve);
ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histCLurve, histLLCurve, histLCurve);
ipf.vibrance(nprevl); ipf.vibrance(nprevl);
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) {
@ -678,7 +689,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
wavcontlutili = false; wavcontlutili = false;
//CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); //CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip);
CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve , /*lhist16CLlad, histCLurve,*/ scale == 1 ? 1 : 16); CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve, scale == 1 ? 1 : 16);
if((params.wavelet.enabled)) { if((params.wavelet.enabled)) {
@ -1291,7 +1302,6 @@ void ImProcCoordinator::startProcessing(int changeCode)
void ImProcCoordinator::process () void ImProcCoordinator::process ()
{ {
if (plistener) { if (plistener) {
plistener->setProgressState (true); plistener->setProgressState (true);
} }

View File

@ -107,7 +107,6 @@ protected:
LUTf NoiseCCcurve; LUTf NoiseCCcurve;
LUTu vhist16, vhist16bw; LUTu vhist16, vhist16bw;
LUTu lhist16, lhist16Cropped;
LUTu lhist16CAM; LUTu lhist16CAM;
LUTu lhist16CCAM; LUTu lhist16CCAM;
LUTu lhist16RETI; LUTu lhist16RETI;
@ -116,7 +115,7 @@ protected:
LUTu histRed, histRedRaw; LUTu histRed, histRedRaw;
LUTu histGreen, histGreenRaw; LUTu histGreen, histGreenRaw;
LUTu histBlue, histBlueRaw; LUTu histBlue, histBlueRaw;
LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve, histCLurve; LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve;
LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma, histLRETI; LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma, histLRETI;
LUTf CAMBrightCurveJ, CAMBrightCurveQ; LUTf CAMBrightCurveJ, CAMBrightCurveQ;

View File

@ -73,34 +73,6 @@ void ImProcFunctions::setScale (double iscale)
scale = iscale; scale = iscale;
} }
// Called from several threads
void ImProcFunctions::firstAnalysisThread (Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to)
{
TMatrix wprof = iccStore->workingSpaceMatrix (wprofile);
lumimul[0] = wprof[1][0];
lumimul[1] = wprof[1][1];
lumimul[2] = wprof[1][2];
int W = original->width;
for (int i = row_from; i < row_to; i++) {
for (int j = 0; j < W; j++) {
int r = original->r(i, j);
int g = original->g(i, j);
int b = original->b(i, j);
int y = CLIP((int)(lumimul[0] * r + lumimul[1] * g + lumimul[2] * b)) ;
if (histogram) {
histogram[y]++;
}
}
}
}
void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent) void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent)
{ {
// set up monitor transform // set up monitor transform
@ -148,59 +120,67 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con
#endif #endif
} }
void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) void ImProcFunctions::firstAnalysis (const Imagefloat* const original, const ProcParams &params, LUTu & histogram)
{ {
Glib::ustring wprofile = params->icm.working; TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
lumimul[0] = wprof[1][0];
lumimul[1] = wprof[1][1];
lumimul[2] = wprof[1][2];
int W = original->width;
int H = original->height;
float lumimulf[3] = {static_cast<float>(lumimul[0]), static_cast<float>(lumimul[1]), static_cast<float>(lumimul[2])};
// calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments
int T = 1;
#ifdef _OPENMP
if(multiThread) {
T = omp_get_max_threads();
}
#endif
unsigned int** hist = new unsigned int* [T];
for (int i = 0; i < T; i++) {
hist[i] = new unsigned int[65536];
memset (hist[i], 0, 65536 * sizeof(int));
}
#ifdef _OPENMP
#pragma omp parallel if (multiThread)
{
int H = original->height;
int tid = omp_get_thread_num();
int nthreads = omp_get_num_threads();
int blk = H / nthreads;
if (tid < nthreads - 1) {
firstAnalysisThread (original, wprofile, hist[tid], tid * blk, (tid + 1)*blk);
} else {
firstAnalysisThread (original, wprofile, hist[tid], tid * blk, H);
}
}
#else
firstAnalysisThread (original, wprofile, hist[0], 0, original->height);
#endif
histogram.clear(); histogram.clear();
for (int j = 0; j < T; j++) if(multiThread) {
for (int i = 0; i < 65536; i++) {
histogram[i] += hist[j][i]; #ifdef _OPENMP
const int numThreads = min(max(W * H / (int)histogram.getSize(), 1), omp_get_max_threads());
#pragma omp parallel num_threads(numThreads) if(numThreads>1)
#endif
{
LUTu hist(histogram.getSize());
hist.clear();
#ifdef _OPENMP
#pragma omp for nowait
#endif
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++) {
float r = original->r(i, j);
float g = original->g(i, j);
float b = original->b(i, j);
int y = (lumimulf[0] * r + lumimulf[1] * g + lumimulf[2] * b);
hist[y]++;
}
} }
for (int i = 0; i < T; i++) { #ifdef _OPENMP
delete [] hist[i]; #pragma omp critical
} #endif
histogram += hist;
delete [] hist; }
} else {
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
float r = original->r(i, j);
float g = original->g(i, j);
float b = original->b(i, j);
int y = (lumimulf[0] * r + lumimulf[1] * g + lumimulf[2] * b);
histogram[y]++;
}
}
}
} }
// Copyright (c) 2012 Jacques Desmis <jdesmis@gmail.com> // Copyright (c) 2012 Jacques Desmis <jdesmis@gmail.com>
@ -1468,34 +1448,14 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
MyTime t1e, t2e; MyTime t1e, t2e;
t1e.set(); t1e.set();
#endif #endif
LUTf dLcurve;
LUTu hist16JCAM;
float val;
//preparate for histograms CIECAM //preparate for histograms CIECAM
if(pW != 1) { //only with improccoordinator LUTu hist16JCAM;
dLcurve(65536, 0); LUTu hist16_CCAM;
dLcurve.clear(); if(pW != 1 && params->colorappearance.datacie) { //only with improccoordinator
hist16JCAM(65536); hist16JCAM(32768);
hist16JCAM.clear(); hist16JCAM.clear();
hist16_CCAM(48000);
for (int i = 0; i < 32768; i++) { //# 32768*1.414 approximation maxi for chroma
val = (double)i / 32767.0;
dLcurve[i] = CLIPD(val);
}
}
LUTf dCcurve(65536, 0);
LUTu hist16_CCAM(65536);
bool chropC = false;
float valc;
if(pW != 1) { //only with improccoordinator
for (int i = 0; i < 48000; i++) { //# 32768*1.414 approximation maxi for chroma
valc = (double)i / 47999.0;
dCcurve[i] = CLIPD(valc);
}
hist16_CCAM.clear(); hist16_CCAM.clear();
} }
@ -1513,8 +1473,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
bool algepd = false; bool algepd = false;
float sum = 0.f; float sum = 0.f;
const bool ciedata = (params->colorappearance.datacie && pW != 1); const bool epdEnabled = params->epd.enabled;
bool jp = ciedata; bool ciedata = (params->colorappearance.datacie && pW != 1) && !((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp)
|| (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab)
|| (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab));
ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB
@ -1732,19 +1694,19 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
hist16Q.clear(); hist16Q.clear();
} }
const int numThreads = min(max(width*height / 65536,1),omp_get_max_threads()); const int numThreads = min(max(width * height / 65536, 1), omp_get_max_threads());
#pragma omp parallel num_threads(numThreads) if(numThreads>1) #pragma omp parallel num_threads(numThreads) if(numThreads>1)
{ {
LUTu hist16Jthr; LUTu hist16Jthr;
LUTu hist16Qthr; LUTu hist16Qthr;
if (needJ) { if (needJ) {
hist16Jthr (32768); hist16Jthr(hist16J.getSize());
hist16Jthr.clear(); hist16Jthr.clear();
} }
if (needQ) { if (needQ) {
hist16Qthr(32768); hist16Qthr(hist16Q.getSize());
hist16Qthr.clear(); hist16Qthr.clear();
} }
@ -1802,11 +1764,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
#pragma omp critical #pragma omp critical
{ {
if(needJ) if(needJ) {
hist16J += hist16Jthr; hist16J += hist16Jthr;
}
if(needQ) if(needQ) {
hist16Q += hist16Qthr; hist16Q += hist16Qthr;
}
} }
} }
@ -1864,9 +1828,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
} else { } else {
yb = 90.0f; yb = 90.0f;
} }
} } else if(settings->viewinggreySc == 1) {
if(settings->viewinggreySc == 1) {
yb = 18.0f; //fixed yb = 18.0f; //fixed
} }
@ -1911,7 +1873,6 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
const float f_l = fl; const float f_l = fl;
const float coe = pow_F(fl, 0.25f); const float coe = pow_F(fl, 0.25f);
const float QproFactor = ( 0.4f / c ) * ( aw + 4.0f ) ; const float QproFactor = ( 0.4f / c ) * ( aw + 4.0f ) ;
const bool epdEnabled = params->epd.enabled;
const bool LabPassOne = !((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp) const bool LabPassOne = !((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp)
|| (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab)
|| (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab));
@ -2391,57 +2352,38 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
if(!params->colorappearance.tonecie || !settings->autocielab || !epdEnabled) { if(!params->colorappearance.tonecie || !settings->autocielab || !epdEnabled) {
if(ciedata) { if(ciedata) { //only with improccoordinator
// Data for J Q M s and C histograms // Data for J Q M s and C histograms
int posl, posc; int posl, posc;
float brli = 327.f; float brli = 327.f;
float chsacol = 327.f; float chsacol = 327.f;
int libr = 0; float libr;
int colch = 0; float colch;
//update histogram
if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) {
brli = 70.0f; brli = 70.0f;
libr = 1; libr = Q; //40.0 to 100.0 approximative factor for Q - 327 for J
} else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) { } else /*if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT)*/ {
brli = 327.f; brli = 327.f;
libr = 0; libr = J; //327 for J
} }
posl = (int)(libr * brli);
hist16JCAM[posl]++;
if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) { if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) {
chsacol = 327.f; chsacol = 327.f;
colch = 0; colch = C; //450.0 approximative factor for s 320 for M
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { } else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) {
chsacol = 450.0f; chsacol = 450.0f;
colch = 1; colch = s;
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { } else /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ {
chsacol = 327.0f; chsacol = 327.0f;
colch = 2; colch = M;
} }
posc = (int)(colch * chsacol);
//update histogram
if(pW != 1) { //only with improccoordinator
if(libr == 1) {
posl = CLIP((int)(Q * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J
} else if(libr == 0) {
posl = CLIP((int)(J * brli)); //327 for J
}
hist16JCAM[posl]++;
}
chropC = true;
if(pW != 1) { //only with improccoordinator
if(colch == 0) {
posc = CLIP((int)(C * chsacol)); //450.0 approximative factor for s 320 for M
} else if(colch == 1) {
posc = CLIP((int)(s * chsacol));
} else if(colch == 2) {
posc = CLIP((int)(M * chsacol));
}
hist16_CCAM[posc]++; hist16_CCAM[posc]++;
}
} }
if(LabPassOne) { if(LabPassOne) {
@ -2586,21 +2528,9 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
if(ciedata) { if(ciedata) {
//update histogram J //update histogram J
for (int i = 0; i < 32768; i++) { // hist16JCAM.compressTo(histLCAM);
if (jp) { //update histogram C
float hval = dLcurve[i]; hist16_CCAM.compressTo(histCCAM);
int hi = (int)(255.0f * CLIPD(hval)); //
histLCAM[hi] += hist16JCAM[i] ;
}
}
for (int i = 0; i < 48000; i++) { //
if (chropC) {
float hvalc = dCcurve[i];
int hic = (int)(255.0f * CLIPD(hvalc)); //
histCCAM[hic] += hist16_CCAM[i] ;
}
}
} }
} }
@ -2732,6 +2662,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
|| (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab)
|| (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)) { || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)) {
ciedata = (params->colorappearance.datacie && pW != 1);
if(epdEnabled && params->colorappearance.tonecie && algepd) { if(epdEnabled && params->colorappearance.tonecie && algepd) {
lab->deleteLab(); lab->deleteLab();
ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale ); ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale );
@ -2786,55 +2717,32 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
int posl, posc; int posl, posc;
float brli = 327.f; float brli = 327.f;
float chsacol = 327.f; float chsacol = 327.f;
int libr = 0; float libr;
int colch = 0; float colch;
float sa_t;
if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) {
brli = 70.0f; brli = 70.0f;
libr = 1; libr = ncie->Q_p[i][j]; //40.0 to 100.0 approximative factor for Q - 327 for J
} else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) { } else /*if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT)*/ {
brli = 327.f; brli = 327.f;
libr = 0; libr = ncie->J_p[i][j]; //327 for J
} }
posl = (int)(libr * brli);
hist16JCAM[posl]++;
if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) { if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) {
chsacol = 327.f; chsacol = 327.f;
colch = 0; colch = ncie_C_p;
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) { } else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) {
chsacol = 450.0f; chsacol = 450.0f;
colch = 1; colch = 100.f * sqrtf(ncie_C_p / ncie->Q_p[i][j]);
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) { } else /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ {
chsacol = 327.0f; chsacol = 327.0f;
colch = 2; colch = ncie->M_p[i][j];
} }
posc = (int)(colch * chsacol);
//update histogram
if(pW != 1) { //only with improccoordinator
if(libr == 1) {
posl = CLIP((int)(ncie->Q_p[i][j] * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J
} else if(libr == 0) {
posl = CLIP((int)(ncie->J_p[i][j] * brli)); //327 for J
}
hist16JCAM[posl]++;
}
chropC = true;
if(pW != 1) { //only with improccoordinator
if(colch == 0) {
posc = CLIP((int)(ncie_C_p * chsacol)); //450.0 approximative factor for s 320 for M
} else if(colch == 1) {
sa_t = 100.f * sqrtf(ncie_C_p / ncie->Q_p[i][j]); //Q_p always > 0
posc = CLIP((int)(sa_t * chsacol));
} else if(colch == 2) {
posc = CLIP((int)(ncie->M_p[i][j] * chsacol));
}
hist16_CCAM[posc]++; hist16_CCAM[posc]++;
} }
}
//end histograms //end histograms
@ -2959,26 +2867,14 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
//show CIECAM histograms //show CIECAM histograms
if(ciedata) { if(ciedata) {
//update histogram J and Q //update histogram J and Q
for (int i = 0; i < 32768; i++) { // //update histogram J
if (jp) { hist16JCAM.compressTo(histLCAM);
float hval = dLcurve[i];
int hi = (int)(255.0f * CLIPD(hval)); //
histLCAM[hi] += hist16JCAM[i] ;
}
}
//update color histogram M,s,C //update color histogram M,s,C
for (int i = 0; i < 48000; i++) { // hist16_CCAM.compressTo(histCCAM);
if (chropC) {
float hvalc = dCcurve[i];
int hic = (int)(255.0f * CLIPD(hvalc)); //
histCCAM[hic] += hist16_CCAM[i] ;
} }
} }
} }
}
}
} }
//end CIECAM //end CIECAM
@ -3215,7 +3111,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
ClutPtr colorLUT; ClutPtr colorLUT;
bool clutAndWorkingProfilesAreSame = false; bool clutAndWorkingProfilesAreSame = false;
TMatrix work2xyz, xyz2clut, clut2xyz, xyz2work; TMatrix xyz2clut, clut2xyz;
if ( params->filmSimulation.enabled && !params->filmSimulation.clutFilename.empty() ) { if ( params->filmSimulation.enabled && !params->filmSimulation.clutFilename.empty() ) {
colorLUT.set( clutStore.getClut( params->filmSimulation.clutFilename ) ); colorLUT.set( clutStore.getClut( params->filmSimulation.clutFilename ) );
@ -3224,9 +3120,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
clutAndWorkingProfilesAreSame = colorLUT->profile() == params->icm.working; clutAndWorkingProfilesAreSame = colorLUT->profile() == params->icm.working;
if ( !clutAndWorkingProfilesAreSame ) { if ( !clutAndWorkingProfilesAreSame ) {
work2xyz = iccStore->workingSpaceMatrix( params->icm.working );
xyz2clut = iccStore->workingSpaceInverseMatrix( colorLUT->profile() ); xyz2clut = iccStore->workingSpaceInverseMatrix( colorLUT->profile() );
xyz2work = iccStore->workingSpaceInverseMatrix( params->icm.working );
clut2xyz = iccStore->workingSpaceMatrix( colorLUT->profile() ); clut2xyz = iccStore->workingSpaceMatrix( colorLUT->profile() );
} }
} }
@ -4338,7 +4232,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (!clutAndWorkingProfilesAreSame) { if (!clutAndWorkingProfilesAreSame) {
//convert from working to clut profile //convert from working to clut profile
float x, y, z; float x, y, z;
Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz ); Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, wprof );
Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut ); Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut );
} }
@ -4362,7 +4256,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
//convert from clut to working profile //convert from clut to working profile
float x, y, z; float x, y, z;
Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz );
Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, wiprof );
} }
} }
@ -5517,9 +5411,8 @@ 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 &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");
@ -5605,31 +5498,15 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
} }
} }
LUTf dCcurve;
LUTf dLcurve;
LUTu hist16Clad; LUTu hist16Clad;
LUTu hist16Llad; LUTu hist16Llad;
//preparate for histograms CIECAM //preparate for histograms CIECAM
if(pW != 1) { //only with improccoordinator if(pW != 1) { //only with improccoordinator
dCcurve(48000, 0);
dLcurve(65536, 0);
hist16Clad(65536); hist16Clad(65536);
hist16Llad(65536);
float val;
for (int i = 0; i < 48000; i++) { //# 32768*1.414 approximation maxi for chroma
val = (double)i / 47999.0;
dCcurve[i] = CLIPD(val);
}
for (int i = 0; i < 65535; i++) { // a
val = (double)i / 65534.0;
dLcurve[i] = CLIPD(val);
}
hist16Clad.clear(); hist16Clad.clear();
hist16Llad(65536);
hist16Llad.clear(); hist16Llad.clear();
} }
@ -6125,7 +6002,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
//update histogram C //update histogram C
if(pW != 1) { //only with improccoordinator if(pW != 1) { //only with improccoordinator
int posp = CLIP((int)sqrt((atmp * atmp + btmp * btmp))); int posp = (int)sqrt(atmp * atmp + btmp * btmp);
hist16Clad[posp]++; hist16Clad[posp]++;
} }
@ -6181,7 +6058,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
//update histo LC //update histo LC
if(pW != 1) { //only with improccoordinator if(pW != 1) { //only with improccoordinator
int posl = CLIP((int(Lprov1 * 327.68f))); int posl = Lprov1 * 327.68f;
hist16Llad[posl]++; hist16Llad[posl]++;
} }
@ -6269,20 +6146,11 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
} }
} // end of parallelization } // end of parallelization
//update histogram C with data chromaticity and not with CC curve
if(pW != 1) { //only with improccoordinator if(pW != 1) { //only with improccoordinator
for (int i = 0; i < 48000; i++) { //32768*1.414 + ... //update histogram C with data chromaticity and not with CC curve
float hval = dCcurve[i]; hist16Clad.compressTo(histCCurve);
int hi = (int)(255.0 * CLIPD(hval)); //
histCCurve[hi] += hist16Clad[i] ;
}
//update histogram L with data luminance //update histogram L with data luminance
for (int i = 0; i < 65535; i++) { hist16Llad.compressTo(histLCurve);
float hlval = dLcurve[i];
int hli = (int)(255.0 * CLIPD(hlval));
histLCurve[hli] += hist16Llad[i] ;
}
} }
#ifdef _DEBUG #ifdef _DEBUG
@ -6683,15 +6551,15 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip)
#pragma omp parallel for // removed schedule(dynamic,10) #pragma omp parallel for // removed schedule(dynamic,10)
#endif #endif
for(int ii = 0; ii < N; ii++) for(int ii = 0; ii < N; ii++) {
a[ii] *= s, a[ii] *= s;
b[ii] *= s, b[ii] *= s;
//L[ii] = L[ii]*32767.0f*(1.f/gamm) + minL;
L[ii] = L[ii] * maxL * (1.f / gamm) + minL; L[ii] = L[ii] * maxL * (1.f / gamm) + minL;
}
} }
void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double defgain, double clip,
double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh) double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh)
{ {
@ -6704,12 +6572,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
float ave = 0.f, hidev = 0.f, lodev = 0.f; float ave = 0.f, hidev = 0.f, lodev = 0.f;
//find average luminance //find average luminance
for (int i = 0; i < imax; i++) { histogram.getSumAndAverage(sum, ave);
sum += histogram[i];
ave += histogram[i] * (float)i;
}
ave /= (sum);
//find median of luminance //find median of luminance
int median = 0, count = histogram[0]; int median = 0, count = histogram[0];
@ -6734,25 +6597,35 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
float octile[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}, ospread = 0.f; float octile[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}, ospread = 0.f;
count = 0; count = 0;
for (int i = 0; i < imax; i++) { int i = 0;
for (; i < min((int)ave,imax); i++) {
if (count < 8) { if (count < 8) {
octile[count] += histogram[i]; octile[count] += histogram[i];
if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) { if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) {
octile[count] = log(1. + (float)i) / log(2.f); octile[count] = xlog(1. + (float)i) / log(2.f);
count++;// = min(count+1,7); count++;// = min(count+1,7);
} }
} }
if (i < ave) {
//lodev += SQR(ave-i)*histogram[i]; //lodev += SQR(ave-i)*histogram[i];
lodev += (log(ave + 1.f) - log((float)i + 1.)) * histogram[i]; lodev += (xlog(ave + 1.f) - xlog((float)i + 1.)) * histogram[i];
losum += histogram[i]; losum += histogram[i];
} else {
//hidev += SQR(i-ave)*histogram[i];
hidev += (log((float)i + 1.) - log(ave + 1.f)) * histogram[i];
hisum += histogram[i];
} }
for (; i < imax; i++) {
if (count < 8) {
octile[count] += histogram[i];
if (octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f)) {
octile[count] = xlog(1. + (float)i) / log(2.f);
count++;// = min(count+1,7);
}
}
//hidev += SQR(i-ave)*histogram[i];
hidev += (xlog((float)i + 1.) - xlog(ave + 1.f)) * histogram[i];
hisum += histogram[i];
} }
if (losum == 0 || hisum == 0) { //probably the image is a blackframe if (losum == 0 || hisum == 0) { //probably the image is a blackframe
@ -6815,7 +6688,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
int clipped = 0; int clipped = 0;
int rawmax = (imax) - 1; int rawmax = (imax) - 1;
while (rawmax > 1 && histogram[rawmax] + clipped <= 0) { while (histogram[rawmax] + clipped <= 0 && rawmax > 1) {
clipped += histogram[rawmax]; clipped += histogram[rawmax];
rawmax--; rawmax--;
} }
@ -6907,11 +6780,15 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
//take gamma into account //take gamma into account
double whiteclipg = (int)(CurveFactory::gamma2 (whiteclip * corr / 65536.0) * 65536.0); double whiteclipg = (int)(CurveFactory::gamma2 (whiteclip * corr / 65536.0) * 65536.0);
double gavg = 0.; float gavg = 0.;
for (int i = 0; i<65536 >> histcompr; i++) { float val = 0.f;
gavg += histogram[i] * CurveFactory::gamma2((float)(corr * (i << histcompr) < 65535 ? corr * (i << histcompr) : 65535)) / sum; float increment = corr * (1 << histcompr);
for (int i = 0; i < 65536 >> histcompr; i++) {
gavg += histogram[i] * Color::gamma2curve[val];
val += increment;
} }
gavg /= sum;
if (black < gavg) { if (black < gavg) {
int maxwhiteclip = (gavg - black) * 4 / 3 + black; // dont let whiteclip be such large that the histogram average goes above 3/4 int maxwhiteclip = (gavg - black) * 4 / 3 + black; // dont let whiteclip be such large that the histogram average goes above 3/4
@ -6981,6 +6858,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
} }
bright = max(-100, min(bright, 100)); bright = max(-100, min(bright, 100));
} }
@ -7101,6 +6979,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst,
wipv[i][j] = F2V(wiprof[i][j]); wipv[i][j] = F2V(wiprof[i][j]);
} }
} }
#endif #endif
#ifdef _OPENMP #ifdef _OPENMP
@ -7110,9 +6989,10 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst,
for(int i = 0; i < H; i++) { for(int i = 0; i < H; i++) {
int j = 0; int j = 0;
#ifdef __SSE2__ #ifdef __SSE2__
for(; j < W - 3; j += 4) { for(; j < W - 3; j += 4) {
vfloat X, Y, Z; vfloat X, Y, Z;
vfloat R,G,B; vfloat R, G, B;
Color::Lab2XYZ(LVFU(src.L[i][j]), LVFU(src.a[i][j]), LVFU(src.b[i][j]), X, Y, Z); Color::Lab2XYZ(LVFU(src.L[i][j]), LVFU(src.a[i][j]), LVFU(src.b[i][j]), X, Y, Z);
Color::xyz2rgb(X, Y, Z, R, G, B, wipv); Color::xyz2rgb(X, Y, Z, R, G, B, wipv);
STVFU(dst.r(i, j), R); STVFU(dst.r(i, j), R);
@ -7121,6 +7001,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst,
} }
#endif #endif
for(; j < W; j++) { for(; j < W; j++) {
float X, Y, Z; float X, Y, Z;
Color::Lab2XYZ(src.L[i][j], src.a[i][j], src.b[i][j], X, Y, Z); Color::Lab2XYZ(src.L[i][j], src.a[i][j], src.b[i][j], X, Y, Z);

View File

@ -75,7 +75,6 @@ class ImProcFunctions
void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, int W, int H, const SharpeningParams &sharpenParam); void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, int W, int H, const SharpeningParams &sharpenParam);
void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H, SharpeningParams &sharpenParam); void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H, SharpeningParams &sharpenParam);
void sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float** base, int W, int H); void sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float** base, int W, int H);
void firstAnalysisThread(Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to);
void dcdamping (float** aI, float** aO, float damping, int W, int H); void dcdamping (float** aI, float** aO, float damping, int W, int H);
bool needsCA (); bool needsCA ();
@ -229,7 +228,7 @@ public:
bool needsTransform (); bool needsTransform ();
bool needsPCVignetting (); bool needsPCVignetting ();
void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); void firstAnalysis (const Imagefloat* const working, const ProcParams &params, LUTu & vhist16);
void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent); void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent);
void rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, void rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
@ -255,7 +254,7 @@ public:
void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params,
const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3,
LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, int scalecd, int rtt); LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, int scalecd, int rtt);
void chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve, LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLCurve, LUTu &histLurve); void chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve, LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLCurve, LUTu &histLurve);
void vibrance (LabImage* lab);//Jacques' vibrance void vibrance (LabImage* lab);//Jacques' vibrance
void colorCurve (LabImage* lold, LabImage* lnew); void colorCurve (LabImage* lold, LabImage* lnew);
void sharpening (LabImage* lab, float** buffer, SharpeningParams &sharpenParam); void sharpening (LabImage* lab, float** buffer, SharpeningParams &sharpenParam);
@ -377,7 +376,7 @@ public:
bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL);
bool transCoord (int W, int H, const std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL); bool transCoord (int W, int H, const std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL);
static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); static void getAutoExp (const LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh);
static double getAutoDistor (const Glib::ustring& fname, int thumb_size); static double getAutoDistor (const Glib::ustring& fname, int thumb_size);
double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL); double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL);
void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace); void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace);

View File

@ -32,7 +32,6 @@
#include "rawimagesource.h" #include "rawimagesource.h"
#include "stdimagesource.h" #include "stdimagesource.h"
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <csetjmp>
#include "rawimage.h" #include "rawimage.h"
#include "jpeg.h" #include "jpeg.h"
#include "../rtgui/ppversion.h" #include "../rtgui/ppversion.h"
@ -54,7 +53,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h,
StdImageSource imgSrc; StdImageSource imgSrc;
if (imgSrc.load(fname)) { if (imgSrc.load(fname)) {
return NULL; return nullptr;
} }
ImageIO* img = imgSrc.getImageIO(); ImageIO* img = imgSrc.getImageIO();
@ -96,7 +95,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h,
// bilinear interpolation // bilinear interpolation
if (tpp->thumbImg) { if (tpp->thumbImg) {
delete tpp->thumbImg; delete tpp->thumbImg;
tpp->thumbImg = NULL; tpp->thumbImg = nullptr;
} }
if (inspectorMode) { if (inspectorMode) {
@ -161,7 +160,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
if( r ) { if( r ) {
delete ri; delete ri;
return NULL; return nullptr;
} }
rml.exifBase = ri->get_exifBase(); rml.exifBase = ri->get_exifBase();
@ -192,7 +191,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
printf("Could not extract thumb from %s\n", fname.data()); printf("Could not extract thumb from %s\n", fname.data());
delete img; delete img;
delete ri; delete ri;
return NULL; return nullptr;
} }
Thumbnail* tpp = new Thumbnail (); Thumbnail* tpp = new Thumbnail ();
@ -220,7 +219,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
if (tpp->thumbImg) { if (tpp->thumbImg) {
delete tpp->thumbImg; delete tpp->thumbImg;
tpp->thumbImg = NULL; tpp->thumbImg = nullptr;
} }
if (inspectorMode) { if (inspectorMode) {
@ -289,7 +288,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
if( r ) { if( r ) {
delete ri; delete ri;
return NULL; return nullptr;
} }
int width = ri->get_width(); int width = ri->get_width();
@ -297,8 +296,8 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
rtengine::Thumbnail* tpp = new rtengine::Thumbnail; rtengine::Thumbnail* tpp = new rtengine::Thumbnail;
tpp->isRaw = true; tpp->isRaw = true;
tpp->embProfile = NULL; tpp->embProfile = nullptr;
tpp->embProfileData = NULL; tpp->embProfileData = nullptr;
tpp->embProfileLength = ri->get_profileLen(); tpp->embProfileLength = ri->get_profileLen();
if (ri->get_profileLen()) if (ri->get_profileLen())
@ -502,7 +501,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
delete tpp->thumbImg; delete tpp->thumbImg;
} }
tpp->thumbImg = NULL; tpp->thumbImg = nullptr;
tpp->thumbImg = resizeTo<Image16>(w, h, TI_Bilinear, tmpImg); tpp->thumbImg = resizeTo<Image16>(w, h, TI_Bilinear, tmpImg);
delete tmpImg; delete tmpImg;
@ -737,11 +736,11 @@ void Thumbnail::init ()
} }
Thumbnail::Thumbnail () : Thumbnail::Thumbnail () :
camProfile(NULL), thumbImg(NULL), camProfile(nullptr), thumbImg(nullptr),
camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0), camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0),
redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0),
autoWBTemp(2700), autoWBGreen(1.0), wbEqual(-1.0), autoWBTemp(2700), autoWBGreen(1.0), wbEqual(-1.0),
embProfileLength(0), embProfileData(NULL), embProfile(NULL), embProfileLength(0), embProfileData(nullptr), embProfile(nullptr),
redMultiplier(1.0), greenMultiplier(1.0), blueMultiplier(1.0), redMultiplier(1.0), greenMultiplier(1.0), blueMultiplier(1.0),
defGain(1.0), defGain(1.0),
scaleForSave(8192), scaleForSave(8192),
@ -935,10 +934,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent); ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent);
LUTu hist16 (65536); LUTu hist16 (65536);
LUTu hist16C (65536);
double gamma = isRaw ? Color::sRGBGamma : 0; // usually in ImageSource, but we don't have that here double gamma = isRaw ? Color::sRGBGamma : 0; // usually in ImageSource, but we don't have that here
ipf.firstAnalysis (baseImg, &params, hist16); ipf.firstAnalysis (baseImg, params, hist16);
// perform transform // perform transform
if (ipf.needsTransform()) { if (ipf.needsTransform()) {
@ -953,7 +951,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
} }
// update blurmap // update blurmap
SHMap* shmap = NULL; SHMap* shmap = nullptr;
if (params.sh.enabled) { if (params.sh.enabled) {
shmap = new SHMap (fw, fh, false); shmap = new SHMap (fw, fh, false);
@ -976,7 +974,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
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);
} }
LUTf curve1 (65536); LUTf curve1 (65536);
@ -989,17 +986,11 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LUTf clcurve (65536); LUTf clcurve (65536);
LUTf clToningcurve; LUTf clToningcurve;
LUTf cl2Toningcurve; LUTf cl2Toningcurve;
LUTf rCurve (65536);
LUTf gCurve (65536);
LUTf bCurve (65536);
LUTu dummy; LUTu dummy;
ToneCurve customToneCurve1, customToneCurve2; ToneCurve customToneCurve1, customToneCurve2;
ColorGradientCurve ctColorCurve; ColorGradientCurve ctColorCurve;
OpacityCurve ctOpacityCurve; OpacityCurve ctOpacityCurve;
// NoisCurve dnNoisCurve;
ColorAppearance customColCurve1; ColorAppearance customColCurve1;
ColorAppearance customColCurve2; ColorAppearance customColCurve2;
@ -1012,9 +1003,15 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
params.toneCurve.curveMode2, params.toneCurve.curve2, params.toneCurve.curveMode2, params.toneCurve.curve2,
hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16); hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16);
LUTf rCurve;
LUTf gCurve;
LUTf bCurve;
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);
bool opautili = false;
if(params.colorToning.enabled) {
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]},
@ -1027,18 +1024,19 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
{wiprof[1][0], wiprof[1][1], wiprof[1][2]}, {wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]} {wiprof[2][0], wiprof[2][1], wiprof[2][2]}
}; };
bool opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
//params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili);
if(params.colorToning.enabled) {
clToningcurve (65536); clToningcurve (65536);
cl2Toningcurve (65536);
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
cl2Toningcurve (65536);
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
} }
if(params.blackwhite.enabled) {
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;
@ -1067,23 +1065,22 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
autor = autog = autob = -9000.f; // This will ask to compute the "auto" values for the B&W tool autor = autog = autob = -9000.f; // This will ask to compute the "auto" values for the B&W tool
LabImage* labView = new LabImage (fw, fh); LabImage* labView = new LabImage (fw, fh);
DCPProfile *dcpProf = NULL; DCPProfile *dcpProf = nullptr;
if (isRaw) { if (isRaw) {
cmsHPROFILE dummy; cmsHPROFILE dummy;
RawImageSource::findInputProfile(params.icm.input, NULL, camName, &dcpProf, dummy); RawImageSource::findInputProfile(params.icm.input, nullptr, camName, &dcpProf, dummy);
if (dcpProf != NULL) { if (dcpProf) {
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, nullptr, 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
customToneCurve1.Reset(); customToneCurve1.Reset();
customToneCurve2.Reset(); customToneCurve2.Reset();
ctColorCurve.Reset(); ctColorCurve.Reset();
ctOpacityCurve.Reset(); ctOpacityCurve.Reset();
// dnNoisCurve.Reset();
customToneCurvebw1.Reset(); customToneCurvebw1.Reset();
customToneCurvebw2.Reset(); customToneCurvebw2.Reset();
@ -1092,36 +1089,34 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
} }
// luminance histogram update // luminance histogram update
if(params.labCurve.contrast != 0) {
hist16.clear(); hist16.clear();
hist16C.clear();
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++) {
hist16[CLIP((int)((labView->L[i][j])))]++; hist16[(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 // luminance processing
// ipf.EPDToneMap(labView,0,6); // ipf.EPDToneMap(labView,0,6);
bool utili = false; bool utili = false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,
hist16, lumacurve, dummy, 16, utili);
bool clcutili = false;
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 16);
bool autili = false; bool autili = false;
bool butili = false; bool butili = false;
bool ccutili = false; bool ccutili = false;
bool cclutili = false; bool cclutili = false;
bool clcutili = false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,
hist16, hist16, lumacurve, dummy, 16, utili);
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 16);
CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
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, dummy, dummy, dummy, dummy,
16); 16);
//ipf.luminanceCurve (labView, labView, curve);
ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, 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);
@ -1129,16 +1124,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ipf.EPDToneMap(labView, 5, 6); ipf.EPDToneMap(labView, 5, 6);
} }
//if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);}
if(params.colorappearance.enabled) { if(params.colorappearance.enabled) {
CurveFactory::curveLightBrightColor ( CurveFactory::curveLightBrightColor (
params.colorappearance.curve, params.colorappearance.curve,
params.colorappearance.curve2, params.colorappearance.curve2,
params.colorappearance.curve3, params.colorappearance.curve3,
hist16, dummy, hist16, dummy,
hist16C, dummy, dummy, dummy,
customColCurve1, customColCurve1,
customColCurve2, customColCurve2,
customColCurve3, customColCurve3,
@ -1219,7 +1211,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight, float &ratio) int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight, float &ratio)
{ {
if (thumbImg == NULL) { if (!thumbImg) {
return 0; // Can happen if thumb is just building and GUI comes in with resize wishes return 0; // Can happen if thumb is just building and GUI comes in with resize wishes
} }
@ -1371,11 +1363,11 @@ void Thumbnail::transformPixel (int x, int y, int tran, int& tx, int& ty)
unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width) unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width)
{ {
if (!thumbImg) { if (!thumbImg) {
return NULL; return nullptr;
} }
if (thumbImg->width < trim_width) { if (thumbImg->width < trim_width) {
return NULL; return nullptr;
} }
// to utilize the 8 bit color range of the thumbnail we brighten it and apply gamma correction // to utilize the 8 bit color range of the thumbnail we brighten it and apply gamma correction
@ -1659,7 +1651,7 @@ bool Thumbnail::readImage (const Glib::ustring& fname)
if (thumbImg) { if (thumbImg) {
delete thumbImg; delete thumbImg;
thumbImg = NULL; thumbImg = nullptr;
} }
Glib::ustring fullFName = fname + ".rtti"; Glib::ustring fullFName = fname + ".rtti";
@ -1872,8 +1864,8 @@ bool Thumbnail::readEmbProfile (const Glib::ustring& fname)
FILE* f = g_fopen (fname.c_str (), "rb"); FILE* f = g_fopen (fname.c_str (), "rb");
if (!f) { if (!f) {
embProfileData = NULL; embProfileData = nullptr;
embProfile = NULL; embProfile = nullptr;
embProfileLength = 0; embProfileLength = 0;
} else { } else {
fseek (f, 0, SEEK_END); fseek (f, 0, SEEK_END);
@ -1945,7 +1937,7 @@ unsigned char* Thumbnail::getImage8Data()
return img8->data; return img8->data;
} }
return NULL; return nullptr;
} }

View File

@ -726,9 +726,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// perform first analysis // perform first analysis
LUTu hist16 (65536); LUTu hist16 (65536);
LUTu hist16C (65536);
ipf.firstAnalysis (baseImg, &params, hist16); ipf.firstAnalysis (baseImg, params, hist16);
// perform transform (excepted resizing) // perform transform (excepted resizing)
if (ipf.needsTransform()) { if (ipf.needsTransform()) {
@ -777,9 +776,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf cl2Toningcurve; LUTf cl2Toningcurve;
LUTf wavclCurve (65536, 0); LUTf wavclCurve (65536, 0);
LUTf rCurve (65536, 0); LUTf rCurve;
LUTf gCurve (65536, 0); LUTf gCurve;
LUTf bCurve (65536, 0); LUTf bCurve;
LUTu dummy; LUTu dummy;
ToneCurve customToneCurve1, customToneCurve2; ToneCurve customToneCurve1, customToneCurve2;
@ -798,23 +797,22 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1); CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); bool opautili = false;
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
if(params.colorToning.enabled) {
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]},
{wprof[1][0], wprof[1][1], wprof[1][2]}, {wprof[1][0], wprof[1][1], wprof[1][2]},
{wprof[2][0], wprof[2][1], wprof[2][2]} {wprof[2][0], wprof[2][1], wprof[2][2]}
}; };
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
double wip[3][3] = { double wip[3][3] = {
{wiprof[0][0], wiprof[0][1], wiprof[0][2]}, {wiprof[0][0], wiprof[0][1], wiprof[0][2]},
{wiprof[1][0], wiprof[1][1], wiprof[1][2]}, {wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]} {wiprof[2][0], wiprof[2][1], wiprof[2][2]}
}; };
bool opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
if(params.colorToning.enabled) {
clToningcurve (65536, 0); clToningcurve (65536, 0);
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1); CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1);
cl2Toningcurve (65536, 0); cl2Toningcurve (65536, 0);
@ -822,8 +820,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
} }
LabImage* labView = new LabImage (fw, fh); LabImage* labView = new LabImage (fw, fh);
if(params.blackwhite.enabled) {
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1);
}
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;
@ -889,10 +888,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// start tile processing...??? // start tile processing...???
hist16.clear();
hist16C.clear();
if(params.labCurve.contrast != 0) { //only use hist16 for contrast if(params.labCurve.contrast != 0) { //only use hist16 for contrast
hist16.clear();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel #pragma omp parallel
@ -918,21 +916,21 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
} }
bool utili = false; bool utili = false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, lumacurve, dummy, 1, utili);
bool clcutili = false;
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1);
bool autili = false; bool autili = false;
bool butili = false; bool butili = false;
bool ccutili = false; bool ccutili = false;
bool cclutili = false; bool cclutili = false;
bool clcutili = false;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, lumacurve, dummy, 1, utili);
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 1);
CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
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, dummy, dummy, dummy, dummy,
1); 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);
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) {
ipf.EPDToneMap(labView, 5, 1); ipf.EPDToneMap(labView, 5, 1);
@ -1024,7 +1022,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
params.colorappearance.curve2, params.colorappearance.curve2,
params.colorappearance.curve3, params.colorappearance.curve3,
hist16, dummy, hist16, dummy,
hist16C, dummy, dummy, dummy,
customColCurve1, customColCurve1,
customColCurve2, customColCurve2,
customColCurve3, customColCurve3,