Solving issue 2023: "Pseudo memory leak with Detail window + memory handling optimization"
The Detail window buffers are now freed up when the it is closed. The CIECAM buffers are allocated only if necessary now, and if the single block allocation fails, it will try to allocate it in several blocks.
This commit is contained in:
@@ -155,7 +155,7 @@ namespace rtengine {
|
||||
|
||||
//srand((unsigned)time(0));//test with random data
|
||||
|
||||
const float gain = pow (2.0f, expcomp);
|
||||
const float gain = pow (2.0f, float(expcomp));
|
||||
float incr=1.f;
|
||||
float noisevar_Ldetail = SQR((SQR(100.f-dnparams.Ldetail) + 50.f*(100.f-dnparams.Ldetail)) * TS * 0.5f * incr);
|
||||
|
||||
|
@@ -10,49 +10,90 @@ CieImage::CieImage (int w, int h) : fromImage(false), W(w), H(h) {
|
||||
sh_p = new float*[H];
|
||||
// ch_p = new float*[H];
|
||||
h_p = new float*[H];
|
||||
|
||||
data = new float [W*H*6];
|
||||
float * index = data;
|
||||
for (int i=0; i<H; i++)
|
||||
J_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
Q_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
M_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
C_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
sh_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
// for (int i=0; i<H; i++)
|
||||
// ch_p[i] = index + i*W;
|
||||
// index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
h_p[i] = index + i*W;
|
||||
|
||||
// Initialize the pointers to zero
|
||||
for (unsigned int c=0; c<6; ++c)
|
||||
data[c] = NULL;
|
||||
|
||||
// Trying to allocate all in one block
|
||||
data[0] = new (std::nothrow) float [W*H*6];
|
||||
|
||||
if (data[0]) {
|
||||
float * index = data[0];
|
||||
for (int i=0; i<H; i++)
|
||||
J_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
Q_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
M_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
C_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
sh_p[i] = index + i*W;
|
||||
index+=W*H;
|
||||
// for (int i=0; i<H; i++)
|
||||
// ch_p[i] = index + i*W;
|
||||
// index+=W*H;
|
||||
for (int i=0; i<H; i++)
|
||||
h_p[i] = index + i*W;
|
||||
}
|
||||
else {
|
||||
// Allocating each plane separately
|
||||
for (unsigned int c=0; c<6; ++c)
|
||||
data[c] = new float [W*H];
|
||||
|
||||
unsigned int c = 0;
|
||||
for (int i=0; i<H; i++)
|
||||
J_p[i] = data[c] + i*W;
|
||||
++c;
|
||||
for (int i=0; i<H; i++)
|
||||
Q_p[i] = data[c] + i*W;
|
||||
++c;
|
||||
for (int i=0; i<H; i++)
|
||||
M_p[i] = data[c] + i*W;
|
||||
++c;
|
||||
for (int i=0; i<H; i++)
|
||||
C_p[i] = data[c] + i*W;
|
||||
++c;
|
||||
for (int i=0; i<H; i++)
|
||||
sh_p[i] = data[c] + i*W;
|
||||
++c;
|
||||
// for (int i=0; i<H; i++)
|
||||
// ch_p[i] = data[c] + i*W;
|
||||
// ++c;
|
||||
for (int i=0; i<H; i++)
|
||||
h_p[i] = data[c] + i*W;
|
||||
}
|
||||
}
|
||||
|
||||
CieImage::~CieImage () {
|
||||
|
||||
if (!fromImage) {
|
||||
delete [] J_p;
|
||||
delete [] Q_p;
|
||||
delete [] J_p;
|
||||
delete [] Q_p;
|
||||
delete [] M_p;
|
||||
delete [] C_p;
|
||||
delete [] sh_p;
|
||||
// delete [] ch_p;
|
||||
// delete [] ch_p;
|
||||
delete [] h_p;
|
||||
|
||||
|
||||
delete [] data;
|
||||
|
||||
for (unsigned int c=0; c<6; ++c)
|
||||
if (data[c]) delete [] data[c];
|
||||
}
|
||||
}
|
||||
|
||||
void CieImage::CopyFrom(CieImage *Img){
|
||||
memcpy(data, Img->data, W*H*6*sizeof(float));
|
||||
if (!data [1])
|
||||
// Only one allocated block
|
||||
memcpy(data, Img->data, W*H*6*sizeof(float));
|
||||
else
|
||||
// Separate allocation
|
||||
for (unsigned int c=0; c<6; ++c)
|
||||
memcpy(data[c], Img->data[c], W*H*sizeof(float));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ private:
|
||||
|
||||
public:
|
||||
int W, H;
|
||||
float * data;
|
||||
float * data[6];
|
||||
float** J_p;
|
||||
float** Q_p;
|
||||
float** M_p;
|
||||
|
@@ -30,25 +30,35 @@ namespace rtengine {
|
||||
extern const Settings* settings;
|
||||
|
||||
Crop::Crop (ImProcCoordinator* parent)
|
||||
: resizeCrop(NULL), transCrop(NULL), updating(false),
|
||||
skip(10),cropw(-1), croph(-1), trafw(-1), trafh(-1),
|
||||
borderRequested(32), cropAllocated(false),
|
||||
cropImageListener(NULL), parent(parent)
|
||||
: origCrop(NULL), transCrop(NULL), laboCrop(NULL), labnCrop(NULL),
|
||||
cropImg(NULL), cieCrop(NULL), cbuf_real(NULL), cshmap(NULL),
|
||||
cbuffer(NULL), updating(false), newUpdatePending(false),
|
||||
skip(10),
|
||||
cropx(0), cropy(0), cropw(-1), croph(-1),
|
||||
trafx(0), trafy(0), trafw(-1), trafh(-1),
|
||||
rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1),
|
||||
borderRequested(32), upperBorder(0), leftBorder(0),
|
||||
cropAllocated(false),
|
||||
cropImageListener(NULL), parent(parent)
|
||||
{
|
||||
parent->crops.push_back (this);
|
||||
}
|
||||
|
||||
Crop::~Crop () {
|
||||
|
||||
cropMutex.lock ();
|
||||
parent->mProcessing.lock ();
|
||||
MyMutex::MyLock cropLock(cropMutex);
|
||||
MyMutex::MyLock processingLock(parent->mProcessing);
|
||||
|
||||
std::vector<Crop*>::iterator i = std::find (parent->crops.begin(), parent->crops.end(), this);
|
||||
if (i!=parent->crops.end ())
|
||||
parent->crops.erase (i);
|
||||
|
||||
freeAll ();
|
||||
parent->mProcessing.unlock ();
|
||||
cropMutex.unlock ();
|
||||
}
|
||||
|
||||
void Crop::destroy () {
|
||||
MyMutex::MyLock lock(cropMutex);
|
||||
MyMutex::MyLock processingLock(parent->mProcessing); ///////// RETESTER MAINTENANT QUE CE VERROU EST AJOUTE!!!
|
||||
freeAll();
|
||||
}
|
||||
|
||||
void Crop::setListener (DetailedCropListener* il) {
|
||||
@@ -80,10 +90,10 @@ void Crop::update (int todo) {
|
||||
if (needsinitupdate || (todo & M_HIGHQUAL))
|
||||
todo = ALL;
|
||||
|
||||
// set improcfuncions' scale now that skip has been updated
|
||||
// Tells to the ImProcFunctions' tool what is the preview scale, which may lead to some simplifications
|
||||
parent->ipf.setScale (skip);
|
||||
|
||||
baseCrop = origCrop;
|
||||
Imagefloat* baseCrop = origCrop;
|
||||
|
||||
bool needstransform = parent->ipf.needsTransform();
|
||||
|
||||
@@ -104,171 +114,181 @@ void Crop::update (int todo) {
|
||||
parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.hlrecovery, params.icm, params.raw );
|
||||
//ColorTemp::CAT02 (origCrop, ¶ms) ;
|
||||
|
||||
//parent->imgsrc->convertColorSpace(origCrop, params.icm);
|
||||
//parent->imgsrc->convertColorSpace(origCrop, params.icm);
|
||||
|
||||
if (todo & M_LINDENOISE) {
|
||||
if (skip==1 && params.dirpyrDenoise.enabled) {
|
||||
parent->ipf.RGB_denoise(origCrop, origCrop, parent->imgsrc->isRAW(), /*Roffset,*/ params.dirpyrDenoise, params.defringe, parent->imgsrc->getDirPyrDenoiseExpComp());
|
||||
}
|
||||
if (skip==1 && params.dirpyrDenoise.enabled)
|
||||
parent->ipf.RGB_denoise(origCrop, origCrop, parent->imgsrc->isRAW(), /*Roffset,*/ params.dirpyrDenoise, params.defringe, parent->imgsrc->getDirPyrDenoiseExpComp());
|
||||
}
|
||||
parent->imgsrc->convertColorSpace(origCrop, params.icm, params.raw);
|
||||
}
|
||||
}
|
||||
|
||||
// transform
|
||||
if ((!needstransform && transCrop) || (transCrop && (transCrop->width!=cropw || transCrop->height!=croph))) {
|
||||
delete transCrop;
|
||||
if (needstransform) {
|
||||
if (!transCrop)
|
||||
transCrop = new Imagefloat (cropw, croph);
|
||||
|
||||
if ((todo & M_TRANSFORM) && needstransform)
|
||||
parent->ipf.transform (baseCrop, transCrop, cropx/skip, cropy/skip, trafx/skip, trafy/skip, SKIPS(parent->fw,skip), SKIPS(parent->fh,skip),
|
||||
parent->imgsrc->getMetaData()->getFocalLen(), parent->imgsrc->getMetaData()->getFocalLen35mm(),
|
||||
parent->imgsrc->getMetaData()->getFocusDist(), parent->imgsrc->getRotateDegree(), false);
|
||||
if (transCrop)
|
||||
baseCrop = transCrop;
|
||||
}
|
||||
else {
|
||||
if (transCrop) delete transCrop;
|
||||
transCrop = NULL;
|
||||
}
|
||||
if (needstransform && !transCrop)
|
||||
transCrop = new Imagefloat (cropw, croph);
|
||||
if ((todo & M_TRANSFORM) && needstransform)
|
||||
parent->ipf.transform (baseCrop, transCrop, cropx/skip, cropy/skip, trafx/skip, trafy/skip, SKIPS(parent->fw,skip), SKIPS(parent->fh,skip),
|
||||
parent->imgsrc->getMetaData()->getFocalLen(), parent->imgsrc->getMetaData()->getFocalLen35mm(),
|
||||
parent->imgsrc->getMetaData()->getFocusDist(), parent->imgsrc->getRotateDegree(), false);
|
||||
if (transCrop)
|
||||
baseCrop = transCrop;
|
||||
|
||||
// blurmap for shadow & highlights
|
||||
if ((todo & M_BLURMAP) && params.sh.enabled) {
|
||||
double radius = sqrt (double(SKIPS(parent->fw,skip)*SKIPS(parent->fw,skip)+SKIPS(parent->fh,skip)*SKIPS(parent->fh,skip))) / 2.0;
|
||||
double shradius = params.sh.radius;
|
||||
if (!params.sh.hq) shradius *= radius / 1800.0;
|
||||
cshmap->update (baseCrop, shradius, parent->ipf.lumimul, params.sh.hq, skip);
|
||||
double shradius = params.sh.radius;
|
||||
if (!params.sh.hq) shradius *= radius / 1800.0;
|
||||
cshmap->update (baseCrop, shradius, parent->ipf.lumimul, params.sh.hq, skip);
|
||||
cshmap->forceStat (parent->shmap->max_f, parent->shmap->min_f, parent->shmap->avg);
|
||||
}
|
||||
|
||||
// shadows & highlights & tone curve & convert to cielab
|
||||
/*int xref,yref;
|
||||
xref=000;yref=000;
|
||||
if (colortest && cropw>115 && croph>115)
|
||||
for(int j=1;j<5;j++){
|
||||
xref+=j*30;yref+=j*30;
|
||||
if (settings->verbose) printf("before rgbProc RGB Xr%i Yr%i Skip=%d R=%f G=%f B=%f gamma=%f \n",xref,yref,skip,
|
||||
baseCrop->r[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
parent->imgsrc->getGamma());
|
||||
}*/
|
||||
|
||||
/*int xref,yref;
|
||||
xref=000;yref=000;
|
||||
if (colortest && cropw>115 && croph>115)
|
||||
for(int j=1;j<5;j++){
|
||||
xref+=j*30;yref+=j*30;
|
||||
if (settings->verbose) printf("before rgbProc RGB Xr%i Yr%i Skip=%d R=%f G=%f B=%f gamma=%f \n",xref,yref,skip,
|
||||
baseCrop->r[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
parent->imgsrc->getGamma());
|
||||
}*/
|
||||
|
||||
if (todo & M_RGBCURVE)
|
||||
parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap,
|
||||
params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->customToneCurve1, parent->customToneCurve2 );
|
||||
params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->customToneCurve1, parent->customToneCurve2 );
|
||||
|
||||
/*xref=000;yref=000;
|
||||
if (colortest && cropw>115 && croph>115)
|
||||
for(int j=1;j<5;j++){
|
||||
xref+=j*30;yref+=j*30;
|
||||
if (settings->verbose) {
|
||||
/*xref=000;yref=000;
|
||||
if (colortest && cropw>115 && croph>115)
|
||||
for(int j=1;j<5;j++){
|
||||
xref+=j*30;yref+=j*30;
|
||||
if (settings->verbose) {
|
||||
printf("after rgbProc RGB Xr%i Yr%i Skip=%d R=%f G=%f B=%f \n",xref,yref,skip,
|
||||
baseCrop->r[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256);
|
||||
printf("after rgbProc Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip,
|
||||
laboCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
laboCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
laboCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327);
|
||||
baseCrop->r[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256);
|
||||
printf("after rgbProc Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip,
|
||||
laboCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
laboCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
laboCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327);
|
||||
}
|
||||
}*/
|
||||
|
||||
// apply luminance operations
|
||||
if (todo & (M_LUMINANCE+M_COLOR)) {
|
||||
//I made a little change here. Rather than have luminanceCurve (and others) use in/out lab images, we can do more if we copy right here.
|
||||
labnCrop->CopyFrom(laboCrop);
|
||||
}*/
|
||||
|
||||
// apply luminance operations
|
||||
if (todo & (M_LUMINANCE+M_COLOR)) {
|
||||
//I made a little change here. Rather than have luminanceCurve (and others) use in/out lab images, we can do more if we copy right here.
|
||||
labnCrop->CopyFrom(laboCrop);
|
||||
|
||||
|
||||
// parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve);
|
||||
bool utili=true;
|
||||
bool autili=true;
|
||||
bool butili=true;
|
||||
bool ccutili=true;
|
||||
bool cclutili=true;
|
||||
//parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve);
|
||||
bool utili=true;
|
||||
bool autili=true;
|
||||
bool butili=true;
|
||||
bool ccutili=true;
|
||||
bool cclutili=true;
|
||||
|
||||
|
||||
LUTu dummy;
|
||||
parent->ipf.chromiLuminanceCurve (1,labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->lumacurve, utili, autili, butili, ccutili,cclutili, dummy);
|
||||
parent->ipf.vibrance (labnCrop);
|
||||
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) parent->ipf.EPDToneMap(labnCrop,5,1);
|
||||
// parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay.
|
||||
// for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled
|
||||
if (skip==1) {
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
|
||||
parent->ipf.impulsedenoise (labnCrop);}
|
||||
if((params.colorappearance.enabled && !settings->autocielab) ||(!params.colorappearance.enabled) ) {parent->ipf.defringe (labnCrop);}
|
||||
parent->ipf.MLsharpen (labnCrop);
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
|
||||
parent->ipf.MLmicrocontrast (labnCrop);
|
||||
parent->ipf.sharpening (labnCrop, (float**)cbuffer);
|
||||
parent->ipf.dirpyrequalizer (labnCrop);
|
||||
}
|
||||
}
|
||||
|
||||
if(params.colorappearance.enabled){
|
||||
float fnum = parent->imgsrc->getMetaData()->getFNumber ();// F number
|
||||
float fiso = parent->imgsrc->getMetaData()->getISOSpeed () ;// ISO
|
||||
float fspeed = parent->imgsrc->getMetaData()->getShutterSpeed () ;//speed
|
||||
float fcomp = parent->imgsrc->getMetaData()->getExpComp ();//compensation + -
|
||||
float adap2,adap;
|
||||
double ada, ada2;
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) {adap=adap=2000.f;ada=ada2=2000.;}//if no exif data or wrong
|
||||
else {
|
||||
float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f));
|
||||
float expo2= params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += expo2;
|
||||
float expo1;//exposure raw white point
|
||||
expo1=log2(params.raw.expos);//log2 ==>linear to EV
|
||||
E_V += expo1;
|
||||
adap2 = adap= powf(2.f, E_V-3.f);//cd / m2
|
||||
ada=ada2=(double) adap;
|
||||
//end calculation adaptation scene luminosity
|
||||
}
|
||||
|
||||
int begh = 0, endh = labnCrop->H;
|
||||
bool execsharp=false;
|
||||
float d;
|
||||
double dd;
|
||||
if(skip==1) execsharp=true;
|
||||
if(settings->ciecamfloat) {parent->ipf.ciecam_02float (cieCrop, adap, begh, endh, 1, 2,labnCrop, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, d);
|
||||
}
|
||||
else {parent->ipf.ciecam_02 (cieCrop,ada, begh, endh, 1, 2, labnCrop, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, dd);}
|
||||
}
|
||||
}
|
||||
LUTu dummy;
|
||||
parent->ipf.chromiLuminanceCurve (1,labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->lumacurve, utili, autili, butili, ccutili,cclutili, dummy);
|
||||
parent->ipf.vibrance (labnCrop);
|
||||
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) parent->ipf.EPDToneMap(labnCrop,5,1);
|
||||
//parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay.
|
||||
// for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled
|
||||
if (skip==1) {
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
|
||||
parent->ipf.impulsedenoise (labnCrop);}
|
||||
if((params.colorappearance.enabled && !settings->autocielab) ||(!params.colorappearance.enabled) ) {parent->ipf.defringe (labnCrop);}
|
||||
parent->ipf.MLsharpen (labnCrop);
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
|
||||
parent->ipf.MLmicrocontrast (labnCrop);
|
||||
parent->ipf.sharpening (labnCrop, (float**)cbuffer);
|
||||
parent->ipf.dirpyrequalizer (labnCrop);
|
||||
}
|
||||
}
|
||||
|
||||
if(params.colorappearance.enabled){
|
||||
float fnum = parent->imgsrc->getMetaData()->getFNumber (); // F number
|
||||
float fiso = parent->imgsrc->getMetaData()->getISOSpeed () ; // ISO
|
||||
float fspeed = parent->imgsrc->getMetaData()->getShutterSpeed () ; // Speed
|
||||
double fcomp = parent->imgsrc->getMetaData()->getExpComp (); // Compensation +/-
|
||||
double adap; // Scene's luminosity adaptation factor
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong
|
||||
adap=2000.;
|
||||
}
|
||||
else {
|
||||
double E_V = fcomp + log2 (double((fnum*fnum) / fspeed / (fiso/100.f)));
|
||||
E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += log2(params.raw.expos);// exposure raw white point ; log2 ==> linear to EV
|
||||
adap= pow(2., E_V-3.);// cd / m2
|
||||
// end calculation adaptation scene luminosity
|
||||
}
|
||||
|
||||
int begh = 0, endh = labnCrop->H;
|
||||
bool execsharp=false;
|
||||
if(skip==1) execsharp=true;
|
||||
|
||||
if (!cieCrop)
|
||||
cieCrop = new CieImage (cropw, croph);
|
||||
|
||||
if(settings->ciecamfloat) {
|
||||
float d; // not used after this block
|
||||
parent->ipf.ciecam_02float (cieCrop, float(adap), begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, d);
|
||||
}
|
||||
else {
|
||||
double dd; // not used after this block
|
||||
parent->ipf.ciecam_02 (cieCrop,adap, begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, dd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// CIECAM is disbaled, we free up its image buffer to save some space
|
||||
if (cieCrop) delete cieCrop; cieCrop=NULL;
|
||||
}
|
||||
}
|
||||
// switch back to rgb
|
||||
parent->ipf.lab2monitorRgb (labnCrop, cropImg);
|
||||
|
||||
//parent->ipf.lab2monitorRgb (laboCrop, cropImg);
|
||||
|
||||
//cropImg = baseCrop->to8();
|
||||
/*
|
||||
// int xref,yref;
|
||||
xref=000;yref=000;
|
||||
if (colortest && cropw>115 && croph>115)
|
||||
for(int j=1;j<5;j++){
|
||||
xref+=j*30;yref+=j*30;
|
||||
int rlin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))]/255.0) * 255.0);
|
||||
int glin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1]/255.0) * 255.0);
|
||||
int blin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2]/255.0) * 255.0);
|
||||
|
||||
printf("after lab2rgb RGB lab2 Xr%i Yr%i Skip=%d R=%d G=%d B=%d \n",xref,yref,skip,
|
||||
rlin,glin,blin);
|
||||
//cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))],
|
||||
//cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1)],
|
||||
//cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2)]);
|
||||
//printf("after lab2rgb Lab lab2 Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327);
|
||||
printf("after lab2rgb Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip,
|
||||
labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327)q;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (colortest && cropImg->height>115 && cropImg->width>115) {//for testing
|
||||
xref=000;yref=000;
|
||||
printf("dcrop final R= %d G= %d B= %d \n",
|
||||
cropImg->data[3*xref/(skip)*(cropImg->width+1)],
|
||||
cropImg->data[3*xref/(skip)*(cropImg->width+1)+1],
|
||||
cropImg->data[3*xref/(skip)*(cropImg->width+1)+2]);
|
||||
}
|
||||
*/
|
||||
//parent->ipf.lab2monitorRgb (laboCrop, cropImg);
|
||||
|
||||
//cropImg = baseCrop->to8();
|
||||
/*
|
||||
// int xref,yref;
|
||||
xref=000;yref=000;
|
||||
if (colortest && cropw>115 && croph>115)
|
||||
for(int j=1;j<5;j++){
|
||||
xref+=j*30;yref+=j*30;
|
||||
int rlin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))]/255.0) * 255.0);
|
||||
int glin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1]/255.0) * 255.0);
|
||||
int blin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2]/255.0) * 255.0);
|
||||
|
||||
printf("after lab2rgb RGB lab2 Xr%i Yr%i Skip=%d R=%d G=%d B=%d \n",xref,yref,skip,
|
||||
rlin,glin,blin);
|
||||
//cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))],
|
||||
//cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1)],
|
||||
//cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2)]);
|
||||
//printf("after lab2rgb Lab lab2 Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327);
|
||||
printf("after lab2rgb Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip,
|
||||
labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,
|
||||
labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327)q;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (colortest && cropImg->height>115 && cropImg->width>115) {//for testing
|
||||
xref=000;yref=000;
|
||||
printf("dcrop final R= %d G= %d B= %d \n",
|
||||
cropImg->data[3*xref/(skip)*(cropImg->width+1)],
|
||||
cropImg->data[3*xref/(skip)*(cropImg->width+1)+1],
|
||||
cropImg->data[3*xref/(skip)*(cropImg->width+1)+2]);
|
||||
}
|
||||
*/
|
||||
if (cropImageListener) {
|
||||
// this in output space held in parallel to allow analysis like shadow/highlight
|
||||
Glib::ustring outProfile=params.icm.output;
|
||||
@@ -281,16 +301,16 @@ void Crop::update (int todo) {
|
||||
int finalH = rqcroph;
|
||||
if (cropImg->getHeight()-upperBorder < finalH)
|
||||
finalH = cropImg->getHeight()-upperBorder;
|
||||
|
||||
|
||||
Image8* final = new Image8 (finalW, finalH);
|
||||
Image8* finaltrue = new Image8 (finalW, finalH);
|
||||
Image8* finaltrue = new Image8 (finalW, finalH);
|
||||
for (int i=0; i<finalH; i++) {
|
||||
memcpy (final->data + 3*i*finalW, cropImg->data + 3*(i+upperBorder)*cropw + 3*leftBorder, 3*finalW);
|
||||
memcpy (finaltrue->data + 3*i*finalW, cropImgtrue->data + 3*(i+upperBorder)*cropw + 3*leftBorder, 3*finalW);
|
||||
}
|
||||
memcpy (finaltrue->data + 3*i*finalW, cropImgtrue->data + 3*(i+upperBorder)*cropw + 3*leftBorder, 3*finalW);
|
||||
}
|
||||
cropImageListener->setDetailedCrop (final, finaltrue, params.icm, params.crop, rqcropx, rqcropy, rqcropw, rqcroph, skip);
|
||||
delete final;
|
||||
delete finaltrue;
|
||||
delete finaltrue;
|
||||
delete cropImgtrue;
|
||||
}
|
||||
}
|
||||
@@ -300,26 +320,23 @@ void Crop::freeAll () {
|
||||
if (settings->verbose) printf ("freeallcrop starts %d\n", (int)cropAllocated);
|
||||
|
||||
if (cropAllocated) {
|
||||
delete origCrop;
|
||||
if (transCrop)
|
||||
delete transCrop;
|
||||
transCrop = NULL;
|
||||
if (resizeCrop)
|
||||
delete resizeCrop;
|
||||
resizeCrop = NULL;
|
||||
delete laboCrop;
|
||||
delete cieCrop;
|
||||
delete labnCrop;
|
||||
delete cropImg;
|
||||
delete cshmap;
|
||||
// for (int i=0; i<croph; i++)
|
||||
// delete [] cbuffer[i];
|
||||
delete [] cbuf_real;
|
||||
delete [] cbuffer;
|
||||
if (origCrop ) { delete origCrop; origCrop=NULL; }
|
||||
if (transCrop) { delete transCrop; transCrop=NULL; }
|
||||
if (laboCrop ) { delete laboCrop; laboCrop=NULL; }
|
||||
if (labnCrop ) { delete labnCrop; labnCrop=NULL; }
|
||||
if (cropImg ) { delete cropImg; cropImg=NULL; }
|
||||
if (cieCrop ) { delete cieCrop; cieCrop=NULL; }
|
||||
if (cbuf_real) { delete [] cbuf_real; cbuf_real=NULL; }
|
||||
if (cbuffer ) { delete [] cbuffer; cbuffer=NULL; }
|
||||
if (cshmap ) { delete cshmap; cshmap=NULL; }
|
||||
}
|
||||
cropAllocated = false;
|
||||
}
|
||||
|
||||
/** @brief Handles crop's image buffer reallocation and trigger sizeChanged of SizeListener[s]
|
||||
* If the scale changes, this method will free all buffers and reallocate ones of the new size.
|
||||
* It will then tell to the SizeListener that size has changed (sizeChanged)
|
||||
*/
|
||||
bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool internal) {
|
||||
|
||||
if (settings->verbose) printf ("setcropsizes before lock\n");
|
||||
@@ -379,8 +396,8 @@ if (settings->verbose) printf ("setcropsizes before lock\n");
|
||||
leftBorder = SKIPS(rqx1-bx1,skip);
|
||||
upperBorder = SKIPS(rqy1-by1,skip);
|
||||
|
||||
if (settings->verbose)
|
||||
printf ("setsizes starts (%d, %d, %d, %d, %d, %d)\n", orW, orH, trafw, trafh,cw,ch);
|
||||
if (settings->verbose)
|
||||
printf ("setsizes starts (%d, %d, %d, %d, %d, %d)\n", orW, orH, trafw, trafh,cw,ch);
|
||||
|
||||
if (cw!=cropw || ch!=croph || orW!=trafw || orH!=trafh) {
|
||||
|
||||
@@ -392,26 +409,22 @@ if (settings->verbose) printf ("setcropsizes before lock\n");
|
||||
trafh = orH;
|
||||
|
||||
origCrop = new Imagefloat (trafw, trafh);
|
||||
laboCrop = new LabImage (cropw, croph);
|
||||
labnCrop = new LabImage (cropw, croph);
|
||||
//transCrop will be allocated later, if necessary
|
||||
laboCrop = new LabImage (cropw, croph);
|
||||
labnCrop = new LabImage (cropw, croph);
|
||||
cropImg = new Image8 (cropw, croph);
|
||||
cieCrop = new CieImage (cropw, croph);
|
||||
|
||||
cshmap = new SHMap (cropw, croph, true);
|
||||
|
||||
//cieCrop is only used in Crop::update, it will be allocated on first use and deleted if not used anymore
|
||||
cbuffer = new float*[croph];
|
||||
cbuf_real= new float[(croph+2)*cropw];
|
||||
for (int i=0; i<croph; i++)
|
||||
cbuffer[i] = cbuf_real+cropw*i+cropw;
|
||||
cshmap = new SHMap (cropw, croph, true);
|
||||
|
||||
resizeCrop = NULL;
|
||||
transCrop = NULL;
|
||||
|
||||
cropAllocated = true;
|
||||
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
cropx = bx1;
|
||||
cropy = by1;
|
||||
trafx = orx;
|
||||
@@ -424,27 +437,38 @@ if (settings->verbose) printf ("setcropsizes before lock\n");
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
// Try a simple, threadless update flag first
|
||||
|
||||
/** @brief Look out if a new thread has to be started to process the update
|
||||
*
|
||||
* @return If true, a new updating thread has to be created. If false, the current updating thread will be used
|
||||
*/
|
||||
bool Crop::tryUpdate() {
|
||||
bool needsFullUpdate = true;
|
||||
|
||||
// If there are more update request, the following WHILE will collect it
|
||||
if (updating) {
|
||||
needsNext = true;
|
||||
needsFullUpdate = false;
|
||||
} else updating = true;
|
||||
|
||||
return needsFullUpdate;
|
||||
bool needsNewThread = true;
|
||||
|
||||
if (updating) {
|
||||
// tells to the updater thread that a new update is pending
|
||||
newUpdatePending = true;
|
||||
// no need for a new thread, the current one will do the job
|
||||
needsNewThread = false;
|
||||
}
|
||||
else
|
||||
// the crop is now being updated ...well, when fullUpdate will be called
|
||||
updating = true;
|
||||
|
||||
return needsNewThread;
|
||||
}
|
||||
|
||||
// Full update, should be called via thread
|
||||
/* @brief Handles Crop updating in its own thread
|
||||
*
|
||||
* This method will cycle updates ss long as Crop::newUpdatePending will be true. During the processing,
|
||||
* intermediary update will be automatically flushed by Crop::tryUpdate.
|
||||
*/
|
||||
void Crop::fullUpdate () {
|
||||
|
||||
parent->updaterThreadStart.lock ();
|
||||
if (parent->updaterRunning && parent->thread) {
|
||||
// Do NOT reset changes here, since in a long chain of events it will lead to chroma_scale not being updated,
|
||||
// causing Color::lab2rgb to return a black image on some opens
|
||||
// Do NOT reset changes here, since in a long chain of events it will lead to chroma_scale not being updated,
|
||||
// causing Color::lab2rgb to return a black image on some opens
|
||||
//parent->changeSinceLast = 0;
|
||||
parent->thread->join ();
|
||||
}
|
||||
@@ -453,12 +477,13 @@ void Crop::fullUpdate () {
|
||||
if (parent->plistener)
|
||||
parent->plistener->setProgressState (true);
|
||||
|
||||
needsNext = true;
|
||||
while (needsNext) {
|
||||
needsNext = false;
|
||||
// If there are more update request, the following WHILE will collect it
|
||||
newUpdatePending = true;
|
||||
while (newUpdatePending) {
|
||||
newUpdatePending = false;
|
||||
update (ALL);
|
||||
}
|
||||
updating = false;
|
||||
updating = false; // end of crop update
|
||||
|
||||
if (parent->plistener)
|
||||
parent->plistener->setProgressState (false);
|
||||
|
@@ -37,20 +37,24 @@ class ImProcCoordinator;
|
||||
class Crop : public DetailedCrop {
|
||||
|
||||
protected:
|
||||
Imagefloat* origCrop, *baseCrop;
|
||||
Imagefloat* *resizeCrop, *transCrop;
|
||||
LabImage *laboCrop, *labnCrop;
|
||||
Image8 *cropImg; // permanently allocated in RAM and only renewed on size changes
|
||||
CieImage *cieCrop;
|
||||
float** cbuffer;
|
||||
float * cbuf_real;
|
||||
SHMap* cshmap;
|
||||
// --- permanently allocated in RAM and only renewed on size changes
|
||||
Imagefloat* origCrop; // "one chunk" allocation
|
||||
Imagefloat* transCrop; // "one chunk" allocation, allocated if necessary
|
||||
LabImage* laboCrop; // "one chunk" allocation
|
||||
LabImage* labnCrop; // "one chunk" allocation
|
||||
Image8* cropImg; // "one chunk" allocation
|
||||
CieImage* cieCrop; // allocating 6 images, each in "one chunk" allocation
|
||||
float * cbuf_real; // "one chunk" allocation
|
||||
SHMap* cshmap; // per line allocation
|
||||
// -----------------------------------------------------------------
|
||||
float** cbuffer;
|
||||
|
||||
bool updating, needsNext;
|
||||
bool updating; /// Flag telling if an updater thread is currently processing
|
||||
bool newUpdatePending; /// Flag telling the updater thread that a new update is pending
|
||||
int skip;
|
||||
int cropx, cropy, cropw, croph; // size of the detail crop image ('skip' taken into account), with border
|
||||
int trafx, trafy, trafw, trafh; // the size and position to get from the imagesource that is transformed to the requested crop area
|
||||
int rqcropx, rqcropy, rqcropw, rqcroph; // size of the requested detail crop image (the image might be smaller) (without border)
|
||||
int cropx, cropy, cropw, croph; /// size of the detail crop image ('skip' taken into account), with border
|
||||
int trafx, trafy, trafw, trafh; /// the size and position to get from the imagesource that is transformed to the requested crop area
|
||||
int rqcropx, rqcropy, rqcropw, rqcroph; /// size of the requested detail crop image (the image might be smaller) (without border)
|
||||
int borderRequested, upperBorder, leftBorder;
|
||||
|
||||
bool cropAllocated;
|
||||
@@ -70,11 +74,15 @@ class Crop : public DetailedCrop {
|
||||
void update (int todo);
|
||||
void setWindow (int cx, int cy, int cw, int ch, int skip) { setCropSizes (cx, cy, cw, ch, skip, false); }
|
||||
|
||||
bool tryUpdate (); // First try, only make fullUpdate if this returns false
|
||||
/** @brief Synchronously look out if a full update is necessary
|
||||
* First try, only make fullUpdate if this returns false
|
||||
*/
|
||||
bool tryUpdate ();
|
||||
/** @brief Asynchronously reprocess the detailed crop */
|
||||
void fullUpdate (); // called via thread
|
||||
|
||||
void setListener (DetailedCropListener* il);
|
||||
void destroy () {}
|
||||
void destroy ();
|
||||
int get_skip () { return skip;}
|
||||
};
|
||||
}
|
||||
|
@@ -29,8 +29,9 @@ namespace rtengine {
|
||||
extern const Settings* settings;
|
||||
|
||||
ImProcCoordinator::ImProcCoordinator ()
|
||||
: workimg(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10), highDetailPreprocessComputed(false),
|
||||
highDetailRawComputed(false), allocated(false),
|
||||
: orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL),
|
||||
ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10),
|
||||
highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false),
|
||||
|
||||
hltonecurve(65536,0),
|
||||
shtonecurve(65536,2),//clip above
|
||||
@@ -46,9 +47,9 @@ ImProcCoordinator::ImProcCoordinator ()
|
||||
lhist16(65536), lhist16Cropped(65536),
|
||||
lhist16CAM(65536), lhist16CroppedCAM(65536),
|
||||
lhist16CCAM(65536), lhist16CroppedCCAM(65536),
|
||||
lhist16CCAMAF(65536), lhist16ClabAF(65536),
|
||||
lhist16CCAMAF(65536), lhist16ClabAF(65536),
|
||||
histCropped(65536),
|
||||
lhist16Clad(65536),lhist16CroppedClad(65536),
|
||||
lhist16Clad(65536),lhist16CroppedClad(65536),
|
||||
|
||||
histRed(256), histRedRaw(256),
|
||||
histGreen(256), histGreenRaw(256),
|
||||
@@ -57,9 +58,9 @@ ImProcCoordinator::ImProcCoordinator ()
|
||||
histToneCurve(256),
|
||||
histLCurve(256),
|
||||
histCCurve(256),
|
||||
histLCAM(256),
|
||||
histCCAM(256),
|
||||
histClad(256),
|
||||
histLCAM(256),
|
||||
histCCAM(256),
|
||||
histClad(256),
|
||||
bcabhist(256),
|
||||
|
||||
rCurve(),
|
||||
@@ -106,45 +107,46 @@ DetailedCrop* ImProcCoordinator::createCrop () {
|
||||
// cropCall: calling crop, used to prevent self-updates
|
||||
void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
mProcessing.lock ();
|
||||
MyMutex::MyLock processingLock(mProcessing);
|
||||
|
||||
int numofphases = 14;
|
||||
int readyphase = 0;
|
||||
|
||||
// Tells to the ImProcFunctions' tools what is the preview scale, which may lead to some simplifications
|
||||
ipf.setScale (scale);
|
||||
|
||||
// Check if any detail crops need high detail. If not, take a fast path short cut
|
||||
// Check if any detail crops need high detail. If not, take a fast path short cut
|
||||
bool highDetailNeeded = (todo & M_HIGHQUAL);
|
||||
if (!highDetailNeeded) {
|
||||
for (size_t i=0; i<crops.size(); i++)
|
||||
if (crops[i]->get_skip() == 1 ) { // skip=1 -> full resolution
|
||||
highDetailNeeded=true;
|
||||
break;
|
||||
}
|
||||
for (size_t i=0; i<crops.size(); i++)
|
||||
if (crops[i]->get_skip() == 1 ) { // skip=1 -> full resolution
|
||||
highDetailNeeded=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RAWParams rp = params.raw;
|
||||
if( !highDetailNeeded ){
|
||||
RAWParams rp = params.raw;
|
||||
if( !highDetailNeeded ){
|
||||
// if below 100% magnification, take a fast path
|
||||
rp.dmethod = RAWParams::methodstring[RAWParams::fast];
|
||||
rp.ca_autocorrect = false;
|
||||
rp.hotdeadpix_filt = false;
|
||||
rp.ccSteps = 0;
|
||||
//rp.all_enhance = false;
|
||||
}
|
||||
rp.dmethod = RAWParams::methodstring[RAWParams::fast];
|
||||
rp.ca_autocorrect = false;
|
||||
rp.hotdeadpix_filt = false;
|
||||
rp.ccSteps = 0;
|
||||
//rp.all_enhance = false;
|
||||
}
|
||||
|
||||
progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases);
|
||||
// raw auto CA is bypassed if no high detail is needed, so we have to compute it when high detail is needed
|
||||
if ( (todo & M_PREPROC) || (!highDetailPreprocessComputed && highDetailNeeded)) {
|
||||
imgsrc->preprocess( rp, params.lensProf, params.coarse );
|
||||
imgsrc->preprocess( rp, params.lensProf, params.coarse );
|
||||
imgsrc->getRAWHistogram( histRedRaw, histGreenRaw, histBlueRaw );
|
||||
if (highDetailNeeded)
|
||||
highDetailPreprocessComputed = true;
|
||||
highDetailPreprocessComputed = true;
|
||||
else
|
||||
highDetailPreprocessComputed = false;
|
||||
highDetailPreprocessComputed = false;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
Demosaic is kicked off only when
|
||||
Detail considerations:
|
||||
accurate detail is not displayed yet needed based on preview specifics (driven via highDetailNeeded flag)
|
||||
@@ -177,7 +179,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
|
||||
if (todo & (M_INIT|M_LINDENOISE)) {
|
||||
MyMutex::MyLock lock(minit); // Also used in crop window
|
||||
MyMutex::MyLock initLock(minit); // Also used in crop window
|
||||
|
||||
imgsrc->HLRecovery_Global( params.hlrecovery ); // this handles Color HLRecovery
|
||||
|
||||
@@ -215,17 +217,19 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
imgsrc->getFullSize (fw, fh, tr);
|
||||
PreviewProps pp (0, 0, fw, fh, scale);
|
||||
|
||||
// Will (re)allocate the preview's buffers
|
||||
setScale (scale);
|
||||
|
||||
imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm, params.raw);
|
||||
//ColorTemp::CAT02 (orig_prev, ¶ms) ;
|
||||
|
||||
//imgsrc->convertColorSpace(orig_prev, params.icm, params.raw);
|
||||
//imgsrc->convertColorSpace(orig_prev, params.icm, params.raw);
|
||||
|
||||
if (todo & M_LINDENOISE) {
|
||||
//printf("denoising!\n");
|
||||
if (scale==1 && params.dirpyrDenoise.enabled) {
|
||||
ipf.RGB_denoise(orig_prev, orig_prev, imgsrc->isRAW(), params.dirpyrDenoise, params.defringe, imgsrc->getDirPyrDenoiseExpComp());
|
||||
}
|
||||
//printf("denoising!\n");
|
||||
if (scale==1 && params.dirpyrDenoise.enabled)
|
||||
ipf.RGB_denoise(orig_prev, orig_prev, imgsrc->isRAW(), params.dirpyrDenoise, params.defringe, imgsrc->getDirPyrDenoiseExpComp());
|
||||
}
|
||||
imgsrc->convertColorSpace(orig_prev, params.icm, params.raw);
|
||||
|
||||
@@ -243,30 +247,29 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
if (needstransform && orig_prev==oprevi)
|
||||
oprevi = new Imagefloat (pW, pH);
|
||||
if ((todo & M_TRANSFORM) && needstransform)
|
||||
ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, imgsrc->getMetaData()->getFocalLen(),
|
||||
imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false);
|
||||
ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, imgsrc->getMetaData()->getFocalLen(),
|
||||
imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false);
|
||||
|
||||
readyphase++;
|
||||
|
||||
progress ("Preparing shadow/highlight map...",100*readyphase/numofphases);
|
||||
if ((todo & M_BLURMAP) && params.sh.enabled) {
|
||||
double radius = sqrt (double(pW*pW+pH*pH)) / 2.0;
|
||||
double shradius = params.sh.radius;
|
||||
if (!params.sh.hq) shradius *= radius / 1800.0;
|
||||
shmap->update (oprevi, shradius, ipf.lumimul, params.sh.hq, scale);
|
||||
|
||||
double shradius = params.sh.radius;
|
||||
if (!params.sh.hq) shradius *= radius / 1800.0;
|
||||
shmap->update (oprevi, shradius, ipf.lumimul, params.sh.hq, scale);
|
||||
}
|
||||
readyphase++;
|
||||
|
||||
if (todo & M_AUTOEXP) {
|
||||
if (params.toneCurve.autoexp) {
|
||||
LUTu aehist; int aehistcompr;
|
||||
imgsrc->getAutoExpHistogram (aehist, aehistcompr);
|
||||
ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, params.toneCurve.expcomp,
|
||||
params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh);
|
||||
if (aeListener)
|
||||
aeListener->autoExpChanged (params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast,
|
||||
params.toneCurve.black, params.toneCurve.hlcompr,params.toneCurve.hlcomprthresh);
|
||||
LUTu aehist; int aehistcompr;
|
||||
imgsrc->getAutoExpHistogram (aehist, aehistcompr);
|
||||
ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, params.toneCurve.expcomp,
|
||||
params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh);
|
||||
if (aeListener)
|
||||
aeListener->autoExpChanged (params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast,
|
||||
params.toneCurve.black, params.toneCurve.hlcompr,params.toneCurve.hlcomprthresh);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,10 +281,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
ipf.g = imgsrc->getGamma();
|
||||
ipf.iGamma = true;
|
||||
CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0,
|
||||
params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh,
|
||||
params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast,
|
||||
ipf.g, !ipf.iGamma, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2,
|
||||
vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale==1 ? 1 : 1);
|
||||
params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh,
|
||||
params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast,
|
||||
ipf.g, !ipf.iGamma, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2,
|
||||
vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale==1 ? 1 : 1);
|
||||
|
||||
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1);
|
||||
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale==1 ? 1 : 1);
|
||||
@@ -297,8 +300,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
int x1, y1, x2, y2, pos, poscc;
|
||||
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
|
||||
lhist16.clear(); lhist16Cropped.clear();
|
||||
lhist16Clad.clear(); lhist16CroppedClad.clear();
|
||||
lhist16ClabAF.clear();
|
||||
lhist16Clad.clear(); lhist16CroppedClad.clear();
|
||||
lhist16ClabAF.clear();
|
||||
for (int x=0; x<pH; x++)
|
||||
for (int y=0; y<pW; y++) {
|
||||
pos=CLIP((int)(oprevl->L[x][y]));
|
||||
@@ -308,58 +311,55 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
}
|
||||
readyphase++;
|
||||
utili=false;
|
||||
autili=false;
|
||||
butili=false;
|
||||
ccutili=false;
|
||||
cclutili=false;
|
||||
utili=false;
|
||||
autili=false;
|
||||
butili=false;
|
||||
ccutili=false;
|
||||
cclutili=false;
|
||||
if ((todo & M_LUMACURVE) || todo==CROP) {
|
||||
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped,
|
||||
lumacurve, histLCurve, scale==1 ? 1 : 16, utili);
|
||||
|
||||
}
|
||||
}
|
||||
if (todo & M_LUMACURVE) {
|
||||
CurveFactory::complexsgnCurve (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,lhist16CroppedClad, histCCurve, scale==1 ? 1 : 16);
|
||||
|
||||
}
|
||||
if (todo & (M_LUMINANCE+M_COLOR) ) {
|
||||
nprevl->CopyFrom(oprevl);
|
||||
|
||||
progress ("Applying Color Boost...",100*readyphase/numofphases);
|
||||
int poscc;
|
||||
|
||||
|
||||
ipf.chromiLuminanceCurve (pW,nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve,lhskcurve, lumacurve, utili, autili, butili, ccutili,cclutili, histCCurve);
|
||||
ipf.vibrance(nprevl);
|
||||
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) ipf.EPDToneMap(nprevl,5,1);
|
||||
// for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled
|
||||
readyphase++;
|
||||
if (scale==1) {
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
progress ("Denoising luminance impulse...",100*readyphase/numofphases);
|
||||
ipf.impulsedenoise (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
progress ("Defringing...",100*readyphase/numofphases);
|
||||
ipf.defringe (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
if (params.sharpenEdge.enabled) {
|
||||
CurveFactory::complexsgnCurve (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,lhist16CroppedClad, histCCurve, scale==1 ? 1 : 16);
|
||||
}
|
||||
if (todo & (M_LUMINANCE+M_COLOR) ) {
|
||||
nprevl->CopyFrom(oprevl);
|
||||
|
||||
progress ("Applying Color Boost...",100*readyphase/numofphases);
|
||||
int poscc;
|
||||
|
||||
ipf.chromiLuminanceCurve (pW,nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve,lhskcurve, lumacurve, utili, autili, butili, ccutili,cclutili, histCCurve);
|
||||
ipf.vibrance(nprevl);
|
||||
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) ipf.EPDToneMap(nprevl,5,1);
|
||||
// for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled
|
||||
readyphase++;
|
||||
if (scale==1) {
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
progress ("Denoising luminance impulse...",100*readyphase/numofphases);
|
||||
ipf.impulsedenoise (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
progress ("Defringing...",100*readyphase/numofphases);
|
||||
ipf.defringe (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
if (params.sharpenEdge.enabled) {
|
||||
progress ("Edge sharpening...",100*readyphase/numofphases);
|
||||
ipf.MLsharpen (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
if (params.sharpenMicro.enabled) {
|
||||
if(( params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
progress ("Microcontrast...",100*readyphase/numofphases);
|
||||
ipf.MLmicrocontrast (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
}
|
||||
if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) {
|
||||
ipf.MLsharpen (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
if (params.sharpenMicro.enabled) {
|
||||
if(( params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
progress ("Microcontrast...",100*readyphase/numofphases);
|
||||
ipf.MLmicrocontrast (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
}
|
||||
if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) {
|
||||
progress ("Sharpening...",100*readyphase/numofphases);
|
||||
|
||||
float **buffer = new float*[pH];
|
||||
@@ -373,84 +373,92 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
delete [] buffer;
|
||||
readyphase++;
|
||||
}
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
// if(params.colorappearance.enabled && !params.colorappearance.sharpcie){
|
||||
progress ("Pyramid equalizer...",100*readyphase/numofphases);
|
||||
ipf.dirpyrequalizer (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
|
||||
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
|
||||
//if(params.colorappearance.enabled && !params.colorappearance.sharpcie){
|
||||
progress ("Pyramid equalizer...",100*readyphase/numofphases);
|
||||
ipf.dirpyrequalizer (nprevl);
|
||||
readyphase++;
|
||||
}
|
||||
}
|
||||
//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
|
||||
|
||||
//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(); lhist16CroppedCCAM.clear();
|
||||
lhist16CCAMAF.clear();
|
||||
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
|
||||
lhist16CAM.clear(); lhist16CroppedCAM.clear();
|
||||
lhist16CCAM.clear(); lhist16CroppedCCAM.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(!params.colorappearance.datacie) lhist16CCAM[posc]++;
|
||||
if(!params.colorappearance.datacie)lhist16CAM[pos]++;
|
||||
if (y>=y1 && y<y2 && x>=x1 && x<x2) {lhist16CroppedCAM[pos]++;lhist16CroppedCCAM[posc]++;}
|
||||
}
|
||||
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, lhist16CroppedCCAM,histCCAM,
|
||||
customColCurve1,
|
||||
customColCurve2,
|
||||
customColCurve3,
|
||||
scale==1 ? 1 : 1);
|
||||
int Iterates=0;
|
||||
if(params.colorappearance.enabled){
|
||||
float fnum = imgsrc->getMetaData()->getFNumber ();// F number
|
||||
float fiso = imgsrc->getMetaData()->getISOSpeed () ;// ISO
|
||||
float fspeed = imgsrc->getMetaData()->getShutterSpeed () ;//speed
|
||||
float fcomp = imgsrc->getMetaData()->getExpComp ();//compensation + -
|
||||
float adap2,adap;
|
||||
double ada, ada2;
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) {adap=adap=2000.f;ada=2000.;}//if no exif data or wrong
|
||||
else {
|
||||
float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f));
|
||||
float expo2= params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += expo2;
|
||||
float expo1;//exposure raw white point
|
||||
expo1=log2(params.raw.expos);//log2 ==>linear to EV
|
||||
E_V += expo1;
|
||||
adap2 = adap= powf(2.f, E_V-3.f);//cd / m2
|
||||
ada=ada2=(double) adap;
|
||||
//end calculation adaptation scene luminosity
|
||||
}
|
||||
int begh=0;
|
||||
int endh=pH;
|
||||
float d;
|
||||
double dd;
|
||||
float **buffer = new float*[pH];
|
||||
for (int i=0; i<pH; i++)
|
||||
buffer[i] = new float[pW];
|
||||
bool execsharp=false;
|
||||
if(scale==1) execsharp=true;
|
||||
if(settings->ciecamfloat){ipf.ciecam_02float (ncie, adap, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, execsharp, d);
|
||||
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*(double)d);
|
||||
if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap2);//real value of adapt scene luminosity
|
||||
}
|
||||
else {ipf.ciecam_02 (ncie, ada, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, execsharp, dd);
|
||||
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*dd);
|
||||
if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(ada);
|
||||
|
||||
}
|
||||
for (int i=0; i<pH; i++)
|
||||
delete [] buffer[i];
|
||||
delete [] buffer;
|
||||
readyphase++;
|
||||
}
|
||||
}
|
||||
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, lhist16CroppedCCAM,histCCAM,
|
||||
customColCurve1,
|
||||
customColCurve2,
|
||||
customColCurve3,
|
||||
scale==1 ? 1 : 1
|
||||
);
|
||||
if(params.colorappearance.enabled){
|
||||
float fnum = imgsrc->getMetaData()->getFNumber (); // F number
|
||||
float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO
|
||||
float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed
|
||||
double fcomp = imgsrc->getMetaData()->getExpComp (); // Compensation +/-
|
||||
double adap;
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong
|
||||
adap=2000.;
|
||||
}
|
||||
else {
|
||||
double E_V = fcomp + log2 (double((fnum*fnum) / fspeed / (fiso/100.f)));
|
||||
E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += log2(params.raw.expos);// exposure raw white point ; log2 ==> linear to EV
|
||||
adap= powf(2.f, E_V-3.f);// cd / m2
|
||||
// end calculation adaptation scene luminosity
|
||||
}
|
||||
int begh=0;
|
||||
int endh=pH;
|
||||
float d;
|
||||
double dd;
|
||||
float **buffer = new float*[pH];
|
||||
for (int i=0; i<pH; i++)
|
||||
buffer[i] = new float[pW];
|
||||
bool execsharp=false;
|
||||
if(scale==1) execsharp=true;
|
||||
|
||||
if(!ncie)
|
||||
ncie = new CieImage (pW, pH);
|
||||
|
||||
if(settings->ciecamfloat){
|
||||
ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, execsharp, d);
|
||||
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*(double)d);
|
||||
if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap);//real value of adapt scene luminosity
|
||||
}
|
||||
else {
|
||||
ipf.ciecam_02 (ncie, adap, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, execsharp, dd);
|
||||
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*dd);
|
||||
if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap);
|
||||
}
|
||||
|
||||
for (int i=0; i<pH; i++)
|
||||
delete [] buffer[i];
|
||||
delete [] buffer;
|
||||
readyphase++;
|
||||
}
|
||||
else {
|
||||
// CIECAM is disbaled, we free up its image buffer to save some space
|
||||
if (ncie)
|
||||
delete ncie; ncie=NULL;
|
||||
}
|
||||
}
|
||||
// process crop, if needed
|
||||
for (size_t i=0; i<crops.size(); i++)
|
||||
if (crops[i]->hasListener () && cropCall != crops[i] )
|
||||
@@ -458,29 +466,26 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
progress ("Conversion to RGB...",100*readyphase/numofphases);
|
||||
if (todo!=CROP) {
|
||||
previmg->getMutex().lock();
|
||||
MyMutex::MyLock prevImgLock(previmg->getMutex());
|
||||
try
|
||||
{
|
||||
ipf.lab2monitorRgb (nprevl, previmg);
|
||||
delete workimg;
|
||||
workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, params.icm.working);
|
||||
workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, params.icm.working);
|
||||
}
|
||||
catch(char * str)
|
||||
{
|
||||
progress ("Error converting file...",0);
|
||||
previmg->getMutex().unlock();
|
||||
mProcessing.unlock ();
|
||||
return;
|
||||
}
|
||||
previmg->getMutex().unlock();
|
||||
}
|
||||
}
|
||||
if (!resultValid) {
|
||||
resultValid = true;
|
||||
if (imageListener)
|
||||
imageListener->setImage (previmg, scale, params.crop);
|
||||
}
|
||||
if (imageListener)
|
||||
// TODO: The WB tool should be advertised too in order to get the AutoWB's temp and green values
|
||||
// TODO: The WB tool should be advertised too in order to get the AutoWB's temp and green values
|
||||
imageListener->imageReady (params.crop);
|
||||
|
||||
readyphase++;
|
||||
@@ -489,8 +494,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
updateLRGBHistograms ();
|
||||
hListener->histogramChanged (histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve,histCCurve, histLCAM, histCCAM, histRedRaw, histGreenRaw, histBlueRaw, histChroma);
|
||||
}
|
||||
|
||||
mProcessing.unlock ();
|
||||
}
|
||||
|
||||
|
||||
@@ -500,18 +503,19 @@ void ImProcCoordinator::freeAll () {
|
||||
|
||||
if (allocated) {
|
||||
if (orig_prev!=oprevi)
|
||||
delete oprevi;
|
||||
delete orig_prev;
|
||||
delete oprevl;
|
||||
delete nprevl;
|
||||
delete ncie;
|
||||
|
||||
delete oprevi; oprevi = NULL;
|
||||
delete orig_prev; orig_prev = NULL;
|
||||
delete oprevl; oprevl = NULL;
|
||||
delete nprevl; nprevl = NULL;
|
||||
if (ncie)
|
||||
delete ncie; ncie = NULL;
|
||||
|
||||
if (imageListener) {
|
||||
imageListener->delImage (previmg);
|
||||
}
|
||||
else
|
||||
delete previmg;
|
||||
|
||||
|
||||
delete workimg;
|
||||
delete shmap;
|
||||
|
||||
@@ -519,6 +523,12 @@ void ImProcCoordinator::freeAll () {
|
||||
allocated = false;
|
||||
}
|
||||
|
||||
/** @brief Handles image buffer (re)allocation and trigger sizeChanged of SizeListener[s]
|
||||
* If the scale change, this method will free all buffers and reallocate ones of the new size.
|
||||
* It will then tell to the SizeListener that size has changed (sizeChanged)
|
||||
*
|
||||
* @param prevscale New Preview's scale.
|
||||
*/
|
||||
void ImProcCoordinator::setScale (int prevscale) {
|
||||
|
||||
if (settings->verbose) printf ("setscale before lock\n");
|
||||
@@ -529,7 +539,7 @@ if (settings->verbose) printf ("setscale before lock\n");
|
||||
if (params.coarse.rotate==270) tr |= TR_R270;
|
||||
if (params.coarse.hflip) tr |= TR_HFLIP;
|
||||
if (params.coarse.vflip) tr |= TR_VFLIP;
|
||||
|
||||
|
||||
int nW, nH;
|
||||
imgsrc->getFullSize (fw, fh, tr);
|
||||
|
||||
@@ -541,22 +551,22 @@ if (settings->verbose) printf ("setscale before lock\n");
|
||||
if (nW!=pW || nH!=pH) {
|
||||
|
||||
freeAll ();
|
||||
|
||||
|
||||
pW = nW;
|
||||
pH = nH;
|
||||
|
||||
|
||||
orig_prev = new Imagefloat (pW, pH);
|
||||
oprevi = orig_prev;
|
||||
oprevl = new LabImage (pW, pH);
|
||||
nprevl = new LabImage (pW, pH);
|
||||
ncie = new CieImage (pW, pH);
|
||||
oprevl = new LabImage (pW, pH);
|
||||
nprevl = new LabImage (pW, pH);
|
||||
//ncie is only used in ImProcCoordinator::updatePreviewImage, it will be allocated on first use and deleted if not used anymore
|
||||
previmg = new Image8 (pW, pH);
|
||||
workimg = new Image8 (pW, pH);
|
||||
workimg = new Image8 (pW, pH);
|
||||
shmap = new SHMap (pW, pH, true);
|
||||
|
||||
allocated = true;
|
||||
}
|
||||
|
||||
|
||||
scale = prevscale;
|
||||
resultValid = false;
|
||||
fullw = fw;
|
||||
@@ -578,13 +588,13 @@ void ImProcCoordinator::updateLRGBHistograms () {
|
||||
histRed.clear();
|
||||
histGreen.clear();
|
||||
histBlue.clear();
|
||||
|
||||
|
||||
for (int i=y1; i<y2; i++) {
|
||||
int ofs = (i*pW + x1)*3;
|
||||
for (int j=x1; j<x2; j++) {
|
||||
int r=workimg->data[ofs++];
|
||||
int g=workimg->data[ofs++];
|
||||
int b=workimg->data[ofs++];
|
||||
int r=workimg->data[ofs++];
|
||||
int g=workimg->data[ofs++];
|
||||
int b=workimg->data[ofs++];
|
||||
|
||||
histRed[r]++;
|
||||
histGreen[g]++;
|
||||
@@ -592,23 +602,22 @@ void ImProcCoordinator::updateLRGBHistograms () {
|
||||
}
|
||||
}
|
||||
|
||||
histLuma.clear();
|
||||
histChroma.clear();
|
||||
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]));
|
||||
}*/
|
||||
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) {
|
||||
@@ -657,7 +666,10 @@ void ImProcCoordinator::getCamWB (double& temp, double& green) {
|
||||
|
||||
void ImProcCoordinator::getSpotWB (int x, int y, int rect, double& temp, double& tgreen) {
|
||||
|
||||
mProcessing.lock ();
|
||||
ColorTemp ret;
|
||||
|
||||
{
|
||||
MyMutex::MyLock lock(mProcessing);
|
||||
std::vector<Coord2D> points, red, green, blue;
|
||||
for (int i=y-rect; i<=y+rect; i++)
|
||||
for (int j=x-rect; j<=x+rect; j++)
|
||||
@@ -670,25 +682,25 @@ void ImProcCoordinator::getSpotWB (int x, int y, int rect, double& temp, double&
|
||||
if (params.coarse.rotate==270) tr |= TR_R270;
|
||||
if (params.coarse.hflip) tr |= TR_HFLIP;
|
||||
if (params.coarse.vflip) tr |= TR_VFLIP;
|
||||
ColorTemp ret = imgsrc->getSpotWB (red, green, blue, tr, params.wb.equal);
|
||||
ret = imgsrc->getSpotWB (red, green, blue, tr, params.wb.equal);
|
||||
currWB = ColorTemp (params.wb.temperature, params.wb.green,params.wb.equal, params.wb.method);
|
||||
//double rr,gg,bb;
|
||||
//currWB.getMultipliers(rr,gg,bb);
|
||||
|
||||
mProcessing.unlock ();
|
||||
} // end of mutex lockong
|
||||
|
||||
if (ret.getTemp() > 0) {
|
||||
temp = ret.getTemp ();
|
||||
tgreen = ret.getGreen ();
|
||||
} else {
|
||||
temp = currWB.getTemp ();
|
||||
tgreen = currWB.getGreen ();
|
||||
}
|
||||
if (ret.getTemp() > 0) {
|
||||
temp = ret.getTemp ();
|
||||
tgreen = ret.getGreen ();
|
||||
} else {
|
||||
temp = currWB.getTemp ();
|
||||
tgreen = currWB.getGreen ();
|
||||
}
|
||||
}
|
||||
|
||||
void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &h) {
|
||||
|
||||
mProcessing.lock ();
|
||||
MyMutex::MyLock lock(mProcessing);
|
||||
|
||||
LCPMapper *pLCPMap=NULL;
|
||||
if (params.lensProf.lcpFile.length() && imgsrc->getMetaData()->getFocalLen()>0) {
|
||||
@@ -700,26 +712,24 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &
|
||||
double fillscale = ipf.getTransformAutoFill (fullw, fullh, pLCPMap);
|
||||
if (ratio>0) {
|
||||
w = fullw * fillscale;
|
||||
h = w / ratio;
|
||||
if (h > fullh * fillscale) {
|
||||
h = fullh * fillscale;
|
||||
w = h * ratio;
|
||||
}
|
||||
h = w / ratio;
|
||||
if (h > fullh * fillscale) {
|
||||
h = fullh * fillscale;
|
||||
w = h * ratio;
|
||||
}
|
||||
}
|
||||
else {
|
||||
w = fullw * fillscale;
|
||||
h = fullh * fillscale;
|
||||
h = fullh * fillscale;
|
||||
}
|
||||
x = (fullw - w) / 2;
|
||||
y = (fullh - h) / 2;
|
||||
|
||||
mProcessing.unlock ();
|
||||
}
|
||||
|
||||
|
||||
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
|
||||
|
||||
mProcessing.lock ();
|
||||
MyMutex::MyLock lock(mProcessing);
|
||||
|
||||
int fW, fH;
|
||||
imgsrc->getFullSize (fW, fH, 0);
|
||||
@@ -758,7 +768,6 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
|
||||
im16->saveTIFF (fname,16,true);
|
||||
delete im16;
|
||||
//im->saveJPEG (fname, 85);
|
||||
mProcessing.unlock ();
|
||||
}
|
||||
|
||||
void ImProcCoordinator::stopProcessing () {
|
||||
|
@@ -35,8 +35,17 @@ using namespace procparams;
|
||||
|
||||
class Crop;
|
||||
|
||||
// Manages the image processing, espc. of the preview windows
|
||||
// There is one ImProcCoordinator per edit panel
|
||||
/** @brief Manages the image processing, espc. of the preview windows
|
||||
*
|
||||
* There is one ImProcCoordinator per edit panel.
|
||||
*
|
||||
* The ImProcCoordinator handle an sized down image representation of the full image, that is used when paning
|
||||
* and in the Navigator object.
|
||||
*
|
||||
* Each ImProcCoordinator handles an rtengine::Crop list, which process images too with their own pipeline,
|
||||
* but using this class' LUT and other precomputed parameters. The main preview area is displaying a non framed Crop object,
|
||||
* while detail windows are framed Crop objects.
|
||||
*/
|
||||
class ImProcCoordinator : public StagedImageProcessor {
|
||||
|
||||
friend class Crop;
|
||||
@@ -44,11 +53,11 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
protected:
|
||||
Imagefloat *orig_prev;
|
||||
Imagefloat *oprevi;
|
||||
LabImage *oprevl;
|
||||
LabImage *nprevl;
|
||||
LabImage *oprevl;
|
||||
LabImage *nprevl;
|
||||
Image8 *previmg;
|
||||
Image8 *workimg;
|
||||
CieImage *ncie;
|
||||
CieImage *ncie;
|
||||
|
||||
ImageSource* imgsrc;
|
||||
|
||||
@@ -82,10 +91,10 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
LUTu lhist16,lhist16Cropped;
|
||||
LUTu lhist16CAM,lhist16CroppedCAM;
|
||||
LUTu lhist16CCAM,lhist16CroppedCCAM;
|
||||
LUTu lhist16CCAMAF;
|
||||
LUTu lhist16ClabAF;
|
||||
LUTu histCropped;
|
||||
LUTu lhist16Clad,lhist16CroppedClad;
|
||||
LUTu lhist16CCAMAF;
|
||||
LUTu lhist16ClabAF;
|
||||
LUTu histCropped;
|
||||
LUTu lhist16Clad,lhist16CroppedClad;
|
||||
LUTu histRed, histRedRaw;
|
||||
LUTu histGreen, histGreenRaw;
|
||||
LUTu histBlue, histBlueRaw;
|
||||
@@ -94,11 +103,11 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
LUTf rCurve;
|
||||
LUTf gCurve;
|
||||
LUTf bCurve;
|
||||
bool utili;
|
||||
bool autili;
|
||||
bool butili;
|
||||
bool ccutili;
|
||||
bool cclutili;
|
||||
bool utili;
|
||||
bool autili;
|
||||
bool butili;
|
||||
bool ccutili;
|
||||
bool cclutili;
|
||||
|
||||
ToneCurve customToneCurve1;
|
||||
ToneCurve customToneCurve2;
|
||||
@@ -124,7 +133,7 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
|
||||
bool resultValid;
|
||||
|
||||
MyMutex minit;
|
||||
MyMutex minit; // to gain mutually exclusive access to ... to what exactly?
|
||||
|
||||
void progress (Glib::ustring str, int pr);
|
||||
void reallocAll ();
|
||||
@@ -189,7 +198,7 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
void setAutoCamListener (AutoCamListener* acl) {acListener = acl; }
|
||||
|
||||
void saveInputICCReference (const Glib::ustring& fname);
|
||||
|
||||
|
||||
InitialImage* getInitialImage () { return imgsrc; }
|
||||
};
|
||||
}
|
||||
|
@@ -250,12 +250,13 @@ namespace rtengine {
|
||||
virtual void autoExpChanged (double brightness, int bright, int contrast, int black, int hlcompr, int hlcomprthresh) {}
|
||||
};
|
||||
|
||||
class AutoCamListener {
|
||||
public :
|
||||
virtual void autoCamChanged (double ccam) {}
|
||||
virtual void adapCamChanged (double cadap) {}
|
||||
|
||||
};
|
||||
class AutoCamListener {
|
||||
public :
|
||||
virtual ~AutoCamListener() {}
|
||||
virtual void autoCamChanged (double ccam) {}
|
||||
virtual void adapCamChanged (double cadap) {}
|
||||
};
|
||||
|
||||
/** This class represents a detailed part of the image (looking through a kind of window).
|
||||
* It can be created and destroyed with the appropriate members of StagedImageProcessor.
|
||||
* Several crops can be assigned to the same image. */
|
||||
|
@@ -42,8 +42,10 @@ CropHandler::~CropHandler () {
|
||||
ipc->delSizeListener (this);
|
||||
|
||||
setEnabled (false);
|
||||
if (crop)
|
||||
if (crop) {
|
||||
crop->destroy ();
|
||||
crop = NULL;
|
||||
}
|
||||
cimg.lock ();
|
||||
if (chi->pending)
|
||||
chi->destroyed = true;
|
||||
|
@@ -82,15 +82,15 @@ void ImageArea::on_resized (Gtk::Allocation& req) {
|
||||
mainCropWindow->addCropWindowListener (this);
|
||||
mainCropWindow->setCropGUIListener (cropgl);
|
||||
mainCropWindow->setPointerMotionListener (pmlistener);
|
||||
mainCropWindow->setPointerMotionHListener (pmhlistener);
|
||||
mainCropWindow->setPointerMotionHListener (pmhlistener);
|
||||
mainCropWindow->setPosition (0, 0);
|
||||
mainCropWindow->setSize (get_width(), get_height(), false); // this execute the refresh itself
|
||||
}
|
||||
else {
|
||||
mainCropWindow->setSize (get_width(), get_height());
|
||||
}
|
||||
parent->syncBeforeAfterViews();
|
||||
}
|
||||
parent->syncBeforeAfterViews();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_) {
|
||||
|
Reference in New Issue
Block a user