Here you go:```
void ExposureWnd::ContChange(float pos) {
contrast=pos;
// Calculate the bias
const float eps=1e-3f;
float bias=-contrast*0.5f+0.5f;
bias=clamp(bias, eps, 1.0f-eps);
contrastBiasMult=1.0f/bias-2.0f;
// Calculate the slope of the contrast function at t>=1.0
contrastSlope=bias/(1.0f-bias);
exponotify->ExpoChanged();
}
// Schlick’s bias function with a precomputed multiplier. It’s used for the contrast correction and it’s defined in [0.0, 0.5].
template
static T schlickBiasPrecomputedMult(T t, float biasMult) {
return t/(biasMult*(1.0f-2.0f*t)+1.0f);
}
// Nonlinear contrast correction function which preserves the detail in dark and bright areas.
template
static T contrastFunc(T c, float slope, float biasMult) {
T res;
// Use Schlick's gain function in [0.0, 1.0] (which is a bias function in [0.0, 0.5] and a reflected bias in [0.5, 1.0]).
// Outside [0.0, 1.0] use a linear function with a slope equal to the slope of the gain function at 0.0 and 1.0.
if (c<=0.0f) res=c*slope;
else if (c<0.5f) res=schlickBiasPrecomputedMult(c, biasMult);
else if (c<1.0f) res=1.0f-schlickBiasPrecomputedMult(1.0f-c, biasMult);
else res=(c-1.0f)*slope+1.0f;
return res;
}
int ExposureWnd::Correct(VUtils::Color *colors, const VUtils::Color alpha, int count, int x, int y, int notForDisplay) {
float mv=powf(2.0f, exposure);
for (int i=0; i<count; i++) {
Color res = colors[i];
//apply exposure
res=mv;
//apply highlight burn
res=res*(Color(1.0f, 1.0f, 1.0f)+res*sqr(highlight))/(Color(1.0f, 1.0f, 1.0f)+res);
//apply contrast
res.r=contrastFunc(res.r, contrastSlope, contrastBiasMult);
res.g=contrastFunc(res.g, contrastSlope, contrastBiasMult);
res.b=contrastFunc(res.b, contrastSlope, contrastBiasMult);
res.clampMin();
colors[i] = res;
}
return 0;
}
Best regards,
Vlado