Unification if sRGB gamma value

see issue 856
This commit is contained in:
Oliver Duis
2011-07-27 19:16:26 +02:00
parent 244caeff9a
commit 5aeb290622
6 changed files with 30 additions and 17 deletions

View File

@@ -62,6 +62,12 @@ namespace rtengine {
poly_y.push_back(y3);
}
// Wikipedia sRGB: Unlike most other RGB color spaces, the sRGB gamma cannot be expressed as a single numerical value.
// The overall gamma is approximately 2.2, consisting of a linear (gamma 1.0) section near black, and a non-linear section elsewhere involving a 2.4 exponent
// and a gamma (slope of log output versus log input) changing from 1.0 through about 2.3.
const double CurveFactory::sRGBGamma = 2.2;
const double CurveFactory::sRGBGammaCurve = 2.4;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void CurveFactory::complexsgnCurve (double saturation, bool satlimit, double satlimthresh, \

View File

@@ -126,6 +126,9 @@ class CurveFactory {
public:
const static double sRGBGamma; // standard average gamma
const static double sRGBGammaCurve; // 2.4 in the curve
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// accurately determine value from integer array with float as index
@@ -154,10 +157,10 @@ class CurveFactory {
// standard srgb gamma and its inverse
static inline double gamma2 (double x) {
return x <= 0.00304 ? x*12.92 : 1.055*exp(log(x)/2.4)-0.055;
return x <= 0.00304 ? x*12.92 : 1.055*exp(log(x)/sRGBGammaCurve)-0.055;
}
static inline double igamma2 (double x) {
return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*2.4);
return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*sRGBGammaCurve);
}
// gamma function with adjustable parameters
static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){

View File

@@ -25,7 +25,8 @@
#include <icmpanel.h>
#include <options.h>
#include <settings.h>
//#include <sRGBgamutbdy.h>
#include <curves.h>
#ifdef _OPENMP
#include <omp.h>
@@ -344,7 +345,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int
if (!freegamma) {//if Free gamma not selected
// gamma : ga0,ga1,ga2,ga3,ga4,ga5 by calcul
if(gam=="BT709_g2.2_s4.5") {ga0=2.222;ga1=1./1.099258;ga2=0.099258/1.099258;ga3=1./4.5; ga4=0.01805;ga5=0.0;}//BT709 2.2 4.5 - my prefered as D.Coffin ga4=0.01805
else if (gam=="sRGB_g2.4_s12.92") {ga0=2.3999 ; ga1=1./1.0550; ga2=0.0550/1.0550;ga3=1./12.92;ga4=0.039289;}//sRGB 2.4 12.92 - RT default as Lightroom
else if (gam=="sRGB_g2.4_s12.92") {ga0=CurveFactory::sRGBGammaCurve-0.0001; ga1=1./1.0550; ga2=0.0550/1.0550;ga3=1./12.92;ga4=0.039289;}//sRGB 2.4 12.92 - RT default as Lightroom
else if (gam=="High_g1.3_s3.35") {ga0=1.3 ; ga1=1./1.001724; ga2=0.001724/1.001724;ga3=1./3.35;ga4=0.001715;}//for high dynamic images
else if (gam== "Low_g2.6_s6.9") {ga0=2.6 ; ga1=1./1.12213; ga2=0.12213/1.12213;ga3=1./6.90;ga4=0.01;} //gamma 2.6 variable : for low contrast images
else if (gam=="linear_g1.0") {ga0=1.0; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;}//gamma=1 linear : for high dynamic images (cf : D.Coffin...)

View File

@@ -22,6 +22,7 @@
#include <imagesource.h>
#include <lcms2.h>
#include <array2D.h>
#include <curves.h>
#define HR_SCALE 2
@@ -142,8 +143,8 @@ class RawImageSource : public ImageSource {
ColorTemp getSpotWB (std::vector<Coord2D> red, std::vector<Coord2D> green, std::vector<Coord2D>& blue, int tran);
double getDefGain () { return defGain; }
// double getGamma () { return 2.2; }
double getGamma () { return 2.4; }//normalize gamma to sRGB
double getGamma () { return CurveFactory::sRGBGamma; }
void getFullSize (int& w, int& h, int tr = TR_NONE);
void getSize (int tran, PreviewProps pp, int& w, int& h);

View File

@@ -499,9 +499,9 @@ void Thumbnail::initGamma () {
igammatab = new unsigned short[256];
gammatab = new unsigned char[65536];
for (int i=0; i<256; i++)
igammatab[i] = (unsigned short)(255.0*pow((double)i/255.0,1.0/0.45));
igammatab[i] = (unsigned short)(255.0*pow((double)i/255.0,CurveFactory::sRGBGamma));
for (int i=0; i<65536; i++)
gammatab[i] = (unsigned char)(255.0*pow((double)i/65535.0,0.45));
gammatab[i] = (unsigned char)(255.0*pow((double)i/65535.0,1.f/CurveFactory::sRGBGamma));
}
void Thumbnail::cleanupGamma () {
@@ -689,7 +689,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ipf.setScale (sqrt(double(fw*fw+fh*fh))/sqrt(double(thumbImg->width*thumbImg->width+thumbImg->height*thumbImg->height))*scale);
LUTu hist16 (65536);
ipf.firstAnalysis (baseImg, &params, hist16, isRaw ? 2.2 : 0.0);
double gamma = isRaw ? CurveFactory::sRGBGamma : 0; // usually in ImageSource, but we don't have that here
ipf.firstAnalysis (baseImg, &params, hist16, gamma);
// perform transform
if (ipf.needsTransform()) {
@@ -722,7 +723,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LUTf satcurve (65536);
LUTu dummy;
CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, isRaw ? 2.2 : 0, true, params.toneCurve.curve,
CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, gamma, true, params.toneCurve.curve,
hist16, dummy, curve1, curve2, curve, dummy, 16);
LabImage* labView = new LabImage (fw,fh);
@@ -847,7 +848,7 @@ void Thumbnail::getSpotWB (const procparams::ProcParams& params, int xp, int yp,
// calculate spot wb (copy & pasted from stdimagesource)
unsigned short igammatab[256];
for (int i=0; i<256; i++)
igammatab[i] = (unsigned short)(255.0*pow(i/255.0,1.0/0.45));
igammatab[i] = (unsigned short)(255.0*pow(i/255.0,CurveFactory::sRGBGamma));
int x; int y;
double reds = 0, greens = 0, blues = 0;
int rn = 0, gn = 0, bn = 0;

View File

@@ -20,6 +20,7 @@
#include <toolpanel.h>
#include <iccmatrices.h> // from rtengine
#include <iccstore.h>
#include <curves.h>
#define D50x 0.96422
#define D50z 0.82521
@@ -164,9 +165,9 @@ void Navigator::rgb2lab (Glib::ustring profile, int r, int g, int b, int &LAB_l,
double ep=216.0/24389.0;
double ka=24389.0/27.0;
volatile double var_R = r / 255.0;
volatile double var_G = g / 255.0;
volatile double var_B = b / 255.0;
double var_R = r / 255.0;
double var_G = g / 255.0;
double var_B = b / 255.0;
if (profile=="sRGB") {//apply sRGB inverse gamma
@@ -175,15 +176,15 @@ void Navigator::rgb2lab (Glib::ustring profile, int r, int g, int b, int &LAB_l,
// today as the gamma output can not be configured
// it is better that the user has the gamma of the output space
if ( var_R > 0.04045 )
var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), 2.4);
var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::CurveFactory::sRGBGammaCurve);
else
var_R = var_R / 12.92;
if ( var_G > 0.04045 )
var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), 2.4);
var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::CurveFactory::sRGBGammaCurve);
else
var_G = var_G / 12.92;
if ( var_B > 0.04045 )
var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), 2.4);
var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::CurveFactory::sRGBGammaCurve);
else
var_B = var_B / 12.92;
}