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 LUTf LUT<float>
#define LUTi LUT<int>
#define LUTu LUT<unsigned int>
#define LUTi LUT<int32_t>
#define LUTu LUT<uint32_t>
#define LUTd LUT<double>
#define LUTuc LUT<unsigned char>
#define LUTuc LUT<uint8_t>
#include <cstring>
#ifndef NDEBUG
@ -155,41 +155,6 @@ public:
#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()
{
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
* @return number of element in the array
*/
int getUpperBound()
unsigned int getUpperBound() const
{
return size > 0 ? upperBound : 0;
}
@ -258,7 +223,8 @@ public:
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)
{
if (rhs.size == this->size) {
@ -274,7 +240,8 @@ public:
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)
{
#ifdef _OPENMP
@ -362,6 +329,7 @@ public:
}
*/
#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 tempv, p1v;
@ -401,6 +369,7 @@ public:
return p1v;
}
#else
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
vfloat operator[](vint idxv ) const
{
vfloat tempv, p1v;
@ -445,6 +414,7 @@ public:
#endif
// 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
{
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.
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
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
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)
template<typename U = T, typename = typename std::enable_if<std::is_same<U, float>::value>::type>
void makeIdentity(float 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)
void compressTo(LUT<T> &dest, unsigned int numVals) const
// compress a LUT<uint32_t> with size y into a LUT<uint32_t> with size x (y>x)
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);
float divisor = numVals - 1;
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
{
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)
{
numVals = numVals == 0 ? size : numVals;
numVals = std::min(numVals, size);
for(unsigned int i = 0; i < numVals; i++) {
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;
cachef(maxindex, LUT_CLIP_BELOW);
gamma2curve(maxindex, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
gammatab(maxindex, 0);
gammatabThumb(maxindex, 0);
@ -185,11 +184,14 @@ void Color::init ()
#ifdef _OPENMP
#pragma omp section
#endif
{
for (int i = 0; i < maxindex; i++)
{
gammatab_srgb[i] = 65535.0 * gamma2(i / 65535.0);
}
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
gamma2curve.share(gammatab_srgb, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); // shares the buffer with gammatab_srgb but has different clip flags
}
#ifdef _OPENMP
#pragma omp section
#endif

View File

@ -294,34 +294,20 @@ void CurveFactory::curveBW ( const std::vector<double>& curvePointsbw, const std
}
// 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;
DiagonalCurve* dCurve = nullptr;
if (outBeforeCLurveHistogram) {
outBeforeCLurveHistogram.clear();
}
bool histNeededCL = false;
if (!clcurvePoints.empty() && clcurvePoints[0] != 0) {
dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS / skip);
if (outBeforeCLurveHistogram) {
histNeededCL = true;
}
if (dCurve && !dCurve->isIdentity()) {
needed = true;
clcutili = true;
}
}
if(histNeededCL) {
histogramcl.compressTo(outBeforeCLurveHistogram, 50000);
}
fillCurveArray(dCurve, clCurve, skip, needed);
if (dCurve) {
@ -543,15 +529,15 @@ void CurveFactory::complexsgnCurve (float adjustr, bool & autili, bool & butili
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh,
double shcompr, double br, double contr,
procparams::ToneCurveParams::eTCModeId curveMode, const std::vector<double>& curvePoints,
procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
LUTu & histogram, LUTu & histogramCropped,
LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve,
LUTu & outBeforeCCurveHistogram,
ToneCurve & customToneCurve1,
ToneCurve & customToneCurve2,
int skip)
double shcompr, double br, double contr,
procparams::ToneCurveParams::eTCModeId curveMode, const std::vector<double>& curvePoints,
procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
LUTu & histogram, LUTu & histogramCropped,
LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve,
LUTu & outBeforeCCurveHistogram,
ToneCurve & customToneCurve1,
ToneCurve & customToneCurve2,
int skip)
{
// the curve shapes are defined in sRGB gamma, but the output curves will operate on linear floating point data,
@ -621,34 +607,40 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double
#ifdef __SSE2__
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
float val = (float)i - shoulder;
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
i++;
}
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 exp_scalev = _mm_set1_pd(exp_scale);
for (; i < 0x10000; i+=2) {
for (; i < 0x10000; i += 2) {
// change to [0,1] range
vdouble resultv = xlog(onev + Rv * exp_scalev) / Rv;
vfloat resultfv = _mm_cvtpd_ps(resultv);
_mm_store_ss(&hlCurve[i], resultfv);
resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1,1,1,1));
_mm_store_ss(&hlCurve[i+1], resultfv);
resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1, 1, 1, 1));
_mm_store_ss(&hlCurve[i + 1], resultfv);
Rv += incrementv;
}
#else
float R = comp / scalemshoulder;
float increment = R;
for (int i = shoulder + 1; i < 0x10000; i++) {
// 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
R += increment;
}
#endif
}
@ -674,8 +666,9 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double
// store result in a temporary array
dcurve[0] = CLIPD(val);
#pragma omp parallel for //schedule(dynamic,2048)
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i = 1; i < 0x10000; i++) {
float val = i / 65535.f;
@ -792,17 +785,21 @@ SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double
vfloat mulv = F2V(mul);
vfloat addv = F2V(add);
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]);
valv = igamma (valv, gamma_v, startv, slopev, mulv, addv);
STVFU(outCurve[i],c65535v * valv);
STVFU(outCurve[i], c65535v * valv);
}
#else
for (int i = 0; i <= 0xffff; i++) {
float val = dcurve[i];
val = igamma (val, gamma_, start, slope, mul, add);
outCurve[i] = (65535.f * val);
}
#endif
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,
const LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve,
const LUTu & histogram, LUTf & outCurve,
LUTu & outBeforeCCurveHistogram, int skip, bool & utili)
{
// curve without contrast
@ -962,7 +959,7 @@ void CurveFactory::complexLCurve (double br, double contr, const std::vector<dou
if (!curvePoints.empty() && curvePoints[0] != 0) {
tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS / skip);
if (outBeforeCCurveHistogram /*&& histogramCropped*/) {
if (outBeforeCCurveHistogram) {
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,
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 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 LUTu & histogramC, const LUTu & histogramLC, LUTu & outBeforeCCurveHistogram, LUTu & outBeforeLCurveHistogram, ///for chroma
int skip = 1);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, const LUTu & histogram, LUTu & histogramCropped,
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, const LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili);
static void curveLightBrightColor (
const std::vector<double>& curvePoints,

View File

@ -814,7 +814,7 @@ void Crop::update (int todo)
LUTu dummy;
int moderetinex;
// 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);
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) {

View File

@ -23,7 +23,9 @@
#include "../rtgui/ppversion.h"
#include "colortemp.h"
#include "improcfun.h"
#ifdef _OPENMP
#include <omp.h>
#endif
namespace rtengine
{
@ -52,12 +54,11 @@ ImProcCoordinator::ImProcCoordinator ()
Noisecurve(65536, 0),
NoiseCCcurve(65536, 0),
vhist16(65536), vhist16bw(65536),
lhist16(65536), lhist16Cropped(65536),
lhist16CAM(65536),
lhist16CCAM(65536),
lhist16RETI(65536),
histCropped(65536),
lhist16Clad(65536), lhist16CLlad(65536),
lhist16Clad(65536),
lhist16LClad(65536), lhist16LLClad(65536),
histRed(256), histRedRaw(256),
histGreen(256), histGreenRaw(256),
@ -67,7 +68,6 @@ ImProcCoordinator::ImProcCoordinator ()
histToneCurveBW(256),
histLCurve(256),
histCCurve(256),
histCLurve(256),
histLLCurve(256),
histLCAM(256),
@ -366,7 +366,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
*/
imgsrc->convertColorSpace(orig_prev, params.icm, currWB);
ipf.firstAnalysis (orig_prev, &params, vhist16);
ipf.firstAnalysis (orig_prev, params, vhist16);
}
readyphase++;
@ -450,28 +450,29 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
{wprof[1][0], wprof[1][1], wprof[1][2]},
{wprof[2][0], wprof[2][1], wprof[2][2]}
};
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
double wip[3][3] = {
{wiprof[0][0], wiprof[0][1], wiprof[0][2]},
{wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]}
};
opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
if(params.colorToning.enabled) {
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
{wprof[1][0], wprof[1][1], wprof[1][2]},
{wprof[2][0], wprof[2][1], wprof[2][2]}
};
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
double wip[3][3] = {
{wiprof[0][0], wiprof[0][1], wiprof[0][2]},
{wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]}
};
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
// clToningcurve.dump("CLToning3");
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
}
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1);
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 satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f);
@ -559,31 +560,39 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
// 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);
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++;
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;
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped,
lumacurve, histLCurve, scale == 1 ? 1 : 16, utili);
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lumacurve, histLCurve, scale == 1 ? 1 : 16, utili);
}
if (todo & M_LUMACURVE) {
@ -593,7 +602,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
cclutili = 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;
@ -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=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;}
*/
lhist16LLClad.clear();
lhist16Clad.clear();
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,
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);
// 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, histCLurve, histLLCurve, histLCurve);
ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLLCurve, histLCurve);
ipf.vibrance(nprevl);
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) {
@ -678,7 +689,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
wavcontlutili = false;
//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)) {
@ -709,7 +720,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int posc = CLIP((int)sqrt(nprevl->a[x][y] * nprevl->a[x][y] + nprevl->b[x][y] * nprevl->b[x][y]));
lhist16CAM[pos]++;
lhist16CCAM[posc]++;
}
}
}
CurveFactory::curveLightBrightColor (params.colorappearance.curve, params.colorappearance.curve2, params.colorappearance.curve3,
@ -1291,7 +1302,6 @@ void ImProcCoordinator::startProcessing(int changeCode)
void ImProcCoordinator::process ()
{
if (plistener) {
plistener->setProgressState (true);
}

View File

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

View File

@ -73,34 +73,6 @@ void ImProcFunctions::setScale (double 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)
{
// set up monitor transform
@ -148,59 +120,67 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con
#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
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();
for (int j = 0; j < T; j++)
for (int i = 0; i < 65536; i++) {
histogram[i] += hist[j][i];
if(multiThread) {
#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]++;
}
}
#ifdef _OPENMP
#pragma omp critical
#endif
histogram += hist;
}
} else {
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
for (int i = 0; i < T; i++) {
delete [] hist[i];
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]++;
}
}
}
delete [] hist;
}
// Copyright (c) 2012 Jacques Desmis <jdesmis@gmail.com>
@ -1468,38 +1448,18 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
MyTime t1e, t2e;
t1e.set();
#endif
LUTf dLcurve;
LUTu hist16JCAM;
float val;
//preparate for histograms CIECAM
if(pW != 1) { //only with improccoordinator
dLcurve(65536, 0);
dLcurve.clear();
hist16JCAM(65536);
LUTu hist16JCAM;
LUTu hist16_CCAM;
if(pW != 1 && params->colorappearance.datacie) { //only with improccoordinator
hist16JCAM(32768);
hist16JCAM.clear();
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(48000);
hist16_CCAM.clear();
}
//end preparate histogram
//end preparate histogram
int width = lab->W, height = lab->H;
float minQ = 10000.f;
float maxQ = -1000.f;
@ -1513,8 +1473,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
bool algepd = false;
float sum = 0.f;
const bool ciedata = (params->colorappearance.datacie && pW != 1);
bool jp = ciedata;
const bool epdEnabled = params->epd.enabled;
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
@ -1732,19 +1694,19 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
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)
{
LUTu hist16Jthr;
LUTu hist16Qthr;
if (needJ) {
hist16Jthr (32768);
hist16Jthr(hist16J.getSize());
hist16Jthr.clear();
}
if (needQ) {
hist16Qthr(32768);
hist16Qthr(hist16Q.getSize());
hist16Qthr.clear();
}
@ -1802,11 +1764,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
#pragma omp critical
{
if(needJ)
if(needJ) {
hist16J += hist16Jthr;
}
if(needQ)
if(needQ) {
hist16Q += hist16Qthr;
}
}
}
@ -1864,9 +1828,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
} else {
yb = 90.0f;
}
}
if(settings->viewinggreySc == 1) {
} else if(settings->viewinggreySc == 1) {
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 coe = pow_F(fl, 0.25f);
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)
|| (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));
@ -2391,57 +2352,38 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
if(!params->colorappearance.tonecie || !settings->autocielab || !epdEnabled) {
if(ciedata) {
if(ciedata) { //only with improccoordinator
// Data for J Q M s and C histograms
int posl, posc;
float brli = 327.f;
float chsacol = 327.f;
int libr = 0;
int colch = 0;
float libr;
float colch;
//update histogram
if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) {
brli = 70.0f;
libr = 1;
} else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) {
libr = Q; //40.0 to 100.0 approximative factor for Q - 327 for J
} else /*if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT)*/ {
brli = 327.f;
libr = 0;
libr = J; //327 for J
}
posl = (int)(libr * brli);
hist16JCAM[posl]++;
if (curveMode3 == ColorAppearanceParams::TC_MODE_CHROMA) {
chsacol = 327.f;
colch = 0;
colch = C; //450.0 approximative factor for s 320 for M
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) {
chsacol = 450.0f;
colch = 1;
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) {
colch = s;
} else /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ {
chsacol = 327.0f;
colch = 2;
colch = M;
}
posc = (int)(colch * chsacol);
hist16_CCAM[posc]++;
//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]++;
}
}
if(LabPassOne) {
@ -2582,25 +2524,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
}
// End of parallelization
if(!params->colorappearance.tonecie || !settings->autocielab) { //normal
if(!params->colorappearance.tonecie || !settings->autocielab) { //normal
if(ciedata) {
//update histogram J
for (int i = 0; i < 32768; i++) { //
if (jp) {
float hval = dLcurve[i];
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] ;
}
}
hist16JCAM.compressTo(histLCAM);
//update histogram C
hist16_CCAM.compressTo(histCCAM);
}
}
@ -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->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)) {
ciedata = (params->colorappearance.datacie && pW != 1);
if(epdEnabled && params->colorappearance.tonecie && algepd) {
lab->deleteLab();
ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale );
@ -2786,54 +2717,31 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
int posl, posc;
float brli = 327.f;
float chsacol = 327.f;
int libr = 0;
int colch = 0;
float sa_t;
float libr;
float colch;
if(curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) {
brli = 70.0f;
libr = 1;
} else if(curveMode == ColorAppearanceParams::TC_MODE_LIGHT) {
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)*/ {
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) {
chsacol = 327.f;
colch = 0;
colch = ncie_C_p;
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_SATUR) {
chsacol = 450.0f;
colch = 1;
} else if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF) {
colch = 100.f * sqrtf(ncie_C_p / ncie->Q_p[i][j]);
} else /*if(curveMode3 == ColorAppearanceParams::TC_MODE_COLORF)*/ {
chsacol = 327.0f;
colch = 2;
}
//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]++;
colch = ncie->M_p[i][j];
}
posc = (int)(colch * chsacol);
hist16_CCAM[posc]++;
}
//end histograms
@ -2959,24 +2867,12 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
//show CIECAM histograms
if(ciedata) {
//update histogram J and Q
for (int i = 0; i < 32768; i++) { //
if (jp) {
float hval = dLcurve[i];
int hi = (int)(255.0f * CLIPD(hval)); //
histLCAM[hi] += hist16JCAM[i] ;
}
}
//update histogram J
hist16JCAM.compressTo(histLCAM);
//update color histogram M,s,C
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] ;
}
}
hist16_CCAM.compressTo(histCCAM);
}
}
}
}
@ -3215,7 +3111,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
ClutPtr colorLUT;
bool clutAndWorkingProfilesAreSame = false;
TMatrix work2xyz, xyz2clut, clut2xyz, xyz2work;
TMatrix xyz2clut, clut2xyz;
if ( params->filmSimulation.enabled && !params->filmSimulation.clutFilename.empty() ) {
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;
if ( !clutAndWorkingProfilesAreSame ) {
work2xyz = iccStore->workingSpaceMatrix( params->icm.working );
xyz2clut = iccStore->workingSpaceInverseMatrix( colorLUT->profile() );
xyz2work = iccStore->workingSpaceInverseMatrix( params->icm.working );
clut2xyz = iccStore->workingSpaceMatrix( colorLUT->profile() );
}
}
@ -4338,7 +4232,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
if (!clutAndWorkingProfilesAreSame) {
//convert from working to clut profile
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 );
}
@ -4362,7 +4256,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
//convert from clut to working profile
float x, y, z;
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 H = lold->H;
// lhskcurve.dump("lh_curve");
@ -5605,31 +5498,15 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
}
}
LUTf dCcurve;
LUTf dLcurve;
LUTu hist16Clad;
LUTu hist16Llad;
//preparate for histograms CIECAM
if(pW != 1) { //only with improccoordinator
dCcurve(48000, 0);
dLcurve(65536, 0);
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();
hist16Llad(65536);
hist16Llad.clear();
}
@ -6125,7 +6002,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
//update histogram C
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]++;
}
@ -6181,7 +6058,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
//update histo LC
if(pW != 1) { //only with improccoordinator
int posl = CLIP((int(Lprov1 * 327.68f)));
int posl = Lprov1 * 327.68f;
hist16Llad[posl]++;
}
@ -6269,20 +6146,11 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
}
} // end of parallelization
//update histogram C with data chromaticity and not with CC curve
if(pW != 1) { //only with improccoordinator
for (int i = 0; i < 48000; i++) { //32768*1.414 + ...
float hval = dCcurve[i];
int hi = (int)(255.0 * CLIPD(hval)); //
histCCurve[hi] += hist16Clad[i] ;
}
//update histogram L with data luminance
for (int i = 0; i < 65535; i++) {
float hlval = dLcurve[i];
int hli = (int)(255.0 * CLIPD(hlval));
histLCurve[hli] += hist16Llad[i] ;
}
//update histogram C with data chromaticity and not with CC curve
hist16Clad.compressTo(histCCurve);
//update histogram L with data luminance
hist16Llad.compressTo(histLCurve);
}
#ifdef _DEBUG
@ -6683,15 +6551,15 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip)
#pragma omp parallel for // removed schedule(dynamic,10)
#endif
for(int ii = 0; ii < N; ii++)
a[ii] *= s,
b[ii] *= s,
//L[ii] = L[ii]*32767.0f*(1.f/gamm) + minL;
L[ii] = L[ii] * maxL * (1.f / gamm) + minL;
for(int ii = 0; ii < N; ii++) {
a[ii] *= s;
b[ii] *= s;
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)
{
@ -6704,12 +6572,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
float ave = 0.f, hidev = 0.f, lodev = 0.f;
//find average luminance
for (int i = 0; i < imax; i++) {
sum += histogram[i];
ave += histogram[i] * (float)i;
}
ave /= (sum);
histogram.getSumAndAverage(sum, ave);
//find median of luminance
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;
count = 0;
for (int i = 0; i < imax; i++) {
int i = 0;
for (; i < min((int)ave,imax); i++) {
if (count < 8) {
octile[count] += histogram[i];
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);
}
}
if (i < ave) {
//lodev += SQR(ave-i)*histogram[i];
lodev += (log(ave + 1.f) - log((float)i + 1.)) * 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];
//lodev += SQR(ave-i)*histogram[i];
lodev += (xlog(ave + 1.f) - xlog((float)i + 1.)) * histogram[i];
losum += 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
@ -6815,7 +6688,7 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
int clipped = 0;
int rawmax = (imax) - 1;
while (rawmax > 1 && histogram[rawmax] + clipped <= 0) {
while (histogram[rawmax] + clipped <= 0 && rawmax > 1) {
clipped += histogram[rawmax];
rawmax--;
}
@ -6907,11 +6780,15 @@ void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defga
//take gamma into account
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++) {
gavg += histogram[i] * CurveFactory::gamma2((float)(corr * (i << histcompr) < 65535 ? corr * (i << histcompr) : 65535)) / sum;
float val = 0.f;
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) {
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));
}
@ -7101,6 +6979,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst,
wipv[i][j] = F2V(wiprof[i][j]);
}
}
#endif
#ifdef _OPENMP
@ -7110,9 +6989,10 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst,
for(int i = 0; i < H; i++) {
int j = 0;
#ifdef __SSE2__
for(; j < W - 3; j += 4) {
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::xyz2rgb(X, Y, Z, R, G, B, wipv);
STVFU(dst.r(i, j), R);
@ -7121,6 +7001,7 @@ SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst,
}
#endif
for(; j < W; j++) {
float 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 (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 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);
bool needsCA ();
@ -229,7 +228,7 @@ public:
bool needsTransform ();
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 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,
@ -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,
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);
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 colorCurve (LabImage* lold, LabImage* lnew);
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, 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);
double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL);
void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace);

View File

@ -32,7 +32,6 @@
#include "rawimagesource.h"
#include "stdimagesource.h"
#include <glib/gstdio.h>
#include <csetjmp>
#include "rawimage.h"
#include "jpeg.h"
#include "../rtgui/ppversion.h"
@ -54,7 +53,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h,
StdImageSource imgSrc;
if (imgSrc.load(fname)) {
return NULL;
return nullptr;
}
ImageIO* img = imgSrc.getImageIO();
@ -96,7 +95,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h,
// bilinear interpolation
if (tpp->thumbImg) {
delete tpp->thumbImg;
tpp->thumbImg = NULL;
tpp->thumbImg = nullptr;
}
if (inspectorMode) {
@ -161,7 +160,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
if( r ) {
delete ri;
return NULL;
return nullptr;
}
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());
delete img;
delete ri;
return NULL;
return nullptr;
}
Thumbnail* tpp = new Thumbnail ();
@ -220,7 +219,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
if (tpp->thumbImg) {
delete tpp->thumbImg;
tpp->thumbImg = NULL;
tpp->thumbImg = nullptr;
}
if (inspectorMode) {
@ -289,7 +288,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
if( r ) {
delete ri;
return NULL;
return nullptr;
}
int width = ri->get_width();
@ -297,8 +296,8 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
rtengine::Thumbnail* tpp = new rtengine::Thumbnail;
tpp->isRaw = true;
tpp->embProfile = NULL;
tpp->embProfileData = NULL;
tpp->embProfile = nullptr;
tpp->embProfileData = nullptr;
tpp->embProfileLength = ri->get_profileLen();
if (ri->get_profileLen())
@ -502,7 +501,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
delete tpp->thumbImg;
}
tpp->thumbImg = NULL;
tpp->thumbImg = nullptr;
tpp->thumbImg = resizeTo<Image16>(w, h, TI_Bilinear, tmpImg);
delete tmpImg;
@ -737,11 +736,11 @@ void Thumbnail::init ()
}
Thumbnail::Thumbnail () :
camProfile(NULL), thumbImg(NULL),
camProfile(nullptr), thumbImg(nullptr),
camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0),
redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-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),
defGain(1.0),
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);
LUTu hist16 (65536);
LUTu hist16C (65536);
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
if (ipf.needsTransform()) {
@ -953,7 +951,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
}
// update blurmap
SHMap* shmap = NULL;
SHMap* shmap = nullptr;
if (params.sh.enabled) {
shmap = new SHMap (fw, fh, false);
@ -976,7 +974,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
int hlcomprthresh = params.toneCurve.hlcomprthresh;
if (params.toneCurve.autoexp && aeHistogram) {
ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh);
//ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr);
}
LUTf curve1 (65536);
@ -989,17 +986,11 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LUTf clcurve (65536);
LUTf clToningcurve;
LUTf cl2Toningcurve;
LUTf rCurve (65536);
LUTf gCurve (65536);
LUTf bCurve (65536);
LUTu dummy;
ToneCurve customToneCurve1, customToneCurve2;
ColorGradientCurve ctColorCurve;
OpacityCurve ctOpacityCurve;
// NoisCurve dnNoisCurve;
ColorAppearance customColCurve1;
ColorAppearance customColCurve2;
@ -1012,33 +1003,40 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
params.toneCurve.curveMode2, params.toneCurve.curve2,
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.gcurve, gCurve, 16);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
{wprof[1][0], wprof[1][1], wprof[1][2]},
{wprof[2][0], wprof[2][1], wprof[2][2]}
};
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
double wip[3][3] = {
{wiprof[0][0], wiprof[0][1], wiprof[0][2]},
{wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]}
};
bool opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
//params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili);
if(params.colorToning.enabled) {
clToningcurve (65536);
cl2Toningcurve (65536);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
{wprof[1][0], wprof[1][1], wprof[1][2]},
{wprof[2][0], wprof[2][1], wprof[2][2]}
};
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
double wip[3][3] = {
{wiprof[0][0], wiprof[0][1], wiprof[0][2]},
{wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]}
};
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
clToningcurve (65536);
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16);
cl2Toningcurve (65536);
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16);
}
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16);
if(params.blackwhite.enabled) {
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16);
}
double rrm, ggm, bbm;
float autor, autog, autob;
float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f;
@ -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
LabImage* labView = new LabImage (fw, fh);
DCPProfile *dcpProf = NULL;
DCPProfile *dcpProf = nullptr;
if (isRaw) {
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);
}
}
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
customToneCurve1.Reset();
customToneCurve2.Reset();
ctColorCurve.Reset();
ctOpacityCurve.Reset();
// dnNoisCurve.Reset();
customToneCurvebw1.Reset();
customToneCurvebw2.Reset();
@ -1092,36 +1089,34 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
}
// luminance histogram update
hist16.clear();
hist16C.clear();
if(params.labCurve.contrast != 0) {
hist16.clear();
for (int i = 0; i < fh; i++)
for (int j = 0; j < fw; j++) {
hist16[(int)((labView->L[i][j]))]++;
}
}
for (int i = 0; i < fh; i++)
for (int j = 0; j < fw; 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]))]++;
}
// luminance processing
// ipf.EPDToneMap(labView,0,6);
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 butili = false;
bool ccutili = 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,
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);
//ipf.luminanceCurve (labView, labView, curve);
ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy);
ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy);
ipf.vibrance(labView);
@ -1129,16 +1124,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ipf.EPDToneMap(labView, 5, 6);
}
//if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);}
if(params.colorappearance.enabled) {
CurveFactory::curveLightBrightColor (
params.colorappearance.curve,
params.colorappearance.curve2,
params.colorappearance.curve3,
hist16, dummy,
hist16C, dummy,
dummy, dummy,
customColCurve1,
customColCurve2,
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)
{
if (thumbImg == NULL) {
if (!thumbImg) {
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)
{
if (!thumbImg) {
return NULL;
return nullptr;
}
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
@ -1659,7 +1651,7 @@ bool Thumbnail::readImage (const Glib::ustring& fname)
if (thumbImg) {
delete thumbImg;
thumbImg = NULL;
thumbImg = nullptr;
}
Glib::ustring fullFName = fname + ".rtti";
@ -1872,8 +1864,8 @@ bool Thumbnail::readEmbProfile (const Glib::ustring& fname)
FILE* f = g_fopen (fname.c_str (), "rb");
if (!f) {
embProfileData = NULL;
embProfile = NULL;
embProfileData = nullptr;
embProfile = nullptr;
embProfileLength = 0;
} else {
fseek (f, 0, SEEK_END);
@ -1945,7 +1937,7 @@ unsigned char* Thumbnail::getImage8Data()
return img8->data;
}
return NULL;
return nullptr;
}

View File

@ -726,9 +726,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// perform first analysis
LUTu hist16 (65536);
LUTu hist16C (65536);
ipf.firstAnalysis (baseImg, &params, hist16);
ipf.firstAnalysis (baseImg, params, hist16);
// perform transform (excepted resizing)
if (ipf.needsTransform()) {
@ -777,9 +776,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf cl2Toningcurve;
LUTf wavclCurve (65536, 0);
LUTf rCurve (65536, 0);
LUTf gCurve (65536, 0);
LUTf bCurve (65536, 0);
LUTf rCurve;
LUTf gCurve;
LUTf bCurve;
LUTu dummy;
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.bcurve, bCurve, 1);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
{wprof[1][0], wprof[1][1], wprof[1][2]},
{wprof[2][0], wprof[2][1], wprof[2][2]}
};
double wip[3][3] = {
{wiprof[0][0], wiprof[0][1], wiprof[0][2]},
{wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]}
};
bool opautili = false;
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
if(params.colorToning.enabled) {
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]},
{wprof[1][0], wprof[1][1], wprof[1][2]},
{wprof[2][0], wprof[2][1], wprof[2][2]}
};
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working);
double wip[3][3] = {
{wiprof[0][0], wiprof[0][1], wiprof[0][2]},
{wiprof[1][0], wiprof[1][1], wiprof[1][2]},
{wiprof[2][0], wiprof[2][1], wiprof[2][2]}
};
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
clToningcurve (65536, 0);
CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1);
cl2Toningcurve (65536, 0);
@ -822,8 +820,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
LabImage* labView = new LabImage (fw, fh);
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1);
if(params.blackwhite.enabled) {
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1);
}
double rrm, ggm, bbm;
float autor, autog, autob;
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...???
hist16.clear();
hist16C.clear();
if(params.labCurve.contrast != 0) { //only use hist16 for contrast
hist16.clear();
#ifdef _OPENMP
#pragma omp parallel
@ -918,21 +916,21 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
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 butili = false;
bool ccutili = 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,
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);
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)) {
ipf.EPDToneMap(labView, 5, 1);
@ -1024,7 +1022,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
params.colorappearance.curve2,
params.colorappearance.curve3,
hist16, dummy,
hist16C, dummy,
dummy, dummy,
customColCurve1,
customColCurve2,
customColCurve3,