Unification if sRGB gamma value
see issue 856
This commit is contained in:
@@ -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, \
|
||||
|
@@ -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){
|
||||
|
@@ -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...)
|
||||
|
@@ -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);
|
||||
|
@@ -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, ¶ms, 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, ¶ms, 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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user