Custom output gamma, on behalf of Jacques; see issue #666
This commit is contained in:
parent
a0c548fdf0
commit
22ec6055ce
@ -759,6 +759,8 @@ TP_FLATFIELD_BT_HORIZONTAL;Horizontal
|
||||
TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz.
|
||||
TP_FLATFIELD_BT_VERTICAL;Vertical
|
||||
TP_FLATFIELD_LABEL;Flat Field
|
||||
TP_GAMMA_OUTPUT;Output gamma
|
||||
TP_GAMMA_COMMENT;(output profile disabled except "default")
|
||||
TP_HLREC_CIELAB;CIELab Blending
|
||||
TP_HLREC_COLOR;Color Propagation
|
||||
TP_HLREC_LABEL;Highlight Reconstruction
|
||||
|
@ -145,6 +145,7 @@ InputProfile=(camera)
|
||||
ApplyGammaBeforeInputProfile=false
|
||||
WorkingProfile=sRGB
|
||||
OutputProfile=No ICM: sRGB output
|
||||
Gammafree=default
|
||||
|
||||
[Equalizer]
|
||||
Enabled=false
|
||||
|
@ -145,6 +145,7 @@ InputProfile=(camera)
|
||||
ApplyGammaBeforeInputProfile=false
|
||||
WorkingProfile=sRGB
|
||||
OutputProfile=No ICM: sRGB output
|
||||
Gammafree=default
|
||||
|
||||
[Equalizer]
|
||||
Enabled=false
|
||||
|
@ -145,6 +145,7 @@ InputProfile=(camera)
|
||||
ApplyGammaBeforeInputProfile=false
|
||||
WorkingProfile=sRGB
|
||||
OutputProfile=No ICM: sRGB output
|
||||
Gammafree=default
|
||||
|
||||
[Equalizer]
|
||||
Enabled=false
|
||||
|
@ -199,10 +199,17 @@ namespace rtengine {
|
||||
gamma= %f, skip= %d \n",def_mul,ecomp,black,hlcompr,shcompr,br,contr,defmul,gamma_,skip);*/
|
||||
|
||||
// compute parameters of the gamma curve
|
||||
double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 )));
|
||||
/*double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 )));
|
||||
double slope = 1.099 * pow (start, 1.0/gamma_-1) - 0.099/start;
|
||||
double mul = 1.099;
|
||||
double add = 0.099;
|
||||
// gamma BT709*/
|
||||
|
||||
//normalize gamma to sRGB
|
||||
double start = exp(gamma_*log( -0.055 / ((1.0/gamma_-1.0)*1.055 )));
|
||||
double slope = 1.055 * pow (start, 1.0/gamma_-1) - 0.055/start;
|
||||
double mul = 1.055;
|
||||
double add = 0.055;
|
||||
|
||||
// a: slope of the curve, black: starting point at the x axis
|
||||
double a = pow (2.0, ecomp);
|
||||
|
@ -34,6 +34,23 @@ namespace rtengine {
|
||||
const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best};
|
||||
const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz};
|
||||
const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"};
|
||||
const char* wpgamma[] = {"default","BT709_g2.2_s4.5", "sRGB_g2.4_s12.92", "linear_g1.0", "standard_g2.2", "standard_g1.8", "High_g1.3_s3.35","Low_g2.6_s6.9"}; //gamma free
|
||||
//default = gamma inside profile
|
||||
//BT709 g=2.22 s=4.5 sRGB g=2.4 s=12.92
|
||||
//linear g=1.0
|
||||
//std22 g=2.2 std18 g=1.8
|
||||
// high g=1.3 s=3.35 for high dynamic images
|
||||
//low g=2.6 s=6.9 for low contrast images
|
||||
|
||||
|
||||
std::vector<std::string> getGamma () {//return gamma
|
||||
|
||||
std::vector<std::string> res;
|
||||
for (unsigned int i=0; i<sizeof(wpgamma)/sizeof(wpgamma[0]); i++)
|
||||
res.push_back (wpgamma[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> getWorkingProfiles () {
|
||||
|
||||
@ -320,7 +337,10 @@ cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, G
|
||||
|
||||
if (gamma) {
|
||||
pcurve[2] = 1;
|
||||
pcurve[3] = 0x1f00000;
|
||||
// pcurve[3] = 0x1f00000;// pcurve for gamma BT709 : g=2.22 s=4.5
|
||||
// normalize gamma in RT, default (Emil's choice = sRGB)
|
||||
pcurve[3] = 0x2390000;//pcurve for gamma sRGB : g:2.4 s=12.92
|
||||
|
||||
}
|
||||
|
||||
// constructing profile header
|
||||
|
@ -150,6 +150,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
setScale (scale);
|
||||
imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm, params.raw);
|
||||
ipf.firstAnalysis (orig_prev, ¶ms, vhist16, imgsrc->getGamma());
|
||||
|
||||
}
|
||||
readyphase++;
|
||||
|
||||
|
@ -56,11 +56,11 @@ class ImProcFunctions {
|
||||
bool needsRotation ();
|
||||
bool needsPerspective ();
|
||||
bool needsVignetting ();
|
||||
// static cmsUInt8Number* Mempro = NULL;
|
||||
|
||||
|
||||
public:
|
||||
static LUTf cachef;
|
||||
|
||||
double lumimul[3];
|
||||
|
||||
static void initCache ();
|
||||
@ -113,7 +113,8 @@ class ImProcFunctions {
|
||||
void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh, bool edges);
|
||||
|
||||
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
|
||||
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
|
||||
Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam);// for gamma output
|
||||
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);//without gamma ==>default
|
||||
|
||||
bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1);
|
||||
bool transCoord (int W, int H, std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1);
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include <iccstore.h>
|
||||
#include <iccmatrices.h>
|
||||
#include <mytime.h>
|
||||
#include <icmpanel.h>
|
||||
#include <options.h>
|
||||
#include <settings.h>
|
||||
//#include <sRGBgamutbdy.h>
|
||||
|
||||
#ifdef _OPENMP
|
||||
@ -227,7 +230,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
// for default (not gamma)
|
||||
Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile) {
|
||||
|
||||
//gamutmap(lab);
|
||||
@ -238,8 +241,9 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
|
||||
if (cy+ch>lab->H) ch = lab->H-cy;
|
||||
|
||||
Image16* image = new Image16 (cw, ch);
|
||||
|
||||
cmsHPROFILE oprof = iccStore->getProfile (profile);
|
||||
cmsHPROFILE oprof = iccStore->getProfile (profile);
|
||||
|
||||
|
||||
|
||||
if (oprof) {
|
||||
#pragma omp parallel for if (multiThread)
|
||||
@ -302,6 +306,131 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
// for gamma options (BT709...sRGB linear...)
|
||||
Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam) {
|
||||
|
||||
//gamutmap(lab);
|
||||
|
||||
if (cx<0) cx = 0;
|
||||
if (cy<0) cy = 0;
|
||||
if (cx+cw>lab->W) cw = lab->W-cx;
|
||||
if (cy+ch>lab->H) ch = lab->H-cy;
|
||||
|
||||
Image16* image = new Image16 (cw, ch);
|
||||
cmsBool rc = TRUE;
|
||||
float p1,p2,p3,p4,p5,p6;//primaries
|
||||
float ga0,ga1,ga2,ga3,ga4,ga5=0;//gamma parameters
|
||||
int t50;
|
||||
int select_temp =1;//5003K
|
||||
double eps=0.000000001;// not divide by zero
|
||||
//primaries
|
||||
if(profi=="ProPhoto") {p1=0.7347; p2=0.2653; p3=0.1596; p4=0.8404; p5=0.0366; p6=0.0001;select_temp=1;}//Prophoto primaries
|
||||
else if (profi=="WideGamut") {p1=0.7350; p2=0.2650; p3=0.1150; p4=0.8260; p5=0.1570; p6=0.0180;select_temp=1;}//Widegamut primaries
|
||||
else if (profi=="Adobe RGB") {p1=0.6400; p2=0.3300; p3=0.2100; p4=0.7100; p5=0.1500; p6=0.0600;select_temp=2;}//Adobe primaries
|
||||
else if (profi=="sRGB") {p1=0.6400; p2=0.3300; p3=0.3000; p4=0.6000; p5=0.1500; p6=0.0600;select_temp=2;} // sRGB primaries
|
||||
else if (profi=="BruceRGB") {p1=0.6400; p2=0.3300; p3=0.2800; p4=0.6500; p5=0.1500; p6=0.0600;select_temp=2;} // Bruce primaries
|
||||
else if (profi=="Beta RGB") {p1=0.6888; p2=0.3112; p3=0.1986; p4=0.7551; p5=0.1265; p6=0.0352;select_temp=1;} // Beta primaries
|
||||
else if (profi=="BestRGB") {p1=0.7347; p2=0.2653; p3=0.2150; p4=0.7750; p5=0.1300; p6=0.0350;select_temp=1;} // Best primaries
|
||||
|
||||
// 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;}//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=="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...)
|
||||
else if (gam=="standard_g2.2") {ga0=2.2; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;}//gamma=2.2 (as gamma of Adobe, Widegamut...)
|
||||
else if (gam=="standard_g1.8") {ga0=1.8; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;}//gamma=1.8 (as gamma of Prophoto)
|
||||
|
||||
|
||||
if(select_temp==1) t50=5003;// for Widegamut, Prophoto Best, Beta D50
|
||||
else if (select_temp==2) t50=6504;// for sRGB, AdobeRGB, Bruce D65
|
||||
|
||||
cmsCIExyY xyD;
|
||||
cmsCIExyYTRIPLE Primaries = {{p1, p2, 1.0},//red primaries
|
||||
{p3, p4, 1.0}, // green
|
||||
{p5, p6, 1.0} //blue
|
||||
};
|
||||
cmsToneCurve* GammaTRC[3];
|
||||
cmsFloat64Number Parameters[7];
|
||||
Parameters[0] = ga0;
|
||||
Parameters[1] = ga1;
|
||||
Parameters[2] = ga2;
|
||||
Parameters[3] = ga3;
|
||||
Parameters[4] = ga4;
|
||||
Parameters[5] = ga5;
|
||||
Parameters[6] = 0;
|
||||
// 6 parameters for smoother curves
|
||||
cmsWhitePointFromTemp(&xyD, t50);
|
||||
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters);//5 = more smoother than 4
|
||||
cmsHPROFILE oprofdef = cmsCreateRGBProfileTHR(NULL, &xyD, &Primaries, GammaTRC);
|
||||
|
||||
cmsFreeToneCurve(GammaTRC[0]);
|
||||
|
||||
|
||||
if (oprofdef) {
|
||||
#pragma omp parallel for if (multiThread)
|
||||
for (int i=cy; i<cy+ch; i++) {
|
||||
float g;
|
||||
float* rL = lab->L[i];
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
short* xa = (short*)image->r[i-cy];
|
||||
short* ya = (short*)image->g[i-cy];
|
||||
short* za = (short*)image->b[i-cy];
|
||||
for (int j=cx; j<cx+cw; j++) {
|
||||
|
||||
float fy = (0.00862069 * rL[j])/327.68 + 0.137932; // (L+16)/116
|
||||
float fx = (0.002 * ra[j])/327.68 + fy;
|
||||
float fz = fy - (0.005 * rb[j])/327.68;
|
||||
|
||||
float x_ = 65535.0 * f2xyz(fx)*D50x;
|
||||
float y_ = 65535.0 * f2xyz(fy);
|
||||
float z_ = 65535.0 * f2xyz(fz)*D50z;
|
||||
|
||||
xa[j-cx] = CLIP((int)x_);
|
||||
ya[j-cx] = CLIP((int)y_);
|
||||
za[j-cx] = CLIP((int)z_);
|
||||
}
|
||||
}
|
||||
|
||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
||||
lcmsMutex->lock ();
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16_PLANAR, oprofdef, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE);
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
cmsDoTransform (hTransform, image->data, image->data, image->planestride);
|
||||
cmsDeleteTransform(hTransform);
|
||||
} else {
|
||||
//
|
||||
#pragma omp parallel for if (multiThread)
|
||||
for (int i=cy; i<cy+ch; i++) {
|
||||
float g;
|
||||
float R,G,B;
|
||||
float* rL = lab->L[i];
|
||||
float* ra = lab->a[i];
|
||||
float* rb = lab->b[i];
|
||||
for (int j=cx; j<cx+cw; j++) {
|
||||
|
||||
float fy = (0.00862069 * rL[j])/327.68 + 0.137932; // (L+16)/116
|
||||
float fx = (0.002 * ra[j])/327.68 + fy;
|
||||
float fz = fy - (0.005 * rb[j])/327.68;
|
||||
|
||||
float x_ = 65535.0 * f2xyz(fx)*D50x;
|
||||
float y_ = 65535.0 * f2xyz(fy);
|
||||
float z_ = 65535.0 * f2xyz(fz)*D50z;
|
||||
|
||||
xyz2srgb(x_,y_,z_,R,G,B);
|
||||
|
||||
image->r[i-cy][j-cx] = (int)gamma2curve[(R)];
|
||||
image->g[i-cy][j-cx] = (int)gamma2curve[(G)];
|
||||
image->b[i-cy][j-cx] = (int)gamma2curve[(B)];
|
||||
}
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
//#include "sRGBgamutbdy.cc"
|
||||
|
||||
|
@ -154,7 +154,8 @@ enum ProcEvent {
|
||||
EvAutoDIST=129,
|
||||
EvDPDNLumCurve=130,
|
||||
EvDPDNChromCurve=131,
|
||||
NUMOFEVENTS=132
|
||||
EvGAMMA=132,
|
||||
NUMOFEVENTS=133
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -210,7 +210,8 @@ void ProcParams::setDefaults () {
|
||||
icm.gammaOnInput = false;
|
||||
icm.working = "sRGB";
|
||||
icm.output = "sRGB";
|
||||
|
||||
icm.gamma = "default";
|
||||
|
||||
equalizer.enabled = false;
|
||||
for(int i = 0; i < 8; i ++)
|
||||
{
|
||||
@ -427,6 +428,7 @@ int ProcParams::save (Glib::ustring fname) const {
|
||||
keyFile.set_boolean ("Color Management", "ApplyGammaBeforeInputProfile", icm.gammaOnInput);
|
||||
keyFile.set_string ("Color Management", "WorkingProfile", icm.working);
|
||||
keyFile.set_string ("Color Management", "OutputProfile", icm.output);
|
||||
keyFile.set_string ("Color Management", "Gammafree", icm.gamma);
|
||||
|
||||
// save wavelet equalizer parameters
|
||||
keyFile.set_boolean ("Equalizer", "Enabled", equalizer.enabled);
|
||||
@ -741,6 +743,8 @@ if (keyFile.has_group ("Color Management")) {
|
||||
if (keyFile.has_key ("Color Management", "ApplyGammaBeforeInputProfile")) icm.gammaOnInput = keyFile.get_boolean ("Color Management", "ApplyGammaBeforeInputProfile");
|
||||
if (keyFile.has_key ("Color Management", "WorkingProfile")) icm.working = keyFile.get_string ("Color Management", "WorkingProfile");
|
||||
if (keyFile.has_key ("Color Management", "OutputProfile")) icm.output = keyFile.get_string ("Color Management", "OutputProfile");
|
||||
if (keyFile.has_key ("Color Management", "Gammafree")) icm.gamma = keyFile.get_string ("Color Management", "Gammafree");
|
||||
|
||||
}
|
||||
|
||||
// load wavelet equalizer parameters
|
||||
@ -989,6 +993,7 @@ bool ProcParams::operator== (const ProcParams& other) {
|
||||
&& icm.gammaOnInput == other.icm.gammaOnInput
|
||||
&& icm.working == other.icm.working
|
||||
&& icm.output == other.icm.output
|
||||
&& icm.gamma == other.icm.gamma
|
||||
&& equalizer == other.equalizer
|
||||
&& dirpyrequalizer == other.dirpyrequalizer
|
||||
&& hsvequalizer.hcurve == other.hsvequalizer.hcurve
|
||||
|
@ -331,6 +331,8 @@ class ColorManagementParams {
|
||||
bool gammaOnInput;
|
||||
Glib::ustring working;
|
||||
Glib::ustring output;
|
||||
Glib::ustring gamma;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1530,6 +1530,7 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams
|
||||
|
||||
if (cmp.input == "(none)")
|
||||
return;
|
||||
|
||||
|
||||
MyTime t1, t2, t3;
|
||||
|
||||
|
@ -127,8 +127,9 @@ 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.2; }
|
||||
double getGamma () { return 2.4; }//normalize gamma to sRGB
|
||||
|
||||
void getFullSize (int& w, int& h, int tr = TR_NONE);
|
||||
void getSize (int tran, PreviewProps pp, int& w, int& h);
|
||||
|
||||
|
@ -152,6 +152,7 @@ FLATFIELD, // EvFlatFieldBlurType,
|
||||
TRANSFORM, // EvAutoDIST,
|
||||
DIRPYRDENOISE, // EvDPDNLumCurve,
|
||||
DIRPYRDENOISE, // EvDPDNChromCurve,
|
||||
ALL, // EvGAMMA
|
||||
|
||||
};
|
||||
|
||||
|
@ -319,6 +319,8 @@ namespace rtengine {
|
||||
/** Returns the available working profile names
|
||||
* @return a vector of the available working profile names */
|
||||
std::vector<std::string> getWorkingProfiles ();
|
||||
/** return gamma */
|
||||
std::vector<std::string> getGamma ();
|
||||
|
||||
/** This class holds all the necessary informations to accomplish the full processing of the image */
|
||||
class ProcessingJob {
|
||||
|
@ -34,7 +34,14 @@ namespace rtengine {
|
||||
Glib::ustring darkFramesPath; ///< The default directory for dark frames
|
||||
Glib::ustring flatFieldsPath; ///< The default directory for flat fields
|
||||
bool LCMSSafeMode; // If true, not OMP
|
||||
|
||||
Glib::ustring adobe;
|
||||
Glib::ustring prophoto;
|
||||
Glib::ustring widegamut;
|
||||
Glib::ustring beta;
|
||||
Glib::ustring best;
|
||||
Glib::ustring bruce;
|
||||
Glib::ustring srgb;
|
||||
|
||||
/** Creates a new instance of Settings.
|
||||
* @return a pointer to the new Settings instance. */
|
||||
static Settings* create ();
|
||||
|
@ -24,16 +24,15 @@
|
||||
#include <iccstore.h>
|
||||
#include <processingjob.h>
|
||||
#include <glibmm.h>
|
||||
|
||||
#include <options.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <rawimagesource.h>
|
||||
#undef THREAD_PRIORITY_NORMAL
|
||||
|
||||
#define CLIP(a) ((a)>0?((a)<65535?(a):65535):0)
|
||||
|
||||
|
||||
namespace rtengine {
|
||||
|
||||
IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData) {
|
||||
|
||||
errorCode = 0;
|
||||
@ -209,7 +208,130 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
cw = params.crop.w;
|
||||
ch = params.crop.h;
|
||||
}
|
||||
Image16* readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output);
|
||||
|
||||
if(params.icm.gamma != "default")
|
||||
{ // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8
|
||||
Image16* readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.working, params.icm.gamma);
|
||||
delete labView;
|
||||
if (pl) pl->setProgress (0.70);
|
||||
|
||||
// get the resize parameters
|
||||
int refw, refh;
|
||||
double tmpScale;
|
||||
|
||||
if (params.resize.enabled) {
|
||||
|
||||
if (params.crop.enabled && params.resize.appliesTo == "Cropped area") {
|
||||
// the resize values applies to the crop dimensions
|
||||
refw = cw;
|
||||
refh = ch;
|
||||
}
|
||||
else {
|
||||
// the resize values applies to the image dimensions
|
||||
// if a crop exists, it will be resized to the calculated scale
|
||||
refw = fw;
|
||||
refh = fh;
|
||||
}
|
||||
|
||||
switch(params.resize.dataspec) {
|
||||
case (1):
|
||||
// Width
|
||||
tmpScale = (double)params.resize.width/(double)refw;
|
||||
break;
|
||||
case (2):
|
||||
// Height
|
||||
tmpScale = (double)params.resize.height/(double)refh;
|
||||
break;
|
||||
case (3):
|
||||
// FitBox
|
||||
if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height) {
|
||||
tmpScale = (double)params.resize.width/(double)refw;
|
||||
}
|
||||
else {
|
||||
tmpScale = (double)params.resize.height/(double)refh;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Scale
|
||||
tmpScale = params.resize.scale;
|
||||
break;
|
||||
}
|
||||
|
||||
// resize image
|
||||
if (fabs(tmpScale-1.0)>1e-5)
|
||||
{
|
||||
int imw, imh;
|
||||
if (params.crop.enabled && params.resize.appliesTo == "Full image") {
|
||||
imw = cw;
|
||||
imh = ch;
|
||||
}
|
||||
else {
|
||||
imw = refw;
|
||||
imh = refh;
|
||||
}
|
||||
imw = (int)( (double)imw * tmpScale + 0.5 );
|
||||
imh = (int)( (double)imh * tmpScale + 0.5 );
|
||||
Image16* tempImage = new Image16 (imw, imh);
|
||||
ipf.resize (readyImg, tempImage, tmpScale);
|
||||
delete readyImg;
|
||||
readyImg = tempImage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tunnelMetaData)
|
||||
readyImg->setMetadata (ii->getMetaData()->getExifData ());
|
||||
else
|
||||
readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc);
|
||||
|
||||
|
||||
ProfileContent pc;
|
||||
Glib::ustring chpro;
|
||||
int present_space[7]={0,0,0,0,0,0,0};
|
||||
std::vector<std::string> opnames = rtengine::getOutputProfiles ();
|
||||
//test if files are in system
|
||||
for (int j=0; j<7;j++) {
|
||||
//one can modify "option" [Color Management] to adapt name of profile ih there are different for windows, MacOS, Linux ??
|
||||
if(j==0) chpro=options.rtSettings.prophoto;
|
||||
else if(j==1) chpro=options.rtSettings.adobe;
|
||||
else if(j==2) chpro=options.rtSettings.widegamut;
|
||||
else if(j==3) chpro=options.rtSettings.beta;
|
||||
else if(j==4) chpro=options.rtSettings.best;
|
||||
else if(j==5) chpro=options.rtSettings.bruce;
|
||||
else if(j==6) chpro=options.rtSettings.srgb;
|
||||
for (int i=0; i<opnames.size(); i++)
|
||||
if(chpro.compare(opnames[i]) ==0) present_space[j]=1;
|
||||
if (present_space[j]==0) { if (pl) pl->setProgressStr ("Missing file..");pl->setProgress (0.0);}// display file not present: not very good display information...!!
|
||||
}
|
||||
//choose output profile
|
||||
if(params.icm.working=="ProPhoto" && present_space[0]==1) params.icm.output=options.rtSettings.prophoto;
|
||||
else if(params.icm.working=="Adobe RGB" && present_space[1]==1) params.icm.output=options.rtSettings.adobe;
|
||||
else if(params.icm.working=="WideGamut" && present_space[2]==1) params.icm.output=options.rtSettings.widegamut;
|
||||
else if(params.icm.working=="Beta RGB" && present_space[3]==1) params.icm.output=options.rtSettings.beta;
|
||||
else if(params.icm.working=="BestRGB" && present_space[4]==1) params.icm.output=options.rtSettings.best;
|
||||
else if(params.icm.working=="BruceRGB" && present_space[5]==1) params.icm.output=options.rtSettings.bruce;
|
||||
else params.icm.output=options.rtSettings.srgb; //if not found or choice=srgb
|
||||
|
||||
|
||||
if (params.icm.output.compare (0, 6, "No ICM") && params.icm.output!="")
|
||||
pc = iccStore->getContent (params.icm.output);
|
||||
|
||||
readyImg->setOutputProfile (pc.data, pc.length);
|
||||
|
||||
delete baseImg;
|
||||
|
||||
if (!job->initialImage)
|
||||
ii->decreaseRef ();
|
||||
|
||||
delete job;
|
||||
if (pl)
|
||||
pl->setProgress (0.75);
|
||||
|
||||
return readyImg;
|
||||
}
|
||||
else
|
||||
{//if default mode : profil = selection by choice in list (Prophoto.icm, sRGB.icm, etc., etc.) , gamma = gamma of profile
|
||||
Image16* readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output);
|
||||
delete labView;
|
||||
if (pl) pl->setProgress (0.70);
|
||||
|
||||
@ -300,6 +422,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
|
||||
return readyImg;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) {
|
||||
|
@ -92,6 +92,22 @@ ICMPanel::ICMPanel () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL),
|
||||
std::vector<std::string> wpnames = rtengine::getWorkingProfiles ();
|
||||
for (int i=0; i<wpnames.size(); i++)
|
||||
wnames->append_text (wpnames[i]);
|
||||
|
||||
Gtk::HSeparator* hsep22 = Gtk::manage (new Gtk::HSeparator ());
|
||||
pack_start (*hsep22, Gtk::PACK_SHRINK, 2);
|
||||
|
||||
Gtk::Label* galab = Gtk::manage (new Gtk::Label ());
|
||||
galab->set_alignment (0.0, 0.5);
|
||||
//galab->set_markup (Glib::ustring("<b>") + M("TP_GAMMA_OUTPUT") + "</b>" +M("TP_GAMMA_COMMENT"));
|
||||
galab->set_markup (Glib::ustring("<b>") + M("TP_GAMMA_OUTPUT") + "</b>");
|
||||
|
||||
pack_start (*galab, Gtk::PACK_SHRINK, 4);
|
||||
wgamma = Gtk::manage (new Gtk::ComboBoxText ());
|
||||
pack_start (*wgamma, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
std::vector<std::string> wpgamma = rtengine::getGamma ();
|
||||
for (int i=0; i<wpgamma.size(); i++)
|
||||
wgamma->append_text (wpgamma[i]);
|
||||
|
||||
onames->append_text (M("TP_ICM_NOICM"));
|
||||
onames->set_active (0);
|
||||
@ -102,6 +118,7 @@ ICMPanel::ICMPanel () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL),
|
||||
|
||||
wnames->set_active (0);
|
||||
onames->set_active (0);
|
||||
wgamma->set_active (0);
|
||||
|
||||
Gtk::FileFilter filter_icc;
|
||||
filter_icc.set_name(M("TP_ICM_FILEDLGFILTERICM"));
|
||||
@ -124,6 +141,8 @@ ICMPanel::ICMPanel () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL),
|
||||
|
||||
wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) );
|
||||
onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) );
|
||||
wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) );
|
||||
|
||||
icamera->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) );
|
||||
iembedded->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) );
|
||||
ifromfile->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) );
|
||||
@ -157,7 +176,9 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) {
|
||||
igamma->set_sensitive (true);
|
||||
}
|
||||
|
||||
wnames->set_active_text (pp->icm.working);
|
||||
wnames->set_active_text (pp->icm.working);
|
||||
wgamma->set_active_text (pp->icm.gamma);
|
||||
|
||||
if (pp->icm.output=="No ICM: sRGB output")
|
||||
onames->set_active_text (M("TP_ICM_NOICM"));
|
||||
else
|
||||
@ -167,7 +188,8 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) {
|
||||
onames->set_active_text (M("TP_ICM_NOICM"));
|
||||
|
||||
igamma->set_active (pp->icm.gammaOnInput);
|
||||
|
||||
onames->set_sensitive(wgamma->get_active_row_number()==0); //"default"
|
||||
//thanks to Michael
|
||||
if (pedited) {
|
||||
iunchanged->set_active (!pedited->icm.input);
|
||||
igamma->set_sensitive (false);
|
||||
@ -175,6 +197,9 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) {
|
||||
wnames->set_active_text(M("GENERAL_UNCHANGED"));
|
||||
if (!pedited->icm.output)
|
||||
onames->set_active_text(M("GENERAL_UNCHANGED"));
|
||||
if (!pedited->icm.gamma)
|
||||
wgamma->set_active_text(M("GENERAL_UNCHANGED"));
|
||||
|
||||
}
|
||||
|
||||
ipc.block (false);
|
||||
@ -194,18 +219,21 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) {
|
||||
pp->icm.input = "file:"+ipDialog->get_filename ();
|
||||
|
||||
pp->icm.working = wnames->get_active_text ();
|
||||
|
||||
pp->icm.gamma = wgamma->get_active_text ();
|
||||
|
||||
if (onames->get_active_text()==M("TP_ICM_NOICM"))
|
||||
pp->icm.output = "No ICM: sRGB output";
|
||||
else
|
||||
pp->icm.output = onames->get_active_text();
|
||||
pp->icm.gammaOnInput = igamma->get_active ();
|
||||
|
||||
|
||||
if (pedited) {
|
||||
pedited->icm.input = !iunchanged->get_active ();
|
||||
pedited->icm.working = wnames->get_active_text()!=M("GENERAL_UNCHANGED");
|
||||
pedited->icm.output = onames->get_active_text()!=M("GENERAL_UNCHANGED");
|
||||
pedited->icm.gammaOnInput = !ifromfile->get_active ();
|
||||
pedited->icm.gamma = wgamma->get_active_text()!=M("GENERAL_UNCHANGED");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,6 +242,14 @@ void ICMPanel::wpChanged () {
|
||||
if (listener)
|
||||
listener->panelChanged (EvWProfile, wnames->get_active_text ());
|
||||
}
|
||||
void ICMPanel::gpChanged () {
|
||||
|
||||
if (listener)
|
||||
{listener->panelChanged (EvGAMMA, wgamma->get_active_text ());
|
||||
onames->set_sensitive(wgamma->get_active_row_number()==0); //"default"//thanks to Michael
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ICMPanel::ipChanged () {
|
||||
|
||||
@ -297,5 +333,7 @@ void ICMPanel::setBatchMode (bool batchMode) {
|
||||
removeIfThere (this, saveRef);
|
||||
onames->append_text (M("GENERAL_UNCHANGED"));
|
||||
wnames->append_text (M("GENERAL_UNCHANGED"));
|
||||
wgamma->append_text (M("GENERAL_UNCHANGED"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@ class ICMPanel : public Gtk::VBox, public FoldableToolPanel {
|
||||
Gtk::RadioButton* ifromfile;
|
||||
Gtk::CheckButton* igamma;
|
||||
Gtk::ComboBoxText* wnames;
|
||||
Gtk::ComboBoxText* wgamma;
|
||||
|
||||
Gtk::ComboBoxText* onames;
|
||||
Gtk::RadioButton* ofromdir;
|
||||
Gtk::RadioButton* ofromfile;
|
||||
@ -58,6 +60,7 @@ class ICMPanel : public Gtk::VBox, public FoldableToolPanel {
|
||||
void wpChanged ();
|
||||
void opChanged ();
|
||||
void ipChanged ();
|
||||
void gpChanged ();
|
||||
|
||||
void ipSelectionChanged ();
|
||||
|
||||
|
@ -152,6 +152,13 @@ void Options::setDefaults () {
|
||||
rtSettings.monitorProfile = "";
|
||||
rtSettings.autoMonitorProfile = false;
|
||||
rtSettings.LCMSSafeMode = true;
|
||||
rtSettings.adobe = "AdobeRGB1998";
|
||||
rtSettings.prophoto = "ProPhoto";
|
||||
rtSettings.widegamut = "WideGamutRGB";
|
||||
rtSettings.srgb = "sRGB Color Space Profile";
|
||||
rtSettings.bruce = "Bruce";
|
||||
rtSettings.beta = "BetaRGB";
|
||||
rtSettings.best = "BestRGB";
|
||||
|
||||
rtSettings.verbose = false;
|
||||
}
|
||||
@ -458,6 +465,13 @@ int Options::saveToFile (Glib::ustring fname) {
|
||||
keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile);
|
||||
keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent);
|
||||
keyFile.set_boolean ("Color Management", "LCMSSafeMode", rtSettings.LCMSSafeMode);
|
||||
keyFile.set_string ("Color Management", "Adobe_RGB", rtSettings.adobe);
|
||||
keyFile.set_string ("Color Management", "Pro_Photo", rtSettings.prophoto);
|
||||
keyFile.set_string ("Color Management", "Wide_Gamut", rtSettings.widegamut);
|
||||
keyFile.set_string ("Color Management", "S_rgb", rtSettings.srgb);
|
||||
keyFile.set_string ("Color Management", "B_eta", rtSettings.beta);
|
||||
keyFile.set_string ("Color Management", "B_est", rtSettings.best);
|
||||
keyFile.set_string ("Color Management", "B_ruce", rtSettings.bruce);
|
||||
|
||||
Glib::ArrayHandle<int> bab = baBehav;
|
||||
keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab);
|
||||
|
@ -250,6 +250,7 @@ class ColorManagementParamsEdited {
|
||||
bool gammaOnInput;
|
||||
bool working;
|
||||
bool output;
|
||||
bool gamma;
|
||||
};
|
||||
|
||||
class EqualizerParamsEdited {
|
||||
|
Loading…
x
Reference in New Issue
Block a user