Flat curve editor widget, HSV tool modified to use it.

Usage :
 - click & drag a control point to move it in X&Y direction
 - click & drag a vertical line to move it in horizontal or vertical direction (the very first move will be used to determine the motion direction)
 - click & drag the yellow or blue square handle to modify the tangent of the same color
This commit is contained in:
Hombre
2011-03-24 00:39:48 +01:00
parent e57a56b40f
commit eb4b2d8781
44 changed files with 4778 additions and 2136 deletions

View File

@@ -28,6 +28,7 @@
#include <glibmm.h>
#include <iccstore.h>
#include <impulse_denoise.h>
#include <utils.h>
#ifdef _OPENMP
#include <omp.h>
@@ -294,16 +295,28 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur
int tH = working->height;
int r, g, b;
float h, s, v;
float satparam,valparam;
int hue, hueband, hueres, nbrband;
double pi = M_PI;
FlatCurve* hCurve;
FlatCurve* sCurve;
FlatCurve* vCurve;
float* cossq = new float [8093];
for (int i=0; i<8093; i++)
cossq[i] = SQR(cos(pi*(float)i/16384));
#pragma omp parallel for private(r, g, b,factor,mapval,h,s,v,hue,hueband,hueres,nbrband,satparam,valparam) if (multiThread)
FlatCurveType hCurveType = (FlatCurveType)params->hsvequalizer.hcurve.at(0);
FlatCurveType sCurveType = (FlatCurveType)params->hsvequalizer.scurve.at(0);
FlatCurveType vCurveType = (FlatCurveType)params->hsvequalizer.vcurve.at(0);
bool hCurveEnabled = hCurveType > FCT_Linear;
bool sCurveEnabled = sCurveType > FCT_Linear;
bool vCurveEnabled = vCurveType > FCT_Linear;
// TODO: We should create a 'skip' value like for CurveFactory::complexsgnCurve (rtengine/curves.cc)
if (hCurveEnabled) hCurve = new FlatCurve(params->hsvequalizer.hcurve);
if (sCurveEnabled) sCurve = new FlatCurve(params->hsvequalizer.scurve);
if (vCurveEnabled) vCurve = new FlatCurve(params->hsvequalizer.vcurve);
#pragma omp parallel for private(r, g, b,factor,mapval,h,s,v) if (multiThread)
for (int i=0; i<tH; i++) {
for (int j=0; j<tW; j++) {
@@ -363,7 +376,7 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur
g = tonecurve[CLIP(g)];
b = tonecurve[CLIP(b)];
if (abs(sat)>0.5 || params->hsvequalizer.enabled) {
if (abs(sat)>0.5 || hCurveEnabled || sCurveEnabled || vCurveEnabled) {
rgb2hsv(r,g,b,h,s,v);
if (sat > 0.5) {
s = (1-(float)sat/100)*s+(float)sat/100*(1-SQR(SQR(1-s)));
@@ -372,44 +385,51 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur
s *= 1+(float)sat/100;
}
//HSV equalizer
if (params->hsvequalizer.enabled) {
hue = (int)(65535*h);
hueres = hue & 8091;//location of hue within a band
hueband = (hue-hueres) >> 13;//divides hue range into 8 bands
nbrband = (hueband+1)&7;
//shift hue
h = fmod(h + 0.0025*(params->hsvequalizer.hue[hueband] * cossq[hueres] + params->hsvequalizer.hue[nbrband] * (1-cossq[hueres])),1);
if (h<0) h +=1;
hue = (int)(65535*h);
hueres = hue & 8091;//location of hue within a band
hueband = (hue-hueres) >> 13;//divides hue range into 8 bands
nbrband = (hueband+1)&7;
//change saturation
satparam = 0.01*(params->hsvequalizer.sat[hueband] * cossq[hueres] + params->hsvequalizer.sat[nbrband] * (1-cossq[hueres]));
if (hCurveEnabled) {
h = (hCurve->getVal((double)h) - 0.5) * 2 + h;
if (h > 1.0)
h -= 1.0;
else if (h < 0.0)
h += 1.0;
}
if (sCurveEnabled) {
//shift saturation
float satparam = (sCurve->getVal((double)h)-0.5) * 2;
if (satparam > 0.00001) {
s = (1-satparam)*s+satparam*(1-SQR(1-s));
} else {
if (satparam < -0.00001)
s *= 1+satparam;
s *= 1+satparam;
}
//change value
valparam = 0.005*(params->hsvequalizer.val[hueband] * cossq[hueres] + params->hsvequalizer.val[nbrband] * (1-cossq[hueres]));
/*s = sCurve->getVal((double)s);
if (s > 1.0)
s -= 1.0;
else if (s < 0.0)
s += 1.0;*/
}
if (vCurveEnabled) {
//shift value
float valparam = vCurve->getVal((double)h)-0.5;
valparam *= (1-SQR(SQR(1-s)));
if (valparam > 0.00001) {
v = (1-valparam)*v+valparam*(1-SQR(1-v));
} else {
if (valparam < -0.00001)
v *= (1+valparam);
v *= (1+valparam);
}
/*v = vCurve->getVal((double)v);
if (v > 1.0)
v -= 1.0;
else if (v < 0.0)
v += 1.0;*/
}
hsv2rgb(h,s,v,r,g,b);
}
//hsv2rgb(h,s,v,r,g,b);
int x = (toxyz[0][0] * r + toxyz[1][0] * g + toxyz[2][0] * b) >> 15;
int y = (toxyz[0][1] * r + toxyz[1][1] * g + toxyz[2][1] * b) >> 15;
int z = (toxyz[0][2] * r + toxyz[1][2] * g + toxyz[2][2] * b) >> 15;
@@ -425,6 +445,9 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur
}
}
if (hCurveEnabled) delete hCurve;
if (sCurveEnabled) delete sCurve;
if (vCurveEnabled) delete vCurve;
delete [] cossq;
//delete [] my_tonecurve;
}
@@ -677,60 +700,5 @@ void ImProcFunctions::getAutoExp (unsigned int* histogram, int histcompr, doubl
if (br>10) br=10;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void ImProcFunctions::rgb2hsv (int r, int g, int b, float &h, float &s, float &v) {
double var_R = r / 65535.0;
double var_G = g / 65535.0;
double var_B = b / 65535.0;
double var_Min = MIN(MIN(var_R,var_G),var_B);
double var_Max = MAX(MAX(var_R,var_G),var_B);
double del_Max = var_Max - var_Min;
v = var_Max;
if (fabs(del_Max)<0.00001) {
h = 0;
s = 0;
}
else {
s = del_Max/var_Max;
if ( var_R == var_Max ) h = (var_G - var_B)/del_Max;
else if ( var_G == var_Max ) h = 2.0 + (var_B - var_R)/del_Max;
else if ( var_B == var_Max ) h = 4.0 + (var_R - var_G)/del_Max;
h /= 6.0;
if ( h < 0 ) h += 1;
if ( h > 1 ) h -= 1;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void ImProcFunctions::hsv2rgb (float h, float s, float v, int &r, int &g, int &b) {
float h1 = h*6; // sector 0 to 5
int i = floor( h1 );
float f = h1 - i; // fractional part of h
float p = v * ( 1 - s );
float q = v * ( 1 - s * f );
float t = v * ( 1 - s * ( 1 - f ) );
float r1,g1,b1;
if (i==0) {r1 = v; g1 = t; b1 = p;}
if (i==1) {r1 = q; g1 = v; b1 = p;}
if (i==2) {r1 = p; g1 = v; b1 = t;}
if (i==3) {r1 = p; g1 = q; b1 = v;}
if (i==4) {r1 = t; g1 = p; b1 = v;}
if (i==5) {r1 = v; g1 = p; b1 = q;}
r = (int)((r1)*65535);
g = (int)((g1)*65535);
b = (int)((b1)*65535);
}
}