Crop-awareness of Lab curve histogram+cleanups; see issue #667
This commit is contained in:
parent
69f42cd8d4
commit
8ac9e46f4f
@ -396,7 +396,7 @@ namespace rtengine {
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void CurveFactory::complexLCurve (double br, double contr, const std::vector<double>& curvePoints, \
|
||||
LUTu & histogram, LUTf & outCurve, \
|
||||
LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve, \
|
||||
LUTu & outBeforeCCurveHistogram, int skip) {
|
||||
|
||||
// curve without contrast
|
||||
@ -422,21 +422,21 @@ namespace rtengine {
|
||||
std::vector<double> brightcurvePoints;
|
||||
brightcurvePoints.push_back((double)((CurveType)DCT_NURBS));
|
||||
|
||||
brightcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
brightcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
brightcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
|
||||
brightcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
|
||||
|
||||
if(br>0) {
|
||||
brightcurvePoints.push_back(0.1); //toe point
|
||||
if (br>0) {
|
||||
brightcurvePoints.push_back(0.1); // toe point
|
||||
brightcurvePoints.push_back(0.1+br/150.0); //value at toe point
|
||||
|
||||
brightcurvePoints.push_back(0.7); //shoulder point
|
||||
brightcurvePoints.push_back(0.7); // shoulder point
|
||||
brightcurvePoints.push_back(MIN(1.0,0.7+br/300.0)); //value at shoulder point
|
||||
} else {
|
||||
brightcurvePoints.push_back(0.1-br/150.0); //toe point
|
||||
brightcurvePoints.push_back(0.1); //value at toe point
|
||||
brightcurvePoints.push_back(0.1-br/150.0); // toe point
|
||||
brightcurvePoints.push_back(0.1); // value at toe point
|
||||
|
||||
brightcurvePoints.push_back(MIN(1.0,0.7-br/300.0)); //shoulder point
|
||||
brightcurvePoints.push_back(0.7); //value at shoulder point
|
||||
brightcurvePoints.push_back(MIN(1.0,0.7-br/300.0)); // shoulder point
|
||||
brightcurvePoints.push_back(0.7); // value at shoulder point
|
||||
}
|
||||
brightcurvePoints.push_back(1); // white point
|
||||
brightcurvePoints.push_back(1); // value at white point
|
||||
@ -444,7 +444,7 @@ namespace rtengine {
|
||||
DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); // Actually, CURVES_MIN_POLY_POINTS = 1000,
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
for (int i=0; i<32768; i++) {//L values range up to 32767, higher values are for highlight overflow
|
||||
for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow
|
||||
|
||||
// change to [0,1] range
|
||||
float val = (float)i / 32767.0;
|
||||
@ -478,14 +478,14 @@ namespace rtengine {
|
||||
std::vector<double> contrastcurvePoints;
|
||||
contrastcurvePoints.push_back((double)((CurveType)DCT_NURBS));
|
||||
|
||||
contrastcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
contrastcurvePoints.push_back(0); //black point. Value in [0 ; 1] range
|
||||
contrastcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
|
||||
contrastcurvePoints.push_back(0); // black point. Value in [0 ; 1] range
|
||||
|
||||
contrastcurvePoints.push_back(avg-avg*(0.6-contr/250.0)); //toe point
|
||||
contrastcurvePoints.push_back(avg-avg*(0.6+contr/250.0)); //value at toe point
|
||||
contrastcurvePoints.push_back(avg-avg*(0.6-contr/250.0)); // toe point
|
||||
contrastcurvePoints.push_back(avg-avg*(0.6+contr/250.0)); // value at toe point
|
||||
|
||||
contrastcurvePoints.push_back(avg+(1-avg)*(0.6-contr/250.0)); //shoulder point
|
||||
contrastcurvePoints.push_back(avg+(1-avg)*(0.6+contr/250.0)); //value at shoulder point
|
||||
contrastcurvePoints.push_back(avg+(1-avg)*(0.6-contr/250.0)); // shoulder point
|
||||
contrastcurvePoints.push_back(avg+(1-avg)*(0.6+contr/250.0)); // value at shoulder point
|
||||
|
||||
contrastcurvePoints.push_back(1); // white point
|
||||
contrastcurvePoints.push_back(1); // value at white point
|
||||
@ -502,7 +502,7 @@ namespace rtengine {
|
||||
}
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
for (int i=0; i<32768; i++) {//L values go up to 32767, last stop is for highlight overflow
|
||||
for (int i=0; i<32768; i++) { // L values go up to 32767, last stop is for highlight overflow
|
||||
float val;
|
||||
|
||||
// apply custom/parametric/NURBS curve, if any
|
||||
@ -510,7 +510,7 @@ namespace rtengine {
|
||||
if (outBeforeCCurveHistogram) {
|
||||
float hval = dcurve[i];
|
||||
int hi = (int)(255.0*CLIPD(hval));
|
||||
outBeforeCCurveHistogram[hi]+=histogram[i] ;
|
||||
outBeforeCCurveHistogram[hi]+=histogramCropped[i] ;
|
||||
}
|
||||
val = tcurve->getVal (dcurve[i]);
|
||||
} else {
|
||||
|
@ -209,7 +209,8 @@ class CurveFactory {
|
||||
LUTu & histogram, LUTu & histogramCropped, LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1);
|
||||
static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector<double>& acurvePoints, \
|
||||
const std::vector<double>& bcurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip=1);
|
||||
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
|
||||
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped,
|
||||
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
|
||||
};
|
||||
|
||||
class Curve {
|
||||
|
@ -237,7 +237,7 @@ Imagefloat::to16() const
|
||||
}
|
||||
|
||||
|
||||
void Imagefloat::CalcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist) {
|
||||
void Imagefloat::calcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist) {
|
||||
hist.clear();
|
||||
|
||||
// Set up factors to calc the lightness
|
||||
@ -249,18 +249,13 @@ void Imagefloat::CalcCroppedHistogram(const ProcParams ¶ms, float scale, LUT
|
||||
|
||||
|
||||
// calc pixel size
|
||||
int hx1 = 0, hx2 = width, hy1 = 0, hy2 = height;
|
||||
if (params.crop.enabled) {
|
||||
hx1 = MIN(width-1,MAX(0,params.crop.x / scale));
|
||||
hy1 = MIN(height-1,MAX(0,params.crop.y / scale));
|
||||
hx2 = MIN(width,MAX(0,(params.crop.x+params.crop.w) / scale));
|
||||
hy2 = MIN(height,MAX(0,(params.crop.y+params.crop.h) / scale));
|
||||
}
|
||||
int x1, x2, y1, y2;
|
||||
params.crop.mapToResized(width, height, scale, x1, x2, y1, y2);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int y=hy1; y<hy2; y++) {
|
||||
for (int y=y1; y<y2; y++) {
|
||||
int i;
|
||||
for (int x=hx1; x<hx2; x++) {
|
||||
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;
|
||||
hist[i]++;
|
||||
|
@ -89,7 +89,7 @@ class Imagefloat : public ImageIO, public IImagefloat {
|
||||
virtual float** getGPlane () { return g; }
|
||||
virtual float** getBPlane () { return b; }
|
||||
|
||||
void CalcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist);
|
||||
void calcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist);
|
||||
|
||||
void ExecCMSTransform(cmsHTRANSFORM hTransform, bool safe);
|
||||
};
|
||||
|
@ -44,7 +44,7 @@ ImProcCoordinator::ImProcCoordinator ()
|
||||
satcurve(65536,0);
|
||||
|
||||
vhist16(65536);
|
||||
lhist16(65536);
|
||||
lhist16(65536); lhist16Cropped(65536);
|
||||
histCropped(65536);
|
||||
|
||||
histRed(256); histRedRaw(256);
|
||||
@ -189,7 +189,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases);
|
||||
if ((todo & M_RGBCURVE) || todo==CROP) {
|
||||
if (hListener) oprevi->CalcCroppedHistogram(params, scale, histCropped);
|
||||
if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped);
|
||||
|
||||
// complexCurve also calculated pre-curves histogram dependend on crop
|
||||
CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, \
|
||||
@ -201,18 +201,30 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
// if it's just crop we just need the histogram, no image updates
|
||||
if ( todo!=CROP ) {
|
||||
ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation);
|
||||
|
||||
// compute L channel histogram
|
||||
lhist16.clear();
|
||||
for (int i=0; i<pH; i++)
|
||||
for (int j=0; j<pW; j++)
|
||||
lhist16[CLIP((int)(oprevl->L[i][j]))]++;
|
||||
}
|
||||
|
||||
// compute L channel histogram
|
||||
int x1, y1, x2, y2, pos;
|
||||
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
|
||||
|
||||
lhist16.clear(); lhist16Cropped.clear();
|
||||
for (int x=0; x<pH; x++)
|
||||
for (int y=0; y<pW; y++) {
|
||||
pos=CLIP((int)(oprevl->L[x][y]));
|
||||
lhist16[pos]++;
|
||||
|
||||
if (y>=y1 && y<y2 && x>=x1 && x<x2) lhist16Cropped[pos]++;
|
||||
}
|
||||
|
||||
}
|
||||
readyphase++;
|
||||
|
||||
if ((todo & M_LUMACURVE) || todo==CROP) {
|
||||
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped,
|
||||
lumacurve, histLCurve, scale==1 ? 1 : 16);
|
||||
}
|
||||
|
||||
if (todo & M_LUMACURVE) {
|
||||
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lumacurve, histLCurve, scale==1 ? 1 : 16);
|
||||
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
|
||||
params.labCurve.acurve, params.labCurve.bcurve, chroma_acurve, chroma_bcurve, satcurve, scale==1 ? 1 : 16);
|
||||
}
|
||||
@ -296,14 +308,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
readyphase++;
|
||||
|
||||
if (hListener) {
|
||||
int hx1 = 0, hx2 = pW, hy1 = 0, hy2 = pH;
|
||||
if (params.crop.enabled) {
|
||||
hx1 = MIN(pW-1,MAX(0,params.crop.x / scale));
|
||||
hy1 = MIN(pH-1,MAX(0,params.crop.y / scale));
|
||||
hx2 = MIN(pW,MAX(0,(params.crop.x+params.crop.w) / scale));
|
||||
hy2 = MIN(pH,MAX(0,(params.crop.y+params.crop.h) / scale));
|
||||
}
|
||||
updateHistograms (hx1, hy1, hx2, hy2); // just RGBL, not the tone curves
|
||||
updateLRGBHistograms ();
|
||||
hListener->histogramChanged (histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, histRedRaw, histGreenRaw, histBlueRaw);
|
||||
}
|
||||
|
||||
@ -386,7 +391,10 @@ if (settings->verbose) printf ("setscale before lock\n");
|
||||
}
|
||||
|
||||
|
||||
void ImProcCoordinator::updateHistograms (int x1, int y1, int x2, int y2) {
|
||||
void ImProcCoordinator::updateLRGBHistograms () {
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
|
||||
|
||||
histRed.clear();
|
||||
histGreen.clear();
|
||||
|
@ -75,7 +75,7 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
LUTf satcurve;
|
||||
|
||||
LUTu vhist16;
|
||||
LUTu lhist16;
|
||||
LUTu lhist16,lhist16Cropped;
|
||||
LUTu histCropped;
|
||||
|
||||
LUTu histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, bcabhist;
|
||||
@ -98,7 +98,7 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
|
||||
void progress (Glib::ustring str, int pr);
|
||||
void reallocAll ();
|
||||
void updateHistograms (int x1, int y1, int x2, int y2);
|
||||
void updateLRGBHistograms ();
|
||||
void setScale (int prevscale);
|
||||
void updatePreviewImage (int todo, Crop* cropCall= NULL);
|
||||
|
||||
|
@ -37,6 +37,17 @@ namespace procparams {
|
||||
const char *RAWParams::methodstring[RAWParams::numMethods]={"eahd", "hphd", "vng4", "dcb", "amaze", "ahd", "fast" };
|
||||
const char *RAWParams::ff_BlurTypestring[RAWParams::numFlatFileBlurTypes]={/*"Parametric",*/ "Area Flatfield", "Vertical Flatfield", "Horizontal Flatfield", "V+H Flatfield"};
|
||||
|
||||
// Maps crop to resized width (e.g. smaller previews)
|
||||
void CropParams::mapToResized(int resizedWidth, int resizedHeight, int scale, int &x1, int &x2, int &y1, int &y2) const {
|
||||
x1 = 0, x2 = resizedWidth, y1 = 0, y2 = resizedHeight;
|
||||
if (enabled) {
|
||||
x1 = MIN(resizedWidth-1, MAX(0, x / scale));
|
||||
y1 = MIN(resizedHeight-1, MAX(0, y / scale));
|
||||
x2 = MIN(resizedWidth, MAX(0, (x+w) / scale));
|
||||
y2 = MIN(resizedHeight, MAX(0, (y+h) / scale));
|
||||
}
|
||||
}
|
||||
|
||||
ProcParams::ProcParams () {
|
||||
|
||||
setDefaults ();
|
||||
|
@ -209,6 +209,8 @@ class CropParams {
|
||||
Glib::ustring ratio;
|
||||
Glib::ustring orientation;
|
||||
Glib::ustring guide;
|
||||
|
||||
void mapToResized(int resizedWidth, int resizedHeight, int scale, int &x1, int &x2, int &y1, int &y2) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -739,7 +739,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
||||
hist16[(int)(2*(labView->L[i][j]))]++;
|
||||
|
||||
// luminance processing
|
||||
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, curve, dummy, 16);
|
||||
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,
|
||||
hist16, hist16, curve, dummy, 16);
|
||||
ipf.luminanceCurve (labView, labView, curve);
|
||||
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
|
||||
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 16);
|
||||
|
@ -169,7 +169,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
hist16[CLIP((int)((labView->L[i][j])))]++;
|
||||
|
||||
// luminance processing
|
||||
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, curve, dummy, 1);
|
||||
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1);
|
||||
ipf.luminanceCurve (labView, labView, curve);
|
||||
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
|
||||
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user