Speedup for thumbnail processing, Issue 2503

This commit is contained in:
Ingo
2014-10-01 21:29:14 +02:00
parent 8f22007bfb
commit 6bc115fe8b
9 changed files with 279 additions and 230 deletions

View File

@@ -110,8 +110,7 @@ void ColorTemp::clip (double &temp, double &green, double &equal) {
equal = MAXEQUAL;
}
ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e) {
method = "Custom";
ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e), method("Custom") {
mul2temp (mulr, mulg, mulb, equal, temp, green);
}
@@ -1205,7 +1204,7 @@ void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00,doub
}
void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,double &Xxyz, double &Zxyz) {
void ColorTemp::temp2mulxyz (double tem, double gree, std::string method ,double &Xxyz, double &Zxyz) {
double xD, yD, x_D, y_D, interm;
double x, y, z;
@@ -1239,10 +1238,10 @@ void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,doub
else if(method == "Flash 6500K" ) spectrum_to_xyz_preset(Flash6500_spect, x, y, z);
else {
// otherwise we use the Temp+Green generic solution
if (tem <= 4000) {
if (tem <= INITIALBLACKBODY) {
// if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K...
// of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw).
spectrum_to_xyz_blackbody(0., 0., tem, x, y, z);
spectrum_to_xyz_blackbody(tem, x, y, z);
}
else {
// from 4000K up to 25000K: using the D illuminant (daylight) which is standard
@@ -1260,7 +1259,7 @@ void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,doub
interm=(0.0241+0.2562*x_D-0.734*y_D);
m1=(-1.3515-1.7703*x_D+5.9114*y_D)/interm;
m2=(0.03-31.4424*x_D+30.0717*y_D)/interm;
spectrum_to_xyz_daylight(m1, m2, 0., x, y, z);
spectrum_to_xyz_daylight(m1, m2, x, y, z);
xD=x;yD=y;
}
@@ -1307,7 +1306,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
double Lpal[50],apal[50],bpal[50];
int palet=-1;
bool palette=true;
bool palette=false;
// double tempalet; // correlated temperature
// We first test for specially handled methods
@@ -1341,10 +1340,10 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
else if(method == "Flash 6500K" ) {spectrum_to_xyz_preset(Flash6500_spect, x, y, z);palet=27; /*tempalet=6500;*/ }
else {
// otherwise we use the Temp+Green generic solution
if (temp <= 4000) {
if (temp <= INITIALBLACKBODY) {
// if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K...
// of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw).
spectrum_to_xyz_blackbody(0., 0., temp, x, y, z);palet=28;
spectrum_to_xyz_blackbody(temp, x, y, z);palet=28;
}
else {
// from 4000K up to 25000K: using the D illuminant (daylight) which is standard
@@ -1362,7 +1361,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
interm=(0.0241+0.2562*x_D-0.734*y_D);
m1=(-1.3515-1.7703*x_D+5.9114*y_D)/interm;
m2=(0.03-31.4424*x_D+30.0717*y_D)/interm;
spectrum_to_xyz_daylight(m1, m2, 0., x, y, z);
spectrum_to_xyz_daylight(m1, m2, x, y, z);
xD=x;yD=y;
}
}
@@ -1442,9 +1441,9 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
}
}
else if(palet>=28) {
if(temp<4000) {
if(temp<INITIALBLACKBODY) {
for(int i=0;i<N_col;i++) {
spectrum_to_color_xyz_blackbody(spec_colorpalet[i], 0.,0.,temp,x_x,y_y,z_z);
spectrum_to_color_xyz_blackbody(spec_colorpalet[i], temp,x_x,y_y,z_z);
Xpal[i]=x_x;Ypal[i]=y_y;Zpal[i]=z_z;
}
}
@@ -1453,7 +1452,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
m11p=m1;m22p=m2;
for(int i=0;i<N_col;i++) {// calculate XYZ palette for illuminant and color
spectrum_to_color_xyz_daylight(spec_colorpalet[i], m11p,m22p,temp,x_x,y_y,z_z);
spectrum_to_color_xyz_daylight(spec_colorpalet[i], m11p,m22p,x_x,y_y,z_z);
Xpal[i]=x_x;Ypal[i]=y_y;Zpal[i]=z_z;
}
}
@@ -1565,16 +1564,16 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
}
//calculate XYZ for each color : for Blackbody and Daylight at tempw
if(tempw<4000) {
if(tempw<=INITIALBLACKBODY) {
for(int i=0;i<N_c;i++) {
spectrum_to_color_xyz_blackbody(spec_color[i],0.,0.,tempw,xx,yy,zz);
spectrum_to_color_xyz_blackbody(spec_color[i],tempw,xx,yy,zz);
Xchk[i]=xx;Ychk[i]=yy;Zchk[i]=zz;
}
spectrum_to_xyz_blackbody(0., 0., tempw, x, y, z);//for white point
spectrum_to_xyz_blackbody(tempw, x, y, z);//for white point
}
else // after 6600K (arbitrary) I use daylight...because ...but there is no lamp...
{
double m11, m22, x_DD,y_DD, interm2, yDD;
double m11, m22, x_DD,y_DD, interm2;
if (tempw<=7000)
x_DD = -4.6070e9/(tempw*tempw*tempw) + 2.9678e6/(tempw*tempw) + 0.09911e3/tempw + 0.244063;
else
@@ -1588,10 +1587,10 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
m22=(0.03-31.4424*x_DD+30.0717*y_DD)/interm2;
for(int i=0;i<N_c;i++) {
spectrum_to_color_xyz_daylight(spec_color[i],m11,m22,tempw,xx,yy,zz);
spectrum_to_color_xyz_daylight(spec_color[i],m11,m22,xx,yy,zz);
Xchk[i]=xx;Ychk[i]=yy;Zchk[i]=zz;
}
spectrum_to_xyz_daylight(m11, m22, 0., x, y, z);
spectrum_to_xyz_daylight(m11, m22, x, y, z);
}
XYZtoCorColorTemp(Xwb, Ywb, Zwb, correl_temp);
@@ -2217,11 +2216,11 @@ void ColorTemp::jch2xyz_ciecam02float( float &x, float &y, float &z, float J, fl
Calculate Planck's radiation
*/
//calculate spectral data for blackbody at temp!
double ColorTemp::blackbody_spect(double wavelength, double m1, double m2, double temp)
double ColorTemp::blackbody_spect(double wavelength, double temperature)
{
double wlm = wavelength * 1e-9; /* Wavelength in meters */
return (3.7417715247e-16 * pow(wlm, -5.0)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light
(exp(1.438786e-2 / (wlm * temp)) - 1.0); //1.4387..= c2 = h*c/k where k=Boltzmann constant
return (3.7417715247e-16 / pow(wlm, 5)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light
(xexp(1.438786e-2 / (wlm * temperature)) - 1.0); //1.4387..= c2 = h*c/k where k=Boltzmann constant
}
/*
@@ -2241,13 +2240,13 @@ E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.00
I have increase precision used by J.Walker and pass to 350nm to 830nm
*/
void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double _temp, double &x, double &y, double &z)
void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, double &y, double &z)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) {
double Me = daylight_spect(lambda, _m1, _m2, _temp);
double Me = daylight_spect(lambda, _m1, _m2);
X += Me * cie_colour_match_jd[i][0];
Y += Me * cie_colour_match_jd[i][1];
Z += Me * cie_colour_match_jd[i][2];
@@ -2258,13 +2257,13 @@ void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double _temp, d
z = Z / XYZ;
}
void ColorTemp::spectrum_to_xyz_blackbody(double _m1, double _m2, double _temp, double &x, double &y, double &z)
void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, double &z)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) {
double Me = blackbody_spect(lambda, _m1, _m2, _temp);
double Me = blackbody_spect(lambda, _temp);
X += Me * cie_colour_match_jd[i][0];
Y += Me * cie_colour_match_jd[i][1];
Z += Me * cie_colour_match_jd[i][2];
@@ -2338,7 +2337,7 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011
void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz)
void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, Yo=0;
@@ -2348,7 +2347,7 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double
double Mc;
Me = get_spectral_color(lambda, spec_color);
Mc = daylight_spect(lambda,_m1, _m2, _temp);
Mc = daylight_spect(lambda,_m1, _m2);
X += Mc * cie_colour_match_jd[i][0] * Me;
Y += Mc * cie_colour_match_jd[i][1] * Me;
Z += Mc * cie_colour_match_jd[i][2] * Me;
@@ -2357,7 +2356,7 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double
double Ms;
Ms = daylight_spect(lambda,_m1, _m2, _temp);
Ms = daylight_spect(lambda,_m1, _m2);
Yo += cie_colour_match_jd[i][1] * Ms;
}
@@ -2367,7 +2366,7 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011
void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz)
void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, Yo=0;
@@ -2377,7 +2376,7 @@ void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double
double Mc;
Me = get_spectral_color(lambda, spec_color);
Mc = blackbody_spect(lambda,_m1, _m2, _temp);
Mc = blackbody_spect(lambda, _temp);
X += Mc * cie_colour_match_jd[i][0] * Me;
Y += Mc * cie_colour_match_jd[i][1] * Me;
Z += Mc * cie_colour_match_jd[i][2] * Me;
@@ -2386,7 +2385,7 @@ void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double
double Ms;
Ms = blackbody_spect(lambda,_m1, _m2, _temp);
Ms = blackbody_spect(lambda, _temp);
Yo += cie_colour_match_jd[i][1] * Ms;
}
@@ -2395,7 +2394,7 @@ void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double
zz = Z / Yo;
}
double ColorTemp::daylight_spect(double wavelength, double m1, double m2, double temp)
double ColorTemp::daylight_spect(double wavelength, double m1, double m2)
{
//Values for Daylight illuminant: s0 s1 s2
//s0

View File

@@ -48,7 +48,7 @@ class ColorTemp {
double temp;
double green;
double equal;
Glib::ustring method;
std::string method;
static void clip (double &temp, double &green);
static void clip (double &temp, double &green, double &equal);
@@ -62,7 +62,7 @@ class ColorTemp {
void update (const double rmul, const double gmul, const double bmul, const double equal) { this->equal = equal; mul2temp (rmul, gmul, bmul, this->equal, temp, green); }
void useDefaults (const double equal) { temp = 6504; green = 1.0; this->equal = equal; } // Values copied from procparams.cc
inline Glib::ustring getMethod() { return method; }
inline std::string getMethod() { return method; }
inline double getTemp () { return temp; }
inline double getGreen () { return green; }
inline double getEqual () { return equal; }
@@ -71,7 +71,7 @@ class ColorTemp {
void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green);
void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul);
static void temp2mulxyz (double tem, double gree, Glib::ustring method, double &Xxyz, double &Zxyz);
static void temp2mulxyz (double tem, double gree, std::string method, double &Xxyz, double &Zxyz);
int XYZtoCorColorTemp(double x0,double y0 ,double z0, double &temp);
static void cieCAT02(double Xw, double Yw, double Zw,double &CAM02BB00,double &CAM02BB01,double &CAM02BB02, double &CAM02BB10,double &CAM02BB11,double &CAM02BB12,double &CAM02BB20,double &CAM02BB21,double &CAM02BB22, double adap );
@@ -204,8 +204,8 @@ class ColorTemp {
bool operator== (const ColorTemp& other) { return fabs(temp-other.temp)<1e-10 && fabs(green-other.green)<1e-10; }
bool operator!= (const ColorTemp& other) { return !(*this==other); }
static double blackbody_spect (double wavelength, double m1, double m2, double temp);
static double daylight_spect (double wavelength, double m1, double m2, double temp);
static double blackbody_spect (double wavelength, double temperature);
static double daylight_spect (double wavelength, double m1, double m2);
static const double Cloudy6200_spect[97];
static const double Daylight5300_spect[97];
static const double Shade7600_spect[97];
@@ -294,12 +294,12 @@ class ColorTemp {
static const double ColabSky60_0_m31_spect[97];//Sky L=60
static const double ColabSky42_0_m24_spect[97];//Sky L=42
static void spectrum_to_xyz_daylight (double _m1, double _m2, double _temp, double &x, double &y, double &z);
static void spectrum_to_xyz_blackbody (double _m1, double _m2, double _temp, double &x, double &y, double &z);
static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z);
static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z);
static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z);
static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz);
static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _m1, double _m2, double _temp, double &xx, double &yy, double &zz);
static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz);
static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz);
static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz);

View File

@@ -29,7 +29,7 @@
#include "array2D.h"
#include "LUT.h"
#include "curves.h"
#include "opthelper.h"
#undef CLIPD
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
@@ -136,13 +136,14 @@ namespace rtengine {
const double CurveFactory::sRGBGamma = 2.2;
const double CurveFactory::sRGBGammaCurve = 2.4;
void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) {
SSEFUNCTION void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) {
if (needed) {
LUTf lutCurve (65536);
for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) {
// change to [0,1] range
double val = (double)i / 65535.0;
float val = (float)i / 65535.f;
// apply custom/parametric/NURBS curve, if any
val = diagCurve->getVal (val);
// store result in a temporary array
@@ -162,14 +163,24 @@ namespace rtengine {
}
for (int i=0; i<=0xffff; i++) {
outCurve[i] = (65535.0 * lutCurve[i]);
outCurve[i] = (65535.f * lutCurve[i]);
}
}
else {
#ifdef __SSE2__
__m128 fourv = _mm_set1_ps(4.f);
__m128 iv = _mm_set_ps(3.f,2.f,1.f,0.f);
for (int i=0; i<=0xfffc; i+=4) {
_mm_storeu_ps(&outCurve[i],iv);
iv += fourv;
}
#else
for (int i=0; i<=0xffff; i++) {
outCurve[i] = (float)i;
}
#endif
}
}
void CurveFactory::updatechroma (
@@ -214,18 +225,6 @@ void CurveFactory::curveLightBrightColor (
ColorAppearance & customColCurve3,
int skip)
{
LUTf dcurve(65536,0);
LUTf dCcurve(65536,0);
float val;
for (int i=0; i<32768; i++) {
val = (double)i / 32767.0;
dcurve[i] = CLIPD(val);
}
for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma
val = (double)i / 47999.0;
dCcurve[i] = CLIPD(val);
}
outBeforeCCurveHistogram.clear();
outBeforeCCurveHistogramC.clear();
@@ -290,22 +289,19 @@ void CurveFactory::curveLightBrightColor (
tcurve = NULL;
}
}
for (int i=0; i<32768; i++) {
float val;
if (histNeeded) {
float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogram[hi] += histogram[i] ;
}
if (histNeeded) {
for (int i=0; i<32768; i++) {
double hval = CLIPD((double)i / 32767.0);
int hi = (int)(255.0*hval);
outBeforeCCurveHistogram[hi] += histogram[i] ;
}
}
for (int i=0; i<48000; i++) {//32768*1.414 + ...
float val;
if (histNeededC) {
float hval = dCcurve[i];
int hi = (int)(255.0*CLIPD(hval)); //
outBeforeCCurveHistogramC[hi] += histogramC[i] ;
}
if (histNeededC) {
for (int i=0; i<48000; i++) {//32768*1.414 + ...
double hval = CLIPD((double)i / 47999.0);
int hi = (int)(255.0*hval); //
outBeforeCCurveHistogramC[hi] += histogramC[i] ;
}
}
if (tcurve) delete tcurve;
@@ -344,13 +340,6 @@ void CurveFactory::curveBW (
LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance
ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip)
{
LUTf dcurve(65536,0);
float val;
for (int i=0; i<32768; i++) {
val = (double)i / 32767.0;
dcurve[i] = CLIPD(val);
}
outBeforeCCurveHistogrambw.clear();
bool histNeeded = false;
@@ -386,15 +375,20 @@ void CurveFactory::curveBW (
tcurve = NULL;
}
// create first curve if needed
for (int i=0; i<32768; i++) {
if (histNeeded) {
LUTf dcurve(65536,0);
float val;
if (histNeeded) {
float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogrambw[hi] += histogrambw[i] ;
for (int i=0; i<32768; i++) {
val = (float)i / 32767.f;
dcurve[i] = CLIPD(val);
}
for (int i=0; i<32768; i++) {
float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogrambw[hi] += histogrambw[i] ;
}
}
if (tcurve) delete tcurve;
@@ -404,12 +398,6 @@ void CurveFactory::curveBW (
void CurveFactory::curveCL ( bool & clcutili,const std::vector<double>& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram,int skip){
bool needed;
DiagonalCurve* dCurve = NULL;
LUTf dCcurve(65536,0);
float val;
for (int i=0; i<50000; i++) { //# 32768*1.414 approximation maxi for chroma
dCcurve[i] = (float)i / 49999.0;
}
if (outBeforeCLurveHistogram)
outBeforeCLurveHistogram.clear();
@@ -424,14 +412,12 @@ void CurveFactory::curveCL ( bool & clcutili,const std::vector<double>& clcurveP
if (dCurve && !dCurve->isIdentity())
{needed = true;clcutili=true;}
}
for (int i=0; i<50000; i++) {//32768*1.414 + ...
float val;
if (histNeededCL) {
float hval = dCcurve[i];
int hi = (int)(255.0*CLIPD(hval)); //
if(histNeededCL)
for (int i=0; i<50000; i++) {//32768*1.414 + ...
int hi = (int)(255.0*CLIPD((float)i / 49999.0)); //
outBeforeCLurveHistogram[hi] += histogramcl[i] ;
}
}
fillCurveArray(dCurve, clCurve, skip, needed);
if (dCurve) {
@@ -444,12 +430,6 @@ void CurveFactory::curveCL ( bool & clcutili,const std::vector<double>& clcurveP
void CurveFactory::curveToningCL ( bool & clctoningutili,const std::vector<double>& clcurvePoints, LUTf & clToningCurve,int skip){
bool needed;
DiagonalCurve* dCurve = NULL;
LUTf dCcurve(65536,0);
float val;
for (int i=0; i<32768; i++) {
dCcurve[i] = (float)i / 32767.0;
}
needed = false;
if (!clcurvePoints.empty() && clcurvePoints[0]!=0) {
@@ -470,12 +450,7 @@ void CurveFactory::curveToningCL ( bool & clctoningutili,const std::vector<doubl
void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<double>& llcurvePoints, LUTf & llToningCurve, int skip){
bool needed;
DiagonalCurve* dCurve = NULL;
LUTf dCcurve(65536,0);
float val;
for (int i=0; i<32768; i++) {
dCcurve[i] = (float)i / 32767.0;
}
needed = false;
if (!llcurvePoints.empty() && llcurvePoints[0]!=0) {
dCurve = new DiagonalCurve (llcurvePoints, CURVES_MIN_POLY_POINTS/skip);
@@ -506,10 +481,11 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
DiagonalCurve* dCurve = NULL;
LUTf dCcurve(65536,0);
int k=48000;//32768*1.41
for (int i=0; i<k*adjustr; i++) { //# 32768*1.414 approximation maxi for chroma
dCcurve[i] = (float)i / (k*adjustr-1);
if(outBeforeCCurveHistogram || outBeforeLCurveHistogram) {
for (int i=0; i<k*adjustr; i++) { //# 32768*1.414 approximation maxi for chroma
dCcurve[i] = (float)i / (k*adjustr-1);
}
}
if (outBeforeCCurveHistogram)
outBeforeCCurveHistogram.clear();
bool histNeededC = false;
@@ -563,9 +539,8 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
if (dCurve && !dCurve->isIdentity())
{needed = true;ccutili=true;}
}
for (int i=0; i<k*adjustr; i++) {//32768*1.414 + ...
float val;
if (histNeededC) {
if (histNeededC) {
for (int i=0; i<k*adjustr; i++) {//32768*1.414 + ...
float hval = dCcurve[i];
int hi = (int)(255.0*CLIPD(hval)); //
outBeforeCCurveHistogram[hi] += histogramC[i] ;
@@ -587,9 +562,8 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
if (dCurve && !dCurve->isIdentity())
{needed = true;cclutili=true;}
}
for (int i=0; i<k*adjustr; i++) {//32768*1.414 + ...
float val;
if (histNeededLC) {
if (histNeededLC) {
for (int i=0; i<k*adjustr; i++) {//32768*1.414 + ...
float hval = dCcurve[i];
int hi = (int)(255.0*CLIPD(hval)); //
outBeforeLCurveHistogram[hi] += histogramLC[i] ;
@@ -609,7 +583,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh,
SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh,
double shcompr, double br, double contr, double gamma_, bool igamma_,
procparams::ToneCurveParams::eTCModeId curveMode, const std::vector<double>& curvePoints,
procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
@@ -643,8 +617,6 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
// a: slope of the curve, black: starting point at the x axis
double a = pow (2.0, ecomp);
// curve without contrast
LUTf dcurve(0x10000);
// check if inverse gamma is needed at the end
bool needigamma = igamma_ && gamma_>1.;
@@ -695,38 +667,77 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
//printf("shoulder = %e\n",shoulder);
//printf ("exp_scale= %f comp= %f def_mul=%f a= %f \n",exp_scale,comp,def_mul,a);
for (int i=0; i<0x10000; i++) {
// change to [0,1] range
float val = (float)i-shoulder;
if (comp>0.0)
{
if (val>0.0) {
float R = val*comp/(scale-shoulder);
hlCurve[i] = log(1.0+R*exp_scale)/R;
} else {
hlCurve[i]=exp_scale;
}
} else {
if (comp<=0.0f)
for (int i=0; i<0x10000; i++)
hlCurve[i]=exp_scale;
else {
for (int i=0; i<=shoulder; i++)
hlCurve[i]=exp_scale;
float scalemshoulder = scale - shoulder;
// SSE makes more sense than omp here
#ifdef __SSE2__
int i;
__m128 exp_scalev = _mm_set1_ps(exp_scale);
__m128 scalemshoulderv = _mm_set1_ps(scalemshoulder);
__m128 compv = _mm_set1_ps(comp);
__m128 valv = _mm_set_ps(4.f,3.f,2.f,1.f);
__m128 onev = _mm_set1_ps(1.f);
__m128 fourv = _mm_set1_ps(4.f);
for (i=shoulder+1; i<0xFFFD; i+=4) {
// change to [0,1] range
__m128 Rv = valv*compv/(scalemshoulderv);
_mm_storeu_ps(&hlCurve[i],xlogf(onev+Rv*exp_scalev)/Rv);
valv += fourv;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%
// change to [0,1] range
if (i!=0) {
for (; i<0x10000; i++) {
// change to [0,1] range
float val = (float)i-shoulder;
float R = val*comp/(scalemshoulder);
hlCurve[i] = xlogf(1.f+R*exp_scale)/R;
}
#else
for (int i=shoulder+1; i<0x10000; i++) {
// change to [0,1] range
float val = (float)i-shoulder;
float R = val*comp/(scalemshoulder);
hlCurve[i] = xlogf(1.f+R*exp_scale)/R;
}
#endif
}
// curve without contrast
LUTf dcurve(0x10000);
//%%%%%%%%%%%%%%%%%%%%%%%%%%
// change to [0,1] range
float val = 1.f/65535.f;
float val2 = simplebasecurve (val, black, 0.015*shcompr);
shCurve[0] = CLIPD(val2)/val;
val = 0.0;
// gamma correction
if (gamma_>1.)
val = gamma (val, gamma_, start, slope, mul, add);
// apply brightness curve
if (brightcurve)
val = brightcurve->getVal (val); // TODO: getVal(double) is very slow! Optimize with a LUTf
// store result in a temporary array
dcurve[0] = CLIPD(val);
#pragma omp parallel for
for (int i=1; i<0x10000; i++) {
float val;
val = (float)i / 65535.0f;
} else {
val = 1.0/65535.0;
}
float val2 = basecurve (val, 1.0, black, 1.0, 0.0, 1.5*shcompr/100.0);
float val2 = simplebasecurve (val, black, 0.015*shcompr);
shCurve[i] = CLIPD(val2)/val;
//%%%%%%%%%%%%%%%%%%%%%%%%%%
// change to [0,1] range
val = (double)i / 65535.0;
// gamma correction
if (gamma_>1.)
val = gamma (val, gamma_, start, slope, mul, add);
@@ -750,16 +761,17 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
if (contr>0.00001 || contr<-0.00001) {
// compute mean luminance of the image with the curve applied
int sum = 0;
unsigned int sum = 0;
float avg = 0;
//double sqavg = 0;
for (int i=0; i<=0xffff; i++) {
float fi=i;
fi = hlCurve[fi]*fi;
fi *= hlCurve[i];
avg += dcurve[(int)(shCurve[fi]*fi)] * histogram[i];
//sqavg += dcurve[i]*dcurve[i] * histogram[i];
sum += histogram[i];
}
avg /= sum;
//sqavg /= sum;
//double stddev = sqrt(sqavg-avg*avg);
@@ -783,7 +795,6 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// apply contrast enhancement
for (int i=0; i<=0xffff; i++) {
dcurve[i] = contrastcurve->getVal (dcurve[i]);
@@ -874,7 +885,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for (int i=0; i<=0xffff; i++) {
float val = dcurve[i];;
float val = dcurve[i];
if (histNeeded) {
float fi=i;
@@ -890,7 +901,7 @@ void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector<doubl
if (needigamma)
val = igamma (val, gamma_, start, slope, mul, add);
outCurve[i] = (65535.0 * val);
outCurve[i] = (65535.f * val);
}
if (tcurve) delete tcurve;

View File

@@ -60,7 +60,7 @@ class CurveFactory {
static inline double basel (double x, double m1, double m2) {
if (x==0.0)
return 0.0;
double k = sqrt ((m1-1.0)*(m1-m2)/2) / (1.0-m2);
double k = sqrt ((m1-1.0)*(m1-m2)*0.5) / (1.0-m2);
double l = (m1-m2) / (1.0-m2) + k;
double lx = xlog(x);
return m2*x + (1.0-m2)*(2.0 - xexp(k*lx))*xexp(l*lx);
@@ -93,12 +93,14 @@ class CurveFactory {
}
static inline double clower2 (double x, double m, double sr) {
//curve for b<0; starts with positive slope and then rolls over toward straight line to x=y=1
float x1 = sr/1.5 + 0.00001;
float y1 = 1-(1-x1)*m;
double x1 = sr/1.5 + 0.00001;
if (x>x1 || sr<0.001)
return 1-(1-x)*m;
else
{
double y1 = 1-(1-x1)*m;
return y1+m*(x-x1)-(1-m)*SQR(SQR(1-x/x1));
}
}
// tone curve base. a: slope (from exp.comp.), b: black point normalized by 65535,
// D: max. x value (can be>1), hr,sr: highlight,shadow recovery
@@ -123,6 +125,26 @@ class CurveFactory {
return y+(x-m)*slope;
}
}
static inline double simplebasecurve (double x, double b, double sr) {
// a = 1, D = 1, hr = 0 (unused for a = D = 1)
if (b<0) {
double m = 0.5;//midpoint
double slope = 1.0+b;//slope of straight line between (0,-b) and (1,1)
double y = -b+m*slope;//value at midpoint
if (x>m)
return y + (x - m)*slope;//value on straight line between (m,y) and (1,1)
else
return y*clower2(x/m, slope*m/y, 2.0-sr);
} else {
double slope = 1.0/(1.0-b);
double m = b+(1-b)*0.25;
double y = (m-b)*slope;
if (x<=m)
return b==0 ? x*slope : clower (x/m, slope*m/y, sr) * y;
else
return y+(x-m)*slope;
}
}
public:

View File

@@ -285,8 +285,8 @@ double DiagonalCurve::getVal (double t) const {
return t;
}
unsigned int k_lo = 0;
unsigned int k_hi = 0;
unsigned int k_lo;
unsigned int k_hi;
k_lo = hash.at(i).smallerValue;
k_hi = hash.at(i).higherValue;

View File

@@ -345,6 +345,7 @@ void Imagefloat::normalizeFloatTo65535() {
}
void Imagefloat::calcCroppedHistogram(const ProcParams &params, float scale, LUTu & hist) {
hist.clear();
// Set up factors to calc the lightness
@@ -359,21 +360,29 @@ void Imagefloat::calcCroppedHistogram(const ProcParams &params, float scale, LUT
int x1, x2, y1, y2;
params.crop.mapToResized(width, height, scale, x1, x2, y1, y2);
#ifdef _OPENMP
#pragma omp parallel for
#endif
#pragma omp parallel
{
LUTu histThr(65536);
histThr.clear();
#pragma omp for nowait
for (int y=y1; y<y2; y++) {
int i;
for (int x=x1; x<x2; x++) {
i = (int)(facRed * r(y,x) + facGreen * g(y,x) + facBlue * b(y,x));
if (i<0) i=0; else if (i>65535) i=65535;
#ifdef _OPENMP
// Access to hist[] must be atomic. In this case, we may need to see if this parallelization is worth it
#pragma omp atomic
#endif
hist[i]++;
if (i<0)
i=0;
else if (i>65535)
i=65535;
histThr[i]++;
}
}
#pragma omp critical
{
for(int i=0;i<=0xffff;i++)
hist[i] += histThr[i];
}
}
}
// Parallelized transformation; create transform with cmsFLAGS_NOCACHE!

View File

@@ -51,7 +51,6 @@ ImProcCoordinator::ImProcCoordinator ()
lhist16(65536), lhist16Cropped(65536),
lhist16CAM(65536), lhist16CroppedCAM(65536),
lhist16CCAM(65536),
lhist16CCAMAF(65536), lhist16ClabAF(65536),
histCropped(65536),
lhist16Clad(65536),lhist16CLlad(65536),
lhist16LClad(65536), lhist16LLClad(65536),
@@ -121,7 +120,6 @@ DetailedCrop* ImProcCoordinator::createCrop (::EditDataProvider *editDataProvid
void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
MyMutex::MyLock processingLock(mProcessing);
int numofphases = 14;
int readyphase = 0;
@@ -330,9 +328,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases);
if ((todo & M_RGBCURVE) || (todo & M_CROP)) {
if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped);
// if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped);
// complexCurve also calculated pre-curves histogram depending on crop
//complexCurve also calculated pre-curves histogram depending on crop
ipf.g = imgsrc->getGamma();
ipf.iGamma = true;
CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0,
@@ -367,10 +365,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
CurveFactory::curveBW (params.blackwhite.beforeCurve,params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW,scale==1 ? 1 : 1);
//initialize rrm bbm ggm different from zero to avoid black screen in some cases
double rrm=33.;
double ggm=33.;
double bbm=33.;
float satLimit = float(params.colorToning.satProtectionThreshold)/100.f*0.7f+0.3f;
float satLimitOpacity = 1.f-(float(params.colorToning.saturatedOpacity)/100.f);
@@ -412,6 +406,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
}
// if it's just crop we just need the histogram, no image updates
if ( todo & M_RGBCURVE ) {
//initialize rrm bbm ggm different from zero to avoid black screen in some cases
double rrm=33.;
double ggm=33.;
double bbm=33.;
ipf.rgbProc (oprevi, oprevl, NULL, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation,
rCurve, gCurve, bCurve, satLimit ,satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2,beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh);
if(params.blackwhite.enabled && params.blackwhite.autoc && abwListener) {
@@ -426,20 +424,18 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
}
// correct GUI black and white with value
}
// compute L channel histogram
int x1, y1, x2, y2, pos;
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
lhist16.clear(); lhist16Cropped.clear();
lhist16Clad.clear(); lhist16CLlad.clear();lhist16LLClad.clear();
lhist16ClabAF.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]++;}
if (y>=y1 && y<y2 && x>=x1 && x<x2)
lhist16Cropped[pos]++;
}
}
readyphase++;
// utili=false;
@@ -461,7 +457,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
clcutili=false;
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, lhist16CLlad, histCLurve, scale==1 ? 1 : 16);
float adjustr=1.0f, adjustbg=1.0f;
float adjustr=1.0f;
/* if (params.icm.working=="ProPhoto") {adjustr = adjustbg = 1.2f;}// 1.2 instead 1.0 because it's very rare to have C>170..
@@ -472,7 +468,6 @@ 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;}
*/
adjustr=1.f;
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);
@@ -534,34 +529,38 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
}
//}
//L histo and Chroma histo for ciecam
// histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C
int x1, y1, x2, y2, pos, posc;
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
lhist16CAM.clear(); lhist16CroppedCAM.clear();
lhist16CCAM.clear();
lhist16CCAMAF.clear();
for (int x=0; x<pH; x++)
for (int y=0; y<pW; y++) {
pos=CLIP((int)(nprevl->L[x][y]));
posc=CLIP((int)sqrt(nprevl->a[x][y]*nprevl->a[x][y] + nprevl->b[x][y]*nprevl->b[x][y]));
if(!params.colorappearance.datacie) lhist16CCAM[posc]++;
if(!params.colorappearance.datacie)lhist16CAM[pos]++;
if (y>=y1 && y<y2 && x>=x1 && x<x2) {lhist16CroppedCAM[pos]++;}
}
LUTu dummy;
CurveFactory::curveLightBrightColor (
params.colorappearance.curveMode, params.colorappearance.curve,
params.colorappearance.curveMode2, params.colorappearance.curve2,
params.colorappearance.curveMode3, params.colorappearance.curve3,
lhist16CAM, lhist16CroppedCAM,histLCAM,
lhist16CCAM, histCCAM,
customColCurve1,
customColCurve2,
customColCurve3,
scale==1 ? 1 : 1
);
if(params.colorappearance.enabled){
//L histo and Chroma histo for ciecam
// histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C
int x1, y1, x2, y2, pos, posc;
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
lhist16CAM.clear(); lhist16CroppedCAM.clear();
lhist16CCAM.clear();
for (int x=0; x<pH; x++)
for (int y=0; y<pW; y++) {
pos=CLIP((int)(nprevl->L[x][y]));
if(!params.colorappearance.datacie) {
posc=CLIP((int)sqrt(nprevl->a[x][y]*nprevl->a[x][y] + nprevl->b[x][y]*nprevl->b[x][y]));
lhist16CAM[pos]++;
lhist16CCAM[posc]++;
}
if (y>=y1 && y<y2 && x>=x1 && x<x2)
lhist16CroppedCAM[pos]++;
}
LUTu dummy;
CurveFactory::curveLightBrightColor (
params.colorappearance.curveMode, params.colorappearance.curve,
params.colorappearance.curveMode2, params.colorappearance.curve2,
params.colorappearance.curveMode3, params.colorappearance.curve3,
lhist16CAM, lhist16CroppedCAM,histLCAM,
lhist16CCAM, histCCAM,
customColCurve1,
customColCurve2,
customColCurve3,
scale==1 ? 1 : 1
);
float fnum = imgsrc->getMetaData()->getFNumber (); // F number
float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO
float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed
@@ -757,6 +756,26 @@ void ImProcCoordinator::updateLRGBHistograms () {
int x1, y1, x2, y2;
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
#pragma omp parallel sections
{
#pragma omp section
{
histChroma.clear();
for (int i=y1; i<y2; i++)
for (int j=x1; j<x2; j++) {
histChroma[(int)(sqrtf(SQR(nprevl->a[i][j]) + SQR(nprevl->b[i][j]))/188.f)]++;//188 = 48000/256
}
}
#pragma omp section
{
histLuma.clear();
for (int i=y1; i<y2; i++)
for (int j=x1; j<x2; j++) {
histLuma[(int)(nprevl->L[i][j]/128.f)]++;
}
}
#pragma omp section
{
histRed.clear();
histGreen.clear();
histBlue.clear();
@@ -773,22 +792,9 @@ void ImProcCoordinator::updateLRGBHistograms () {
histBlue[b]++;
}
}
histLuma.clear();
histChroma.clear();
for (int i=y1; i<y2; i++)
for (int j=x1; j<x2; j++) {
histChroma[(int)(sqrt(nprevl->a[i][j]*nprevl->a[i][j] + nprevl->b[i][j]*nprevl->b[i][j]))/188]++;//188 = 48000/256
histLuma[(int)(nprevl->L[i][j]/128)]++;
}
}
}
/*for (int i=0; i<256; i++) {
Lhist[i] = (int)(256*sqrt(Lhist[i]));
rhist[i] = (int)(256*sqrt(rhist[i]));
ghist[i] = (int)(256*sqrt(ghist[i]));
bhist[i] = (int)(256*sqrt(bhist[i]));
bcrgbhist[i] = (int)(256*sqrt(bcrgbhist[i]));
bcLhist[i] = (int)(256*sqrt(bcLhist[i]));
}*/
}
void ImProcCoordinator::progress (Glib::ustring str, int pr) {

View File

@@ -99,8 +99,6 @@ class ImProcCoordinator : public StagedImageProcessor {
LUTu lhist16,lhist16Cropped;
LUTu lhist16CAM,lhist16CroppedCAM;
LUTu lhist16CCAM;
LUTu lhist16CCAMAF;
LUTu lhist16ClabAF;
LUTu histCropped;
LUTu lhist16Clad,lhist16CLlad,lhist16LClad,lhist16LLClad;
LUTu histRed, histRedRaw;

View File

@@ -870,8 +870,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili);
//params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili);
LabImage* labView = new LabImage (fw,fh);
CieImage* cieView = new CieImage (fw,fh);
bool clctoningutili=false;
bool llctoningutili=false;
CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve,scale==1 ? 1 : 16);
@@ -899,6 +897,8 @@ 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);
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);
// freeing up some memory
@@ -940,10 +940,11 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
hist16C, hist16C, dummy, dummy,
16);
//ipf.luminanceCurve (labView, labView, curve);
ipf.chromiLuminanceCurve (NULL, 1,labView, labView, curve1, curve2, satcurve,lhskcurve, clcurve, curve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy);
ipf.vibrance(labView);
int begh = 0, endh = labView->H;
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || !params.colorappearance.enabled) ipf.EPDToneMap(labView,5,6);
@@ -961,6 +962,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
16);
if(params.colorappearance.enabled){
int begh = 0, endh = labView->H;
float** buffer = new float*[fh];
for (int i=0; i<fh; i++)
buffer[i] = new float[fw];
@@ -996,7 +998,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
int scale;
sk=16;
int rtt=0;
CieImage* cieView = new CieImage (fw,fh);
ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, &params,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 6, (float**)buffer, execsharp, d, sk, rtt);
delete cieView;
for (int i=0; i<fh; i++)
delete [] buffer[i];
delete [] buffer; buffer=NULL;
@@ -1009,7 +1013,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ipf.lab2monitorRgb (labView, readyImg);
delete labView;
delete baseImg;
delete cieView;
// calculate scale
if (params.coarse.rotate==90 || params.coarse.rotate==270)
myscale = scale * thumbImg->width / fh;
@@ -1030,6 +1033,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
else
ix += 3;
}*/
return readyImg;
}