Merge branch 'master' into clang-tidy

This commit is contained in:
Flössie 2016-10-18 17:48:50 +02:00
commit 0bbc84b2af
85 changed files with 6870 additions and 2817 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

View File

@ -632,6 +632,7 @@ HISTORY_MSG_403;O - NB - Sensibilité des bords
HISTORY_MSG_404;O - NB - Base amplification
HISTORY_MSG_405;O - Débruitage - Niveau 4
HISTORY_MSG_406;O - NB - Pixels voisins
HISTORY_MSG_443;Compensation du Point Noir de Sortie
HISTORY_NEWSNAPSHOT;Ajouter
HISTORY_NEWSNAPSHOT_TOOLTIP;Raccourci: <b>Alt-s</b>
HISTORY_SNAPSHOT;Capture
@ -953,6 +954,7 @@ PREFERENCES_MENUGROUPPROFILEOPERATIONS;Opérations sur les profils
PREFERENCES_MENUGROUPRANK;Classement
PREFERENCES_MENUOPTIONS;Options du menu
PREFERENCES_METADATA;Metadonnées
PREFERENCES_MONBPC;Compensation du Point Noir pour la transformation L*a*b*->Moniteur
PREFERENCES_MIN;Mini (100x115)
PREFERENCES_MULTITAB;Éditeurs multiple
PREFERENCES_MULTITABDUALMON;Éditeurs multiple, si possible sur un second moniteur
@ -1083,6 +1085,8 @@ SAVEDLG_SUBSAMP_3;Meilleure qualité
SAVEDLG_TIFFUNCOMPRESSED;TIFF non compressé
SAVEDLG_WARNFILENAME;Le fichier sera nommé
SHCSELECTOR_TOOLTIP;Cliquez le bouton droit de la souris\npour réinitialiser la position de ces 3 curseurs
SOFTPROOF_GAMUTCHECK_TOOLTIP;Si activé, indique en gris les pixels dont la couleurs est en dehors du gamut du profile de sortie
SOFTPROOF_TOOLTIP;Épreuvage écran\nSi activé, simule le rendu généré par le profiles de sortie de l'outil ICM. Particulièrement utile pour simuler le rendu en sortie d'imprimante.
THRESHOLDSELECTOR_B;Bas
THRESHOLDSELECTOR_BL;Bas-gauche
THRESHOLDSELECTOR_BR;Bas-droite
@ -1456,6 +1460,8 @@ TP_ICM_APPLYLOOKTABLE;Table de recherche
TP_ICM_APPLYLOOKTABLE_TOOLTIP;Utilise la table de recherche (LUT) contenu dans le profil DCP. Ce réglage n'est possible que si le profil DCP sélectionné en contient une.
TP_ICM_BLENDCMSMATRIX;Mélange des hautes lumières\ndu profil ICC avec la matrice
TP_ICM_BLENDCMSMATRIX_TOOLTIP;Activer la récupération des zones brûlées lorsque les profils ICC basés sur la LUT sont utilisés
TP_ICM_BPC;Compensation du Point Noir
TP_ICM_BPC_TOOLTIP;Activez ceci pour faire correspondre le canal Luminosité à l'espace couleur de sortie avec un Point Blanc fixe
TP_ICM_DCPILLUMINANT;Illuminant
TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolé
TP_ICM_DCPILLUMINANT_TOOLTIP;Sélectionne quel illuminant DCP inclus utiliser. La valeur par défaut est "Interpolé", qui est un mix entre les 2 profils inclus basé sur la Balance des Blancs choisie. Ce paramètre n'est actif que si un fichier DCP Bi-Illuminant avec support de l'interpolation est choisi.

View File

@ -674,6 +674,7 @@ HISTORY_MSG_439;Retinex - Process
HISTORY_MSG_440;CbDL - Method
HISTORY_MSG_441;Retinex - Gain transmission
HISTORY_MSG_442;Retinex - Scale
HISTORY_MSG_443;Output Black Point Compensation
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
HISTORY_SNAPSHOT;Snapshot
@ -1000,6 +1001,7 @@ PREFERENCES_MENUGROUPRANK;Group "Rank"
PREFERENCES_MENUOPTIONS;Context Menu Options
PREFERENCES_METADATA;Metadata
PREFERENCES_MIN;Mini (100x115)
PREFERENCES_MONBPC;Black Point Compensation for the L*a*b*->Monitor transform
PREFERENCES_MONINTENT;Default monitor intent
PREFERENCES_MONPROFILE;Default monitor profile
PREFERENCES_MULTITAB;Multiple Editor Tabs Mode
@ -1136,6 +1138,8 @@ SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved h
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
SAVEDLG_WARNFILENAME;File will be named
SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders.
SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile.
SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs.
THRESHOLDSELECTOR_B;Bottom
THRESHOLDSELECTOR_BL;Bottom-left
THRESHOLDSELECTOR_BR;Bottom-right
@ -1523,6 +1527,8 @@ TP_ICM_APPLYLOOKTABLE;Look table
TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only enabled if the selected DCP has one.
TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix
TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles.
TP_ICM_BPC;Black Point Compensation
TP_ICM_BPC_TOOLTIP;Enable this to fit the Luminosity channel to the output color space with a fix White Point
TP_ICM_DCPILLUMINANT;Illuminant
TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated
TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected.

View File

@ -156,11 +156,9 @@ void RawImageSource::CA_correct_RT(const double cared, const double cablue, cons
const int vblsz = ceil((float)(height + border2) / (ts - border2) + 2 + vz1);
const int hblsz = ceil((float)(width + border2) / (ts - border2) + 2 + hz1);
char *buffer1 = (char *) calloc(vblsz * hblsz * (2 * 2 + 1), sizeof(float));
//block CA shift values and weight assigned to block
float *blockwt = (float*)buffer1;
float (*blockshifts)[2][2] = (float (*)[2][2])(buffer1 + (vblsz * hblsz * sizeof(float)));
float* const blockwt = static_cast<float*>(calloc(vblsz * hblsz * (2 * 2 + 1), sizeof(float)));
float (*blockshifts)[2][2] = (float (*)[2][2])(blockwt + vblsz * hblsz);
double fitparams[2][2][16];
@ -1013,7 +1011,7 @@ void RawImageSource::CA_correct_RT(const double cared, const double cablue, cons
}
free(Gtmp);
free(buffer1);
free(blockwt);
free(RawDataTmp);
if(plistener) {

View File

@ -17,20 +17,20 @@ calculates A x where x is some vector. Stops when rms residual < RMSResidual or
Stops at n iterates if MaximumIterates = 0 since that many iterates gives exact solution. Applicable to symmetric positive
definite problems only, which is what unconstrained smooth optimization pretty much always is.
Parameter pass can be passed through, containing whatever info you like it to contain (matrix info?).
Takes less memory with OkToModify_b = true, and Preconditioner = NULL. */
Takes less memory with OkToModify_b = true, and Preconditioner = nullptr. */
float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), float *b, int n, bool OkToModify_b,
float *x, float RMSResidual, void *Pass, int MaximumIterates, void Preconditioner(float *Product, float *x, void *Pass))
{
int iterate, i;
char* buffer = (char*)malloc(2 * n * sizeof(float) + 128);
float *r = (float*)(buffer + 64);
float* buffer = (float*)malloc(2 * n * sizeof(float) + 128);
float *r = (buffer + 16);
//Start r and x.
if(x == nullptr) {
x = new float[n];
memset(x, 0, sizeof(float)*n); //Zero initial guess if x == NULL.
memset(x, 0, sizeof(float)*n); //Zero initial guess if x == nullptr.
memcpy(r, b, sizeof(float)*n);
} else {
Ax(r, x, Pass);
@ -61,7 +61,7 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl
}
//Search direction d.
float *d = (float*)(buffer + n * sizeof(float) + 128);
float *d = (buffer + n + 32);
memcpy(d, s, sizeof(float)*n);
@ -127,15 +127,13 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl
#endif
{
float c = 0.0f;
float t;
float temp;
#ifdef _OPENMP
#pragma omp for reduction(+:rs) // Summation with error correction
#endif
for(int ii = 0; ii < n; ii++) {
temp = r[ii] * s[ii];
t = rs + temp;
float temp = r[ii] * s[ii];
float t = rs + temp;
if( fabsf(rs) >= fabsf(temp) ) {
c += ((rs - t) + temp);
@ -183,7 +181,7 @@ float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), fl
return x;
}
MultiDiagonalSymmetricMatrix::MultiDiagonalSymmetricMatrix(int Dimension, int NumberOfDiagonalsInLowerTriangle)
MultiDiagonalSymmetricMatrix::MultiDiagonalSymmetricMatrix(int Dimension, int NumberOfDiagonalsInLowerTriangle) : buffer(nullptr), DiagBuffer(nullptr)
{
n = Dimension;
m = NumberOfDiagonalsInLowerTriangle;
@ -223,7 +221,7 @@ bool MultiDiagonalSymmetricMatrix::CreateDiagonal(int index, int StartRow)
{
DiagBuffer = nullptr;
} else {
DiagBuffer = (char*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64);
DiagBuffer = (float*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64);
}
}
@ -239,7 +237,7 @@ bool MultiDiagonalSymmetricMatrix::CreateDiagonal(int index, int StartRow)
}
if(DiagBuffer != nullptr) {
Diagonals[index] = (float*)(DiagBuffer + (index * (n + padding) * sizeof(float)) + ((index + 16) * 64));
Diagonals[index] = (DiagBuffer + (index * (n + padding)) + ((index + 16) * 16));
} else {
Diagonals[index] = new float[DiagonalLength(StartRow)];
@ -305,9 +303,9 @@ SSEFUNCTION void MultiDiagonalSymmetricMatrix::VectorProduct(float* RESTRICT Pro
const int chunkSize = (lm - srm) / (omp_get_num_procs() * 32);
#else
const int chunkSize = (lm - srm) / (omp_get_num_procs() * 8);
#endif
#endif
#pragma omp parallel
#endif
{
// First fill the big part in the middle
// This can be done without intermediate stores to memory and it can be parallelized too
@ -443,8 +441,8 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max
}
//It's all initialized? Uhkay. Do the actual math then.
int sss, ss, s;
int k, MaxStartRow = StartRows[m - 1]; //Handy number.
int sss, ss;
int MaxStartRow = StartRows[m - 1]; //Handy number.
float **l = ic->Diagonals;
float *d = ic->Diagonals[0]; //Describes D in LDLt.
int icm = ic->m;
@ -506,8 +504,8 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max
//This is a loop over k from 1 to j, inclusive. We'll cover that by looping over the index of the diagonals (s), and get k from it.
//The first diagonal is d (k = 0), so skip that and have s start at 1. Cover all available s but stop if k exceeds j.
s = 1;
k = icStartRows[s];
int s = 1;
int k = icStartRows[s];
while(k <= j) {
d[j] -= l[s][j - k] * l[s][j - k] * d[j - k];
@ -554,7 +552,7 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max
return true;
}
void MultiDiagonalSymmetricMatrix::KillIncompleteCholeskyFactorization()
void MultiDiagonalSymmetricMatrix::KillIncompleteCholeskyFactorization(void)
{
delete IncompleteCholeskyFactorization;
}
@ -713,9 +711,7 @@ SSEFUNCTION float *EdgePreservingDecomposition::CreateBlur(float *Source, float
a = Blur, g = Source;
}
int i;
int w1 = w - 1, h1 = h - 1;
// float eps = 0.02f;
const float sqreps = 0.0004f; // removed eps*eps from inner loop

View File

@ -93,7 +93,7 @@ public:
*/
float **Diagonals;
char *buffer;
char *DiagBuffer;
float *DiagBuffer;
int *StartRows;
bool CreateDiagonal(int index, int StartRow);
int n, m; //The matrix is n x n, with m diagonals on the lower triangle. Don't change these. They should be private but aren't for convenience.

View File

@ -37,6 +37,7 @@
#include "opthelper.h"
#include "cplx_wavelet_dec.h"
#include "median.h"
#include "iccstore.h"
#ifdef _OPENMP
#include <omp.h>
#endif

View File

@ -536,6 +536,8 @@ public:
size = 0;
upperBound = 0;
maxs = 0;
maxsf = 0.f;
clip = 0;
}
// create an identity LUT (LUT(x) = x) or a scaled identity LUT (LUT(x) = x / divisor)

View File

@ -74,7 +74,8 @@ class array2D :
{
private:
int x, y, owner, flags;
int x, y, owner;
unsigned int flags;
T ** ptr;
T * data;
bool lock; // useful lock to ensure data is not changed anymore.
@ -82,19 +83,19 @@ private:
{
if ((ptr) && ((h > y) || (4 * h < y))) {
delete[] ptr;
ptr = nullptr;
ptr = NULL;
}
if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) {
delete[] data;
data = nullptr;
data = NULL;
}
if (ptr == nullptr) {
if (ptr == NULL) {
ptr = new T*[h];
}
if (data == nullptr) {
if (data == NULL) {
data = new T[h * w + offset];
}
@ -112,7 +113,7 @@ public:
// use as empty declaration, resize before use!
// very useful as a member object
array2D() :
x(0), y(0), owner(0), ptr(nullptr), data(nullptr), lock(0)
x(0), y(0), owner(0), ptr(NULL), data(NULL), lock(0), flags(0)
{
//printf("got empty array2D init\n");
}
@ -150,7 +151,7 @@ public:
if (owner) {
data = new T[h * w];
} else {
data = nullptr;
data = NULL;
}
x = w;
@ -285,6 +286,8 @@ public:
if (this != &rhs)
{
flags = rhs.flags;
lock = rhs.lock;
if (!owner) { // we can only copy same size data
if ((x != rhs.x) || (y != rhs.y)) {
printf(" assignment error in array2D\n");

View File

@ -558,10 +558,20 @@ CameraConstantsStore::parse_camera_constants_file(Glib::ustring filename_)
while ((ret = fread(&buf[datasize], 1, bufsize - datasize, stream)) != 0) {
datasize += ret;
if (datasize == bufsize) {
if (datasize == bufsize) { // we need more memory
bufsize += increment;
buf = (char *)realloc(buf, bufsize);
increment *= 2;
void *temp = realloc(buf, bufsize); // try to realloc buffer with new size
if(!temp) { // realloc failed
temp = malloc(bufsize); // alloc now buffer
if (temp) { // alloc worked
memcpy(temp, buf, bufsize - increment); // copy old buffer content to new buffer
free(buf); // free old buffer
} else { // alloc didn't work, break
break;
}
}
buf = (char *)temp; // assign new buffer
increment *= 2; // double increment
}
}

View File

@ -68,11 +68,10 @@ void RawImageSource::CLASS cfa_linedn(float noise)
{
// allocate memory and assure the arrays don't have same 64 byte boundary to avoid L1 conflict misses
char *buffer = (char*)malloc(4 * TS * TS * sizeof(float) + 3 * 64);
float *cfain = (float*)(buffer);
float *cfablur = (float*)(buffer + (TS * TS * sizeof(float)) + 1 * 64);
float *cfadiff = (float*)(buffer + (2 * TS * TS * sizeof(float)) + 2 * 64);
float *cfadn = (float*)(buffer + (3 * TS * TS * sizeof(float)) + 3 * 64);
float *cfain = (float*)malloc(4 * TS * TS * sizeof(float) + 3 * 16 * sizeof(float));
float *cfablur = (cfain + (TS * TS) + 1 * 16);
float *cfadiff = (cfain + (2 * TS * TS) + 2 * 16);
float *cfadn = (cfain + (3 * TS * TS) + 3 * 16);
float linehvar[4], linevvar[4], noisefactor[4][8][2], coeffsq;
@ -250,7 +249,7 @@ void RawImageSource::CLASS cfa_linedn(float noise)
}
// clean up
free(buffer);
free(cfain);
// copy temporary buffer back to image matrix
#pragma omp for

View File

@ -23,6 +23,7 @@
#include "mytime.h"
#include "sleef.c"
#include "opthelper.h"
#include "iccstore.h"
#define pow_F(a,b) (xexpf(b*xlogf(a)))
@ -542,7 +543,7 @@ void Color::rgb2hsl(float r, float g, float b, float &h, float &s, float &l)
h_ = 4. + (var_R - var_G) / C;
}
h = float(h_ /= 6.0);
h = float(h_ / 6.0);
if ( h < 0.f ) {
h += 1.f;
@ -923,7 +924,7 @@ void Color::hsv2rgb (float h, float s, float v, int &r, int &g, int &b)
r1 = t;
g1 = p;
b1 = v;
} else if (i == 5) {
} else /*if (i == 5)*/ {
r1 = v;
g1 = p;
b1 = q;
@ -1647,7 +1648,7 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg
Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut
}
void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5)
void Color::calcGamma (double pwr, double ts, int mode, int imax, GammaValues &gamma)
{
//from Dcraw (D.Coffin)
int i;
@ -1683,12 +1684,13 @@ void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0
}
if (!mode--) {
gamma0 = g[0];
gamma1 = g[1];
gamma2 = g[2];
gamma3 = g[3];
gamma4 = g[4];
gamma5 = g[5];
gamma[0] = g[0];
gamma[1] = g[1];
gamma[2] = g[2];
gamma[3] = g[3];
gamma[4] = g[4];
gamma[5] = g[5];
gamma[6] = 0.;
return;
}
}
@ -1996,7 +1998,6 @@ void Color::skinred ( double J, double h, double sres, double Sp, float dred, fl
float factorskin, factorsat, factor, factorskinext, interm;
float scale = 100.0f / 100.1f; //reduction in normal zone
float scaleext = 1.0f; //reduction in transition zone
float protect_redh;
float deltaHH = 0.3f; //HH value transition : I have choice 0.3 radians
float HH;
bool doskin = false;
@ -2077,7 +2078,6 @@ void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, f
if(doskin) {
float factorskin, factorsat, factor, factorskinext;
float protect_redh;
float deltaHH = 0.3f; //HH value transition : I have choice 0.3 radians
float chromapro = sres / Sp;
@ -2757,8 +2757,8 @@ SSEFUNCTION void Color::LabGamutMunsell(float *labL, float *laba, float *labb,
printf(" Gamut : G1negat=%iiter G165535=%iiter \n", negat, moreRGB);
if (MunsDebugInfo) {
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhuelum[0] , MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum);
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhuelum[0] , MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum);
} else {
printf(" Munsell correction wasn't requested\n");
}

View File

@ -23,7 +23,6 @@
#include "rt_math.h"
#include "LUT.h"
#include "labimage.h"
#include "iccstore.h"
#include "iccmatrices.h"
#include "sleef.c"
#define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c)
@ -31,6 +30,8 @@
namespace rtengine
{
typedef std::array<double, 7> GammaValues;
#ifdef _DEBUG
class MunsellDebugInfo
@ -47,6 +48,7 @@ public:
#endif
class Color
{
@ -880,21 +882,21 @@ public:
return h;
}
/**
* @brief Get the gamma curves' parameters used by LCMS2
* @param pwr gamma value [>1]
* @param ts slope [0 ; 20]
* @param mode [always 0]
* @imax imax [always 0]
* @param gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
* @param gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value)
* @param gamma2 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
* @param gamma3 used in ip2Lab2rgb [0 ; 1], usually near 0.003(return value)
* @param gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
* @param gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
* @param gamma a pointer to an array of 6 double gamma values:
* gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
* gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value)
* gamma2 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
* gamma3 used in ip2Lab2rgb [0 ; 1], usually near 0.003(return value)
* gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
* gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
*/
static void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5);
static void calcGamma (double pwr, double ts, int mode, int imax, GammaValues &gamma);
/**

View File

@ -36,6 +36,7 @@
#include "opthelper.h"
#include "ciecam02.h"
#include "color.h"
#include "iccstore.h"
#undef CLIPD
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
@ -44,7 +45,7 @@ using namespace std;
namespace rtengine
{
Curve::Curve () : N(0), x(nullptr), y(nullptr), ypp(nullptr), hashSize(1000 /* has to be initialized to the maximum value */) {}
Curve::Curve () : N(0), ppn(0), x(nullptr), y(nullptr), mc(0.0), mfc(0.0), msc(0.0), mhc(0.0), ypp(nullptr), x1(0.0), y1(0.0), x2(0.0), y2(0.0), x3(0.0), y3(0.0), firstPointIncluded(false), increment(0.0), nbr_points(0), hashSize(1000 /* has to be initialized to the maximum value */) {}
void Curve::AddPolygons ()
{
@ -1434,11 +1435,9 @@ void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3],
double currY = pCurve->getVal(x) - prevY;
if (dY > 0.000001 || dY < -0.000001) {
float r1, g1, b1, r2, g2, b2, ro, go, bo;
float r1, g1, b1, r2, g2, b2;
Color::hsv2rgb(float(prevY), satur, lr1, r1, g1, b1);
Color::hsv2rgb(float(nextY), satur, lr2, r2, g2, b2);
bool chr = false;
bool lum = true;
LUTf dum;
float X1, X2, Y1, Y2, Z1, Z2, L1, a_1, b_1, c1, h1;
Color::rgbxyz(r2, g2, b2, X2, Y2, Z2, xyz_rgb);

File diff suppressed because it is too large Load Diff

View File

@ -43,14 +43,14 @@ public:
:exif_base(-1)
,ciff_base(-1)
,ciff_len(0)
,ifp(nullptr),ofp(nullptr)
,ifp(NULL),ofp(NULL)
,order(0x4949)
,ifname(nullptr)
,meta_data(nullptr)
,ifname(NULL)
,meta_data(NULL)
,shot_select(0),multi_out(0)
,float_raw_image(nullptr)
,image(nullptr)
,bright(1.),threshold(0.)
,float_raw_image(NULL)
,image(NULL)
,bright(1.)
,half_size(0),four_color_rgb(0),document_mode(0),highlight(0)
,verbose(0)
,use_auto_wb(0),use_camera_wb(0),use_camera_matrix(1)
@ -344,23 +344,23 @@ void foveon_make_curves(short **curvep, float dq[3], float div[3], float filt);
int foveon_apply_curve (short *curve, int i);
void foveon_interpolate();
void xtrans_interpolate (int passes);
void cielab (ushort rgb[3], short lab[3]);
//void xtrans_interpolate (int passes);
//void cielab (ushort rgb[3], short lab[3]);
void remove_zeroes();
void bad_pixels (const char *cfname);
void subtract (const char *fname);
//void remove_zeroes();
//void bad_pixels (const char *cfname);
//void subtract (const char *fname);
void gamma_curve (double pwr, double ts, int mode, int imax);
void pseudoinverse (double (*in)[3], double (*out)[3], int size);
void cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]);
void hat_transform (float *temp, float *base, int st, int size, int sc);
void wavelet_denoise();
//void hat_transform (float *temp, float *base, int st, int size, int sc);
//void wavelet_denoise();
void scale_colors();
void pre_interpolate();
void border_interpolate (int border);
void median_filter();
void blend_highlights();
void recover_highlights();
//void border_interpolate (int border);
//void median_filter();
//void blend_highlights();
//void recover_highlights();
void crop_masked_pixels();
void tiff_get (unsigned base, unsigned *tag, unsigned *type, unsigned *len, unsigned *save);
@ -397,7 +397,6 @@ void simple_coeff (int index);
short guess_byte_order (int words);
float find_green (int bps, int bite, int off0, int off1);
void identify();
void apply_profile (const char *input, const char *output);
void jpeg_thumb() {} // not needed
bool dcraw_coeff_overrides(const char make[], const char model[], int iso_speed, short trans[12], int *black_level, int *white_level);
void shiftXtransMatrix( const int offsy, const int offsx) {

File diff suppressed because it is too large Load Diff

View File

@ -962,24 +962,14 @@ void Crop::update (int todo)
// all pipette buffer processing should be finished now
PipetteBuffer::setReady();
// switch back to rgb
// Computing the preview image, i.e. converting from lab->Monitor color space (soft-proofing disabled) or lab->Output profile->Monitor color space (soft-proofing enabled)
parent->ipf.lab2monitorRgb (labnCrop, cropImg);
if (cropImageListener) {
// this in output space held in parallel to allow analysis like shadow/highlight
Glib::ustring outProfile = params.icm.output;
Glib::ustring workProfile = params.icm.working;
Image8 *cropImgtrue;
// Computing the internal image for analysis, i.e. conversion from lab->Output profile (rtSettings.HistogramWorking disabled) or lab->WCS (rtSettings.HistogramWorking enabled)
if(settings->HistogramWorking) {
cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, RI_RELATIVE, false); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ?
} else {
if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) {
outProfile = "sRGB";
}
cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, params.icm.outputIntent, false);
}
// internal image in output color space for analysis
Image8 *cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, params.icm);
int finalW = rqcropw;
@ -1121,7 +1111,7 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte
PreviewProps cp (orx, ory, orw, orh, skip);
int orW, orH;
parent->imgsrc->getSize (tr, cp, orW, orH);
parent->imgsrc->getSize (cp, orW, orH);
int cw = SKIPS(bw, skip);
int ch = SKIPS(bh, skip);

View File

@ -44,7 +44,7 @@ protected:
Imagefloat* origCrop; // "one chunk" allocation
LabImage* laboCrop; // "one chunk" allocation
LabImage* labnCrop; // "one chunk" allocation
Image8* cropImg; // "one chunk" allocation
Image8* cropImg; // "one chunk" allocation ; displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not
float * cbuf_real; // "one chunk" allocation
SHMap* cshmap; // per line allocation

View File

@ -36,16 +36,18 @@ extern const Settings* settings;
inline dfInfo& dfInfo::operator =(const dfInfo &o)
{
pathname = o.pathname;
maker = o.maker;
model = o.model;
iso = o.iso;
shutter = o.shutter;
timestamp = o.timestamp;
if (this != &o) {
pathname = o.pathname;
maker = o.maker;
model = o.model;
iso = o.iso;
shutter = o.shutter;
timestamp = o.timestamp;
if( ri ) {
delete ri;
ri = nullptr;
if( ri ) {
delete ri;
ri = NULL;
}
}
return *this;
@ -138,7 +140,7 @@ void dfInfo::updateRawImage()
if( ri->loadRaw(true)) {
delete ri;
ri = nullptr;
ri = NULL;
} else {
int H = ri->get_height();
int W = ri->get_width();
@ -200,7 +202,7 @@ void dfInfo::updateRawImage()
if( ri->loadRaw(true)) {
delete ri;
ri = nullptr;
ri = NULL;
} else {
ri->compress_image();
}
@ -332,11 +334,11 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
auto file = Gio::File::create_for_path (filename);
if (!file) {
return nullptr;
return 0;
}
if (!file->query_exists ()) {
return nullptr;
return 0;
}
try {
@ -344,11 +346,11 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
auto info = file->query_info ();
if (!info && info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
return nullptr;
return 0;
}
if (!options.fbShowHidden && info->is_hidden ()) {
return nullptr;
return 0;
}
Glib::ustring ext;
@ -359,14 +361,14 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
}
if (!options.is_extention_enabled (ext)) {
return nullptr;
return 0;
}
RawImage ri (filename);
int res = ri.loadRaw (false); // Read informations about shot
if (res != 0) {
return nullptr;
return 0;
}
dfList_t::iterator iter;
@ -406,7 +408,7 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
} catch(Gio::Error&) {}
return nullptr;
return 0;
}
void DFManager::getStat( int &totFiles, int &totTemplates)
@ -433,7 +435,7 @@ void DFManager::getStat( int &totFiles, int &totTemplates)
dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int isospeed, double shut, time_t t )
{
if( dfList.empty() ) {
return nullptr;
return 0;
}
std::string key( dfInfo::key(mak, mod, isospeed, shut) );
@ -467,7 +469,7 @@ dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int iso
}
}
return bestD != INFINITY ? &(bestMatch->second) : nullptr ;
return bestD != INFINITY ? &(bestMatch->second) : 0 ;
}
}
@ -478,7 +480,7 @@ RawImage* DFManager::searchDarkFrame( const std::string &mak, const std::string
if( df ) {
return df->getRawImage();
} else {
return nullptr;
return 0;
}
}
@ -496,7 +498,7 @@ RawImage* DFManager::searchDarkFrame( const Glib::ustring filename )
return df->getRawImage();
}
return nullptr;
return 0;
}
std::vector<badPix> *DFManager::getHotPixels ( const Glib::ustring filename )
{
@ -506,7 +508,7 @@ std::vector<badPix> *DFManager::getHotPixels ( const Glib::ustring filename )
}
}
return nullptr;
return 0;
}
std::vector<badPix> *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t )
{
@ -525,7 +527,7 @@ std::vector<badPix> *DFManager::getHotPixels ( const std::string &mak, const std
return &df->getHotPixels();
} else {
return nullptr;
return 0;
}
}
@ -624,7 +626,7 @@ std::vector<badPix> *DFManager::getBadPixels ( const std::string &mak, const std
}
if(!found) {
return nullptr;
return 0;
} else {
return &(iter->second);
}

View File

@ -245,7 +245,7 @@ void DiagonalCurve::NURBS_set ()
printf("sc_length[%zu/3]=%f \n", it, sc_length[it / 3]);
}
printf("NURBS diagonal curve: error detected!\n i=%d nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f", i, nbr_points, ppn, N, sc_length[i / 3], total_length);
printf("NURBS diagonal curve: error detected!\n i=%u nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f", i, nbr_points, ppn, N, sc_length[i / 3], total_length);
exit(0);
}

View File

@ -31,17 +31,19 @@ extern const Settings* settings;
inline ffInfo& ffInfo::operator =(const ffInfo &o)
{
pathname = o.pathname;
maker = o.maker;
model = o.model;
lens = o.lens;
shutter = o.shutter;
focallength = o.focallength;
timestamp = o.timestamp;
if (this != &o) {
pathname = o.pathname;
maker = o.maker;
model = o.model;
lens = o.lens;
focallength = o.focallength;
timestamp = o.timestamp;
aperture = o.aperture;
if( ri ) {
delete ri;
ri = nullptr;
if( ri ) {
delete ri;
ri = NULL;
}
}
return *this;
@ -131,7 +133,7 @@ void ffInfo::updateRawImage()
if( ri->loadRaw(true)) {
delete ri;
ri = nullptr;
ri = NULL;
} else {
int H = ri->get_height();
int W = ri->get_width();
@ -193,7 +195,7 @@ void ffInfo::updateRawImage()
if( ri->loadRaw(true)) {
delete ri;
ri = nullptr;
ri = NULL;
} else {
ri->compress_image();
}
@ -291,11 +293,11 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool)
auto file = Gio::File::create_for_path (filename);
if (!file ) {
return nullptr;
return 0;
}
if (!file->query_exists ()) {
return nullptr;
return 0;
}
try {
@ -303,11 +305,11 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool)
auto info = file->query_info ();
if (!info || info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
return nullptr;
return 0;
}
if (!options.fbShowHidden && info->is_hidden ()) {
return nullptr;
return 0;
}
Glib::ustring ext;
@ -319,7 +321,7 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool)
}
if (!options.is_extention_enabled (ext)) {
return nullptr;
return 0;
}
@ -327,7 +329,7 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool)
int res = ri.loadRaw (false); // Read informations about shot
if (res != 0) {
return nullptr;
return 0;
}
ffList_t::iterator iter;
@ -367,7 +369,7 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool)
} catch (Gio::Error&) {}
return nullptr;
return 0;
}
void FFManager::getStat( int &totFiles, int &totTemplates)
@ -394,7 +396,7 @@ void FFManager::getStat( int &totFiles, int &totTemplates)
ffInfo* FFManager::find( const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert, time_t t )
{
if( ffList.empty() ) {
return nullptr;
return 0;
}
std::string key( ffInfo::key(mak, mod, len, focal, apert) );
@ -428,7 +430,7 @@ ffInfo* FFManager::find( const std::string &mak, const std::string &mod, const s
}
}
return bestD != INFINITY ? &(bestMatch->second) : nullptr ;
return bestD != INFINITY ? &(bestMatch->second) : 0 ;
}
}
@ -439,7 +441,7 @@ RawImage* FFManager::searchFlatField( const std::string &mak, const std::string
if( ff ) {
return ff->getRawImage();
} else {
return nullptr;
return 0;
}
}
@ -457,7 +459,7 @@ RawImage* FFManager::searchFlatField( const Glib::ustring filename )
return ff->getRawImage();
}
return nullptr;
return 0;
}

View File

@ -34,8 +34,6 @@ public:
std::string maker; ///< manufacturer
std::string model; ///< model
std::string lens; ///< lens
int iso; ///< ISO (gain)
double shutter; ///< shutter or exposure time in sec
double aperture; ///< aperture in stops
double focallength; ///< focal length in mm
time_t timestamp; ///< seconds since 1 Jan 1970

View File

@ -311,10 +311,10 @@ void FlatCurve::CtrlPoints_set ()
if (nbr_points < 0) {
for(size_t it = 0; it < sc_x.size(); it += 3) {
printf("sc_length[%zd/3]=%f \n", it, sc_length[it / 3]);
printf("sc_length[%zu/3]=%f \n", it, sc_length[it / 3]);
}
printf("Flat curve: error detected!\n i=%d k=%d periodic=%d nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f\n", i, k, periodic, nbr_points, ppn, N, sc_length[i / 3], total_length);
printf("Flat curve: error detected!\n i=%u k=%u periodic=%d nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f\n", i, k, periodic, nbr_points, ppn, N, sc_length[i / 3], total_length);
exit(0);
}

View File

@ -1,397 +0,0 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
namespace rtengine
{
template<class T> T** allocArray (int W, int H)
{
T** t = new T*[H];
for (int i = 0; i < H; i++) {
t[i] = new T[W];
}
return t;
}
void RawImageSource::updateHLRecoveryMap (bool needred, bool needgreen, bool needblue, bool full)
{
// detect maximal pixel values
unsigned short* red = new unsigned short[W];
unsigned short* blue = new unsigned short[W];
int maxr = 0, maxg = 0, maxb = 0;
for (int i = 32; i < H - 32; i++) {
interpolate_row_rb (red, blue, green[i - 1], green[i], green[i + 1], i);
for (int j = 32; j < W - 32; j++) {
if (red[j] > maxr) {
maxr = red[j];
}
if (green[i][j] > maxg) {
maxg = green[i][j];
}
if (blue[j] > maxb) {
maxb = blue[j];
}
}
}
delete [] red;
delete [] blue;
maxr = maxr * 19 / 20;
maxg = maxg * 19 / 20;
maxb = maxb * 19 / 20;
int max[3];
max[0] = maxr;
max[1] = maxg;
max[2] = maxb;
if( options.rtSettings.verbose ) {
printf ("HLRecoveryMap Maximum: R: %d, G: %d, B: %d\n", maxr, maxg, maxb);
}
// downscale image
int dw = W / SCALE;
int dh = H / SCALE;
Image16* ds = new Image16 (dw, dh);
// overburnt areas
int** rec[3];
for (int i = 0; i < 3; i++) {
rec[i] = allocArray<int> (dw, dh);
}
unsigned short* reds[SCALE];
unsigned short* blues[SCALE];
for (int i = 0; i < SCALE; i++) {
reds[i] = new unsigned short[W];
blues[i] = new unsigned short[W];
}
for (int i = 0; i < dh; i++) {
for (int j = 0; j < SCALE; j++) {
interpolate_row_rb (reds[j], blues[j], green[SCALE * i + j - 1], green[SCALE * i + j], green[SCALE * i + j + 1], SCALE * i + j);
}
for (int j = 0; j < dw; j++) {
int sumr = 0;
int cr = 0;
int sumg = 0;
int cg = 0;
int sumb = 0;
int cb = 0;
for (int x = 0; x < SCALE; x++)
for (int y = 0; y < SCALE; y++) {
int ix = SCALE * i + x;
int jy = SCALE * j + y;
sumr += reds[x][jy];
if (reds[x][jy] < maxr) {
cr++;
}
sumg += green[ix][jy];
if (green[ix][jy] < maxg) {
cg++;
}
sumb += blues[x][jy];
if (blues[x][jy] < maxb) {
cb++;
}
}
if (cr < SCALE * SCALE && needred) {
rec[0][i][j] = INT_MAX;
} else {
rec[0][i][j] = sumr / SCALE / SCALE;
}
if (cg < SCALE * SCALE && needgreen) {
rec[1][i][j] = INT_MAX;
} else {
rec[1][i][j] = sumg / SCALE / SCALE;
}
if (cb < SCALE * SCALE && needblue) {
rec[2][i][j] = INT_MAX;
} else {
rec[2][i][j] = sumb / SCALE / SCALE;
}
ds->r(i, j) = sumr / SCALE / SCALE;
ds->g(i, j) = sumg / SCALE / SCALE;
ds->b(i, j) = sumb / SCALE / SCALE;
}
}
for (int i = 0; i < SCALE; i++) {
delete [] reds[i];
delete [] blues[i];
}
// STEP I. recover color from the partially lost areas
bool phase2 = false;
for (int k = 0; k < 400; k++) {
if (k > 200) {
phase2 = true;
}
for (int i = 1; i < dh - 1; i++)
for (int j = 1; j < dw - 1; j++) {
for (int c = 0; c < 3; c++) {
// if channel c is lost
if (rec[c][i][j] == INT_MAX) {
double ratio[2] = {0.0, 0.0};
double w[2] = {0.0, 0.0};
int count[2] = {0, 0};
int ix = 0;
for (int m = 0; m < 3; m++) {
if (m == c) {
continue;
}
// if channel m is not lost at this point (or already recovered)
if (rec[m][i][j] != INT_MAX && rec[m][i][j] >= 0) {
for (int x = -1; x <= 1; x++)
for (int y = -1; y <= 1; y++)
// average m/c color ratios in the surrounding pixels
if (rec[m][i + x][j + y] >= 0 && rec[m][i + x][j + y] != INT_MAX && rec[c][i + x][j + y] > 0 && rec[c][i + x][j + y] != INT_MAX) {
double ww = 1.0;
if (!phase2 && (/*(double)(rec[m][i+x][j+y] - rec[m][i][j])/max[m]*(rec[m][i+x][j+y] - rec[m][i][j])/max[m] > 1.0/2 || */rec[c][i + x][j + y] < max[c] * 3 / 4)) {
continue;
}
w[ix] += ww;
ratio[ix] += ww * rec[m][i + x][j + y] / rec[c][i + x][j + y];
count[ix] ++;
}
}
ix++;
}
// compute new pixel values from the surrounding color ratios
double newc = 0.0;
int nc = 0;
ix = 0;
for (int m = 0; m < 3; m++) {
if (c == m) {
continue;
}
if (count[ix]) {
newc += (double)rec[m][i][j] / ratio[ix] * w[ix];
nc++;
}
ix++;
}
if (nc) {
rec[c][i][j] = - (int) (newc / nc);
}
}
}
}
bool change = false;
for (int i = 0; i < dh; i++)
for (int j = 0; j < dw; j++)
for (int c = 0; c < 3; c++) {
if (rec[c][i][j] < 0) {
rec[c][i][j] = -rec[c][i][j];
}
change = true;
}
if (!change) {
break;
}
}
printf ("Phase1 vege\n");
// STEP II. recover fully lost pixels
if (full) {
int maxY = (299 * max[0] + 587 * max[1] + 114 * max[2]) / 1000;
phase2 = false;
for (int k = 0; k < 600; k++) {
if (k > 200) {
phase2 = true;
}
for (int i = 1; i < dh - 1; i++)
for (int j = 1; j < dw - 1; j++) {
if (rec[0][i][j] == INT_MAX || rec[1][i][j] == INT_MAX || rec[2][i][j] == INT_MAX) {
int count = 0;
double yavg = 0, iavg = 0, qavg = 0, weight = 0.0;
for (int x = -1; x <= 1; x++)
for (int y = -1; y <= 1; y++)
if (rec[0][i + x][j + y] > 0 && rec[0][i + x][j + y] != INT_MAX && rec[1][i + x][j + y] > 0 && rec[1][i + x][j + y] != INT_MAX && rec[2][i + x][j + y] > 0 && rec[2][i + x][j + y] != INT_MAX) {
// convert to yiq
double Y = 0.299 * rec[0][i + x][j + y] + 0.587 * rec[1][i + x][j + y] + 0.114 * rec[2][i + x][j + y];
double I = 0.596 * rec[0][i + x][j + y] - 0.275 * rec[1][i + x][j + y] - 0.321 * rec[2][i + x][j + y];
double Q = 0.212 * rec[0][i + x][j + y] - 0.523 * rec[1][i + x][j + y] + 0.311 * rec[2][i + x][j + y];
if (Y > maxY * 7 / 10) {
double w = 1.0;// / (I*I+Q*Q);
yavg += Y * w;
iavg += I * w;
qavg += Q * w;
weight += w;
count++;
}
}
if ((!phase2 && count > 5) || (phase2 && count > 3)) {
double Y = yavg / weight;
double I = iavg / weight;
double Q = qavg / weight;
rec[0][i][j] = - (Y + 0.956 * I + 0.621 * Q);
rec[1][i][j] = - (Y - 0.272 * I - 0.647 * Q);
rec[2][i][j] = - (Y - 1.105 * I + 1.702 * Q);
}
}
}
bool change = false;
for (int i = 0; i < dh; i++)
for (int j = 0; j < dw; j++)
for (int c = 0; c < 3; c++) {
if (rec[c][i][j] < 0) {
rec[c][i][j] = -rec[c][i][j];
}
change = true;
}
if (!change) {
break;
}
}
}
int maxval = 0;
for (int i = 0; i < dh; i++)
for (int j = 0; j < dw; j++)
for (int c = 0; c < 3; c++)
if (rec[c][i][j] != INT_MAX && rec[c][i][j] > maxval) {
maxval = rec[c][i][j];
}
for (int i = 0; i < dh; i++)
for (int j = 0; j < dw; j++)
if (rec[0][i][j] == INT_MAX || rec[1][i][j] == INT_MAX || rec[2][i][j] == INT_MAX) {
rec[0][i][j] = maxval;
rec[1][i][j] = maxval;
rec[2][i][j] = maxval;
}
if (hrmap[0] != NULL) {
freeArray<float> (hrmap[0], dh);
freeArray<float> (hrmap[1], dh);
freeArray<float> (hrmap[2], dh);
}
hrmap[0] = allocArray<float> (dw, dh);
hrmap[1] = allocArray<float> (dw, dh);
hrmap[2] = allocArray<float> (dw, dh);
this->full = full;
for (int i = 0; i < dh; i++)
for (int j = 0; j < dw; j++) {
hrmap[0][i][j] = (double)rec[0][i][j] / ds->r(i, j);
hrmap[1][i][j] = (double)rec[1][i][j] / ds->g(i, j);
hrmap[2][i][j] = (double)rec[2][i][j] / ds->b(i, j);
}
/* for (int i=0; i<dh; i++)
for (int j=0; j<dh; j++) {
ds->r(i,j) = CLIP (rec[0][i][j]);
ds->g(i,j) = CLIP (rec[1][i][j]);
ds->b(i,j) = CLIP (rec[2][i][j]);
}
ds->save ("test.png");
*/
delete ds;
freeArray<int> (rec[0], dh);
freeArray<int> (rec[1], dh);
freeArray<int> (rec[2], dh);
printf ("HLMap vege\n");
}
void RawImageSource::hlRecovery (unsigned short* red, unsigned short* green, unsigned short* blue, int i, int sx1, int sx2, int skip)
{
int blr = (i + SCALE / 2) / SCALE - 1;
if (blr < 0 || blr >= H / SCALE - 1) {
return;
}
double mr1 = 1.0 - ((double)((i + SCALE / 2) % SCALE) / SCALE + 0.5 / SCALE);
int jx = 0;
int maxcol = W / SCALE;
for (int j = sx1, jx = 0; j < sx2; j += skip, jx++) {
int blc = (j + SCALE / 2) / SCALE - 1;
if (blc < 0 || blc >= maxcol - 1) {
continue;
}
double mc1 = 1.0 - ((double)((j + SCALE / 2) % SCALE) / SCALE + 0.5 / SCALE);
double mulr = mr1 * mc1 * hrmap[0][blr][blc] + mr1 * (1.0 - mc1) * hrmap[0][blr][blc + 1] + (1.0 - mr1) * mc1 * hrmap[0][blr + 1][blc] + (1.0 - mr1) * (1.0 - mc1) * hrmap[0][blr + 1][blc + 1];
double mulg = mr1 * mc1 * hrmap[1][blr][blc] + mr1 * (1.0 - mc1) * hrmap[1][blr][blc + 1] + (1.0 - mr1) * mc1 * hrmap[1][blr + 1][blc] + (1.0 - mr1) * (1.0 - mc1) * hrmap[1][blr + 1][blc + 1];
double mulb = mr1 * mc1 * hrmap[2][blr][blc] + mr1 * (1.0 - mc1) * hrmap[2][blr][blc + 1] + (1.0 - mr1) * mc1 * hrmap[2][blr + 1][blc] + (1.0 - mr1) * (1.0 - mc1) * hrmap[2][blr + 1][blc + 1];
red[jx] = CLIP(red[jx] * mulr);
green[jx] = CLIP(green[jx] * mulg);
blue[jx] = CLIP(blue[jx] * mulb);
}
}
}

View File

@ -32,14 +32,15 @@
#include "../rtgui/options.h"
namespace
namespace rtengine
{
extern const Settings* settings;
void loadProfiles (const Glib::ustring& dirName,
std::map<Glib::ustring, cmsHPROFILE>* profiles,
std::map<Glib::ustring, rtengine::ProfileContent>* profileContents,
std::map<Glib::ustring, ProfileContent>* profileContents,
std::map<Glib::ustring, Glib::ustring>* profileNames,
bool nameUpper, bool onlyRgb)
bool nameUpper)
{
if (dirName.empty ()) {
return;
@ -76,10 +77,10 @@ void loadProfiles (const Glib::ustring& dirName,
}
if (profiles) {
const rtengine::ProfileContent content (filePath);
const ProfileContent content (filePath);
const cmsHPROFILE profile = content.toProfile ();
if (profile && (!onlyRgb || cmsGetColorSpace (profile) == cmsSigRgbData)) {
if (profile) {
profiles->insert (std::make_pair (name, profile));
if (profileContents) {
@ -95,20 +96,20 @@ void loadProfiles (const Glib::ustring& dirName,
} catch (Glib::Exception&) {}
}
inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, std::uint8_t& result)
inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, uint8_t& result)
{
if (cmsIsIntentSupported (profile, intent, direction)) {
result |= 1 << intent;
}
}
inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction)
inline uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction)
{
if (!profile) {
return 0;
}
std::uint8_t result = 0;
uint8_t result = 0;
getSupportedIntent (profile, INTENT_PERCEPTUAL, direction, result);
getSupportedIntent (profile, INTENT_RELATIVE_COLORIMETRIC, direction, result);
@ -121,7 +122,7 @@ inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number di
inline cmsHPROFILE createXYZProfile ()
{
double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0} };
return rtengine::ICCStore::createFromMatrix (mat, false, "XYZ");
return ICCStore::createFromMatrix (mat, false, "XYZ");
}
const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best, xyz_rec2020};
@ -164,7 +165,7 @@ std::vector<Glib::ustring> getWorkingProfiles ()
return res;
}
std::vector<Glib::ustring> ICCStore::getProfiles () const
std::vector<Glib::ustring> ICCStore::getProfiles (const bool onlyRgb) const
{
MyMutex::MyLock lock(mutex_);
@ -172,6 +173,7 @@ std::vector<Glib::ustring> ICCStore::getProfiles () const
std::vector<Glib::ustring> res;
for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) {
if (!onlyRgb || (onlyRgb && cmsGetColorSpace (profile->second) == cmsSigRgbData))
res.push_back (profile->first);
}
@ -187,8 +189,8 @@ std::vector<Glib::ustring> ICCStore::getProfilesFromDir (const Glib::ustring& di
ProfileMap profiles;
loadProfiles (profilesDir, &profiles, nullptr, nullptr, false, true);
loadProfiles (dirName, &profiles, nullptr, nullptr, false, true);
loadProfiles (profilesDir, &profiles, nullptr, nullptr, false);
loadProfiles (dirName, &profiles, nullptr, nullptr, false);
for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) {
res.push_back (profile->first);
@ -205,7 +207,7 @@ cmsHPROFILE ICCStore::makeStdGammaProfile (cmsHPROFILE iprof)
}
cmsUInt32Number bytesNeeded = 0;
cmsSaveProfileToMem(iprof, nullptr, &bytesNeeded);
cmsSaveProfileToMem(iprof, 0, &bytesNeeded);
if (bytesNeeded == 0) {
return nullptr;
@ -362,6 +364,312 @@ cmsHPROFILE ICCStore::workingSpaceGamma (const Glib::ustring& name) const
}
}
void ICCStore::getGammaArray(const procparams::ColorManagementParams &icm, GammaValues &ga)
{
const double eps = 0.000000001; // not divide by zero
if (!icm.freegamma) {//if Free gamma not selected
// gamma : ga[0],ga[1],ga[2],ga[3],ga[4],ga[5] by calcul
if(icm.gamma == "BT709_g2.2_s4.5") {
ga[0] = 2.22; //BT709 2.2 4.5 - my preferred as D.Coffin
ga[1] = 0.909995;
ga[2] = 0.090005;
ga[3] = 0.222222;
ga[4] = 0.081071;
} else if (icm.gamma == "sRGB_g2.4_s12.92") {
ga[0] = 2.40; //sRGB 2.4 12.92 - RT default as Lightroom
ga[1] = 0.947858;
ga[2] = 0.052142;
ga[3] = 0.077399;
ga[4] = 0.039293;
} else if (icm.gamma == "High_g1.3_s3.35") {
ga[0] = 1.3 ; //for high dynamic images
ga[1] = 0.998279;
ga[2] = 0.001721;
ga[3] = 0.298507;
ga[4] = 0.005746;
} else if (icm.gamma == "Low_g2.6_s6.9") {
ga[0] = 2.6 ; //gamma 2.6 variable : for low contrast images
ga[1] = 0.891161;
ga[2] = 0.108839;
ga[3] = 0.144928;
ga[4] = 0.076332;
} else if (icm.gamma == "standard_g2.2") {
ga[0] = 2.2; //gamma=2.2 (as gamma of Adobe, Widegamut...)
ga[1] = 1.;
ga[2] = 0.;
ga[3] = 1. / eps;
ga[4] = 0.;
} else if (icm.gamma == "standard_g1.8") {
ga[0] = 1.8; //gamma=1.8 (as gamma of Prophoto)
ga[1] = 1.;
ga[2] = 0.;
ga[3] = 1. / eps;
ga[4] = 0.;
} else /* if (icm.gamma == "linear_g1.0") */ {
ga[0] = 1.0; //gamma=1 linear : for high dynamic images (cf : D.Coffin...)
ga[1] = 1.;
ga[2] = 0.;
ga[3] = 1. / eps;
ga[4] = 0.;
}
ga[5] = 0.0;
ga[6] = 0.0;
} else { //free gamma selected
GammaValues g_a; //gamma parameters
double pwr = 1.0 / icm.gampos;
double ts = icm.slpos;
double slope = icm.slpos == 0 ? eps : icm.slpos;
int mode = 0, imax = 0;
Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
ga[4] = g_a[3] * ts;
//printf("g_a.gamma0=%f g_a.gamma1=%f g_a.gamma2=%f g_a.gamma3=%f g_a.gamma4=%f\n", g_a.gamma0,g_a.gamma1,g_a.gamma2,g_a.gamma3,g_a.gamma4);
ga[0] = icm.gampos;
ga[1] = 1. / (1.0 + g_a[4]);
ga[2] = g_a[4] / (1.0 + g_a[4]);
ga[3] = 1. / slope;
ga[5] = 0.0;
ga[6] = 0.0;
//printf("ga[0]=%f ga[1]=%f ga[2]=%f ga[3]=%f ga[4]=%f\n", ga[0],ga[1],ga[2],ga[3],ga[4]);
}
}
// WARNING: the caller must lock lcmsMutex
cmsHPROFILE ICCStore::createGammaProfile (const procparams::ColorManagementParams &icm, GammaValues &ga) {
float p[6]; //primaries
ga[6] = 0.0;
enum class ColorTemp {
D50 = 5003, // for Widegamut, Prophoto Best, Beta -> D50
D65 = 6504 // for sRGB, AdobeRGB, Bruce Rec2020 -> D65
};
ColorTemp temp = ColorTemp::D50;
//primaries for 7 working profiles ==> output profiles
// eventually to adapt primaries if RT used special profiles !
if (icm.output == "WideGamut") {
p[0] = 0.7350; //Widegamut primaries
p[1] = 0.2650;
p[2] = 0.1150;
p[3] = 0.8260;
p[4] = 0.1570;
p[5] = 0.0180;
} else if (icm.output == "Adobe RGB") {
p[0] = 0.6400; //Adobe primaries
p[1] = 0.3300;
p[2] = 0.2100;
p[3] = 0.7100;
p[4] = 0.1500;
p[5] = 0.0600;
temp = ColorTemp::D65;
} else if (icm.output == "sRGB") {
p[0] = 0.6400; // sRGB primaries
p[1] = 0.3300;
p[2] = 0.3000;
p[3] = 0.6000;
p[4] = 0.1500;
p[5] = 0.0600;
temp = ColorTemp::D65;
} else if (icm.output == "BruceRGB") {
p[0] = 0.6400; // Bruce primaries
p[1] = 0.3300;
p[2] = 0.2800;
p[3] = 0.6500;
p[4] = 0.1500;
p[5] = 0.0600;
temp = ColorTemp::D65;
} else if (icm.output == "Beta RGB") {
p[0] = 0.6888; // Beta primaries
p[1] = 0.3112;
p[2] = 0.1986;
p[3] = 0.7551;
p[4] = 0.1265;
p[5] = 0.0352;
} else if (icm.output == "BestRGB") {
p[0] = 0.7347; // Best primaries
p[1] = 0.2653;
p[2] = 0.2150;
p[3] = 0.7750;
p[4] = 0.1300;
p[5] = 0.0350;
} else if (icm.output == "Rec2020") {
p[0] = 0.7080; // Rec2020 primaries
p[1] = 0.2920;
p[2] = 0.1700;
p[3] = 0.7970;
p[4] = 0.1310;
p[5] = 0.0460;
temp = ColorTemp::D65;
} else {
p[0] = 0.7347; //ProPhoto and default primaries
p[1] = 0.2653;
p[2] = 0.1596;
p[3] = 0.8404;
p[4] = 0.0366;
p[5] = 0.0001;
}
cmsCIExyY xyD;
cmsCIExyYTRIPLE Primaries = {
{p[0], p[1], 1.0}, // red
{p[2], p[3], 1.0}, // green
{p[4], p[5], 1.0} // blue
};
cmsToneCurve* GammaTRC[3];
// 7 parameters for smoother curves
cmsFloat64Number Parameters[7] = { ga[0], ga[1], ga[2], ga[3], ga[4], ga[5], ga[6] } ;
//lcmsMutex->lock (); Mutex acquired by the caller
cmsWhitePointFromTemp(&xyD, (double)temp);
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters); //5 = smoother than 4
cmsHPROFILE oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC); //oprofdef become Outputprofile
cmsFreeToneCurve(GammaTRC[0]);
//lcmsMutex->unlock ();
return oprofdef;
}
// WARNING: the caller must lock lcmsMutex
cmsHPROFILE ICCStore::createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, GammaValues &ga) {
bool pro = false;
Glib::ustring outProfile;
cmsHPROFILE outputProfile = nullptr;
if (icm.freegamma && icm.gampos < 1.35) {
pro = true; //select profil with gammaTRC modified :
} else if (icm.gamma == "linear_g1.0" || (icm.gamma == "High_g1.3_s3.35")) {
pro = true; //pro=0 RT_sRGB || Prophoto
}
// Check that output profiles exist, otherwise use LCMS2
// Use the icc/icm profiles associated to possible working profiles, set in "options"
if (icm.working == "ProPhoto" && iccStore->outputProfileExist(options.rtSettings.prophoto) && !pro) {
outProfile = options.rtSettings.prophoto;
} else if (icm.working == "Adobe RGB" && iccStore->outputProfileExist(options.rtSettings.adobe) ) {
outProfile = options.rtSettings.adobe;
} else if (icm.working == "WideGamut" && iccStore->outputProfileExist(options.rtSettings.widegamut) ) {
outProfile = options.rtSettings.widegamut;
} else if (icm.working == "Beta RGB" && iccStore->outputProfileExist(options.rtSettings.beta) ) {
outProfile = options.rtSettings.beta;
} else if (icm.working == "BestRGB" && iccStore->outputProfileExist(options.rtSettings.best) ) {
outProfile = options.rtSettings.best;
} else if (icm.working == "BruceRGB" && iccStore->outputProfileExist(options.rtSettings.bruce) ) {
outProfile = options.rtSettings.bruce;
} else if (icm.working == "sRGB" && iccStore->outputProfileExist(options.rtSettings.srgb) && !pro) {
outProfile = options.rtSettings.srgb;
} else if (icm.working == "sRGB" && iccStore->outputProfileExist(options.rtSettings.srgb10) && pro) {
outProfile = options.rtSettings.srgb10;
} else if (icm.working == "ProPhoto" && iccStore->outputProfileExist(options.rtSettings.prophoto10) && pro) {
outProfile = options.rtSettings.prophoto10;
} else if (icm.working == "Rec2020" && iccStore->outputProfileExist(options.rtSettings.rec2020) ) {
outProfile = options.rtSettings.rec2020;
} else {
// Should not occurs
if (settings->verbose) {
printf("\"%s\": unknown working profile! - use LCMS2 substitution\n", icm.working.c_str() );
}
return nullptr;
}
//begin adaptation rTRC gTRC bTRC
//"outputProfile" profile has the same characteristics than RGB values, but TRC are adapted... for applying profile
if (settings->verbose) {
printf("Output Gamma - profile: \"%s\"\n", outProfile.c_str() ); //c_str()
}
outputProfile = iccStore->getProfile(outProfile); //get output profile
if (outputProfile == nullptr) {
if (settings->verbose) {
printf("\"%s\" ICC output profile not found!\n", outProfile.c_str());
}
return nullptr;
}
// 7 parameters for smoother curves
cmsFloat64Number Parameters[7] = { ga[0], ga[1], ga[2], ga[3], ga[4], ga[5], ga[6] };
//change desc Tag , to "free gamma", or "BT709", etc.
cmsMLU *mlu;
cmsContext ContextID = cmsGetProfileContextID(outputProfile); // create context to modify some TAGs
mlu = cmsMLUalloc(ContextID, 1);
// instruction with //ICC are used to generate ICC profile
if (mlu == nullptr) {
printf("Description error\n");
} else {
// Description TAG : selection of gamma and Primaries
if (!icm.freegamma) {
std::wstring gammaStr;
if(icm.gamma == "High_g1.3_s3.35") {
gammaStr = std::wstring(L"GammaTRC: High g=1.3 s=3.35");
} else if (icm.gamma == "Low_g2.6_s6.9") {
gammaStr = std::wstring(L"GammaTRC: Low g=2.6 s=6.9");
} else if (icm.gamma == "sRGB_g2.4_s12.92") {
gammaStr = std::wstring(L"GammaTRC: sRGB g=2.4 s=12.92");
} else if (icm.gamma == "BT709_g2.2_s4.5") {
gammaStr = std::wstring(L"GammaTRC: BT709 g=2.2 s=4.5");
} else if (icm.gamma == "linear_g1.0") {
gammaStr = std::wstring(L"GammaTRC: Linear g=1.0");
} else if (icm.gamma == "standard_g2.2") {
gammaStr = std::wstring(L"GammaTRC: g=2.2");
} else if (icm.gamma == "standard_g1.8") {
gammaStr = std::wstring(L"GammaTRC: g=1.8");
}
cmsMLUsetWide(mlu, "en", "US", gammaStr.c_str());
} else {
// create description with gamma + slope + primaries
std::wostringstream gammaWs;
gammaWs.precision(2);
gammaWs << "Manual GammaTRC: g=" << (float)icm.gampos << " s=" << (float)icm.slpos;
cmsMLUsetWide(mlu, "en", "US", gammaWs.str().c_str());
}
cmsWriteTag(outputProfile, cmsSigProfileDescriptionTag, mlu);//desc changed
/*
cmsMLUsetWide(mlu, "en", "US", L"General Public License - AdobeRGB compatible");//adapt to profil
cmsWriteTag(outputProfile, cmsSigCopyrightTag, mlu);
cmsMLUsetWide(mlu, "en", "US", L"RawTherapee");
cmsWriteTag(outputProfile, cmsSigDeviceMfgDescTag, mlu);
cmsMLUsetWide(mlu, "en", "US", L"RTMedium"); //adapt to profil
cmsWriteTag(outputProfile, cmsSigDeviceModelDescTag, mlu);
*/
cmsMLUfree (mlu);
}
// Calculate output profile's rTRC gTRC bTRC
cmsToneCurve* GammaTRC = nullptr;
GammaTRC = cmsBuildParametricToneCurve(nullptr, 5, Parameters);
cmsWriteTag(outputProfile, cmsSigRedTRCTag, (void*)GammaTRC );
cmsWriteTag(outputProfile, cmsSigGreenTRCTag, (void*)GammaTRC );
cmsWriteTag(outputProfile, cmsSigBlueTRCTag, (void*)GammaTRC );
if (GammaTRC) {
cmsFreeToneCurve(GammaTRC);
}
return outputProfile;
}
bool ICCStore::outputProfileExist (const Glib::ustring& name) const
{
MyMutex::MyLock lock(mutex_);
return fileProfiles.find(name) != fileProfiles.end();
}
cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const
{
@ -433,21 +741,21 @@ ProfileContent ICCStore::getContent (const Glib::ustring& name) const
return r != fileProfileContents.end () ? r->second : ProfileContent();
}
std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const
uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const
{
MyMutex::MyLock lock (mutex_);
return getSupportedIntents (profile, LCMS_USED_AS_INPUT);
}
std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const
uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const
{
MyMutex::MyLock lock (mutex_);
return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT);
}
std::uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const
uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const
{
MyMutex::MyLock lock (mutex_);
@ -464,15 +772,15 @@ void ICCStore::init (const Glib::ustring& usrICCDir, const Glib::ustring& rtICCD
profilesDir = Glib::build_filename (rtICCDir, "output");
fileProfiles.clear();
fileProfileContents.clear();
loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, nullptr, false, true);
loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, nullptr, false, true);
loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, nullptr, false);
loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, nullptr, false);
// Input profiles
// Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir)
stdProfilesDir = Glib::build_filename (rtICCDir, "input");
fileStdProfiles.clear();
fileStdProfilesFileNames.clear();
loadProfiles (stdProfilesDir, nullptr, nullptr, &fileStdProfilesFileNames, true, false);
loadProfiles (stdProfilesDir, nullptr, nullptr, &fileStdProfilesFileNames, true);
}
// Determine the first monitor default profile of operating system, if selected
@ -551,7 +859,7 @@ ProfileContent::ProfileContent (cmsHPROFILE hProfile) : data(nullptr), length(0)
if (hProfile != nullptr) {
cmsUInt32Number bytesNeeded = 0;
cmsSaveProfileToMem(hProfile, nullptr, &bytesNeeded);
cmsSaveProfileToMem(hProfile, 0, &bytesNeeded);
if (bytesNeeded > 0) {
data = new char[bytesNeeded + 1];

View File

@ -23,6 +23,9 @@
#include <glibmm.h>
#include <map>
#include <string>
#include <cstdint>
#include "procparams.h"
#include "color.h"
#include "../rtgui/threadutils.h"
namespace rtengine
@ -85,8 +88,11 @@ public:
void init (const Glib::ustring& usrICCDir, const Glib::ustring& stdICCDir);
static void getGammaArray(const procparams::ColorManagementParams &icm, GammaValues &ga);
static cmsHPROFILE makeStdGammaProfile (cmsHPROFILE iprof);
static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring());
static cmsHPROFILE createGammaProfile (const procparams::ColorManagementParams &icm, GammaValues &ga);
static cmsHPROFILE createCustomGammaOutputProfile (const procparams::ColorManagementParams &icm, GammaValues &ga);
// Main monitors standard profile name, from OS
void findDefaultMonitorProfile ();
@ -98,23 +104,24 @@ public:
TMatrix workingSpaceMatrix (const Glib::ustring& name) const;
TMatrix workingSpaceInverseMatrix (const Glib::ustring& name) const;
cmsHPROFILE getProfile (const Glib::ustring& name) const;
cmsHPROFILE getStdProfile (const Glib::ustring& name) const;
ProfileContent getContent (const Glib::ustring& name) const;
bool outputProfileExist (const Glib::ustring& name) const;
cmsHPROFILE getProfile (const Glib::ustring& name) const;
cmsHPROFILE getStdProfile (const Glib::ustring& name) const;
ProfileContent getContent (const Glib::ustring& name) const;
cmsHPROFILE getXYZProfile () const;
cmsHPROFILE getsRGBProfile () const;
std::vector<Glib::ustring> getProfiles () const;
std::vector<Glib::ustring> getProfiles (const bool onlyRgb = false) const;
std::vector<Glib::ustring> getProfilesFromDir (const Glib::ustring& dirName) const;
std::uint8_t getInputIntents (cmsHPROFILE profile) const;
std::uint8_t getOutputIntents (cmsHPROFILE profile) const;
std::uint8_t getProofIntents (cmsHPROFILE profile) const;
uint8_t getInputIntents (cmsHPROFILE profile) const;
uint8_t getOutputIntents (cmsHPROFILE profile) const;
uint8_t getProofIntents (cmsHPROFILE profile) const;
std::uint8_t getInputIntents (const Glib::ustring& name) const;
std::uint8_t getOutputIntents (const Glib::ustring& name) const;
std::uint8_t getProofIntents (const Glib::ustring& name) const;
uint8_t getInputIntents (const Glib::ustring& name) const;
uint8_t getOutputIntents (const Glib::ustring& name) const;
uint8_t getProofIntents (const Glib::ustring& name) const;
};
#define iccStore ICCStore::getInstance()
@ -140,17 +147,17 @@ inline Glib::ustring ICCStore::getDefaultMonitorProfileName () const
return defaultMonitorProfile;
}
inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const
inline uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const
{
return getInputIntents (getProfile (name));
}
inline std::uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const
inline uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const
{
return getOutputIntents (getProfile (name));
}
inline std::uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const
inline uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const
{
return getProofIntents (getProfile (name));
}

View File

@ -326,43 +326,48 @@ Image16::tofloat()
}
// Parallized transformation; create transform with cmsFLAGS_NOCACHE!
void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform)
void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage, int cx, int cy)
{
//cmsDoTransform(hTransform, data, data, planestride);
// LittleCMS cannot parallelize planar setups -- Hombre: LCMS2.4 can! But it we use this new feature, memory allocation have to be modified too
// LittleCMS cannot parallelize planar Lab float images
// so build temporary buffers to allow multi processor execution
#ifdef _OPENMP
#pragma omp parallel
#endif
{
AlignedBuffer<unsigned short> buffer(width * 3);
AlignedBuffer<float> bufferLab(width * 3);
AlignedBuffer<unsigned short> bufferRGB(width * 3);
#ifdef _OPENMP
#pragma omp for schedule(static)
#endif
for (int y = 0; y < height; y++)
for (int y = cy; y < cy + height; y++)
{
unsigned short *p = buffer.data, *pR = r(y), *pG = g(y), *pB = b(y);
unsigned short *pRGB, *pR, *pG, *pB;
float *pLab, *pL, *pa, *pb;
pLab= bufferLab.data;
pL = labImage.L[y] + cx;
pa = labImage.a[y] + cx;
pb = labImage.b[y] + cx;
for (int x = 0; x < width; x++) {
*(p++) = *(pR++);
*(p++) = *(pG++);
*(p++) = *(pB++);
*(pLab++) = *(pL++) / 327.68f;
*(pLab++) = *(pa++) / 327.68f;
*(pLab++) = *(pb++) / 327.68f;
}
cmsDoTransform (hTransform, buffer.data, buffer.data, width);
cmsDoTransform (hTransform, bufferLab.data, bufferRGB.data, width);
p = buffer.data;
pR = r(y);
pG = g(y);
pB = b(y);
pRGB = bufferRGB.data;
pR = r(y - cy);
pG = g(y - cy);
pB = b(y - cy);
for (int x = 0; x < width; x++) {
*(pR++) = *(p++);
*(pG++) = *(p++);
*(pB++) = *(p++);
*(pR++) = *(pRGB++);
*(pG++) = *(pRGB++);
*(pB++) = *(pRGB++);
}
} // End of parallelization
}

View File

@ -96,7 +96,7 @@ public:
delete this;
}
void ExecCMSTransform(cmsHTRANSFORM hTransform);
void ExecCMSTransform(cmsHTRANSFORM hTransform, const LabImage &labImage, int cx, int cy);
};
}

View File

@ -52,7 +52,7 @@ namespace
// Opens a file for binary writing and request exclusive lock (cases were you need "wb" mode plus locking)
FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname)
{
FILE* f = nullptr;
FILE* f = NULL;
#ifdef WIN32
@ -91,13 +91,13 @@ Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid h
// For only copying the raw input data
void ImageIO::setMetadata (const rtexif::TagDirectory* eroot)
{
if (exifRoot != nullptr) {
if (exifRoot != NULL) {
delete exifRoot;
exifRoot = nullptr;
exifRoot = NULL;
}
if (eroot) {
rtexif::TagDirectory* td = ((rtexif::TagDirectory*)eroot)->clone (nullptr);
rtexif::TagDirectory* td = ((rtexif::TagDirectory*)eroot)->clone (NULL);
// make IPTC and XMP pass through
td->keepTag(0x83bb); // IPTC
@ -115,18 +115,18 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr
exifChange.clear();
exifChange = exif;
if (exifRoot != nullptr) {
if (exifRoot != NULL) {
delete exifRoot;
exifRoot = nullptr;
exifRoot = NULL;
}
if (eroot) {
exifRoot = ((rtexif::TagDirectory*)eroot)->clone (nullptr);
exifRoot = ((rtexif::TagDirectory*)eroot)->clone (NULL);
}
if (iptc != nullptr) {
if (iptc != NULL) {
iptc_data_free (iptc);
iptc = nullptr;
iptc = NULL;
}
// build iptc structures for libiptcdata
@ -184,7 +184,7 @@ void ImageIO::setOutputProfile (char* pdata, int plen)
profileData = new char [plen];
memcpy (profileData, pdata, plen);
} else {
profileData = nullptr;
profileData = NULL;
}
profileLength = plen;
@ -224,7 +224,7 @@ int ImageIO::getPNGSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat,
}
//initializing main structures
png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png) {
fclose (file);
@ -303,7 +303,7 @@ int ImageIO::loadPNG (Glib::ustring fname)
}
//initializing main structures
png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png) {
fclose (file);
@ -331,7 +331,7 @@ int ImageIO::loadPNG (Glib::ustring fname)
png_read_info(png, info);
embProfile = nullptr;
embProfile = NULL;
//retrieving image information
png_uint_32 width, height;
@ -388,7 +388,7 @@ int ImageIO::loadPNG (Glib::ustring fname)
for (unsigned int i = 0; i < height; i++) {
png_read_row (png, (png_byte*)row, nullptr);
png_read_row (png, (png_byte*)row, NULL);
if (bit_depth == 16) { // convert scanline to host byte order
unsigned short* srow = (unsigned short*)row;
@ -405,7 +405,7 @@ int ImageIO::loadPNG (Glib::ustring fname)
}
}
png_read_end (png, nullptr);
png_read_end (png, 0);
png_destroy_read_struct (&png, &info, &end_info);
delete [] row;
@ -489,7 +489,7 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
if (hasprofile) {
embProfile = cmsOpenProfileFromMem (loadedProfileData, loadedProfileLength);
} else {
embProfile = nullptr;
embProfile = NULL;
}
jpeg_start_decompress(&cinfo);
@ -568,7 +568,7 @@ int ImageIO::loadJPEG (Glib::ustring fname)
if (hasprofile) {
embProfile = cmsOpenProfileFromMem (loadedProfileData, loadedProfileLength);
} else {
embProfile = nullptr;
embProfile = NULL;
}
jpeg_start_decompress(&cinfo);
@ -623,7 +623,7 @@ int ImageIO::getTIFFSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat,
TIFF* in = TIFFOpen(fname.c_str(), "r");
#endif
if (in == nullptr) {
if (in == NULL) {
return IMIO_CANNOTREADFILE;
}
@ -732,7 +732,7 @@ int ImageIO::loadTIFF (Glib::ustring fname)
TIFF* in = TIFFOpen(fname.c_str(), "r");
#endif
if (in == nullptr) {
if (in == NULL) {
return IMIO_CANNOTREADFILE;
}
@ -771,39 +771,39 @@ int ImageIO::loadTIFF (Glib::ustring fname)
* We could use the min/max values set in TIFFTAG_SMINSAMPLEVALUE and
* TIFFTAG_SMAXSAMPLEVALUE, but for now, we normalize the image to the
* effective minimum and maximum values
*
printf("Informations de \"%s\":\n", fname.c_str());
uint16 tiffDefaultScale, tiffBaselineExposure, tiffLinearResponseLimit;
if (TIFFGetField(in, TIFFTAG_DEFAULTSCALE, &tiffDefaultScale)) {
printf(" DefaultScale: %d\n", tiffDefaultScale);
}
else
printf(" No DefaultScale value!\n");
if (TIFFGetField(in, TIFFTAG_BASELINEEXPOSURE, &tiffBaselineExposure)) {
printf(" BaselineExposure: %d\n", tiffBaselineExposure);
}
else
printf(" No BaselineExposure value!\n");
if (TIFFGetField(in, TIFFTAG_LINEARRESPONSELIMIT, &tiffLinearResponseLimit)) {
printf(" LinearResponseLimit: %d\n", tiffLinearResponseLimit);
}
else
printf(" No LinearResponseLimit value!\n");
*/
if (options.rtSettings.verbose) {
printf("Informations of \"%s\":\n", fname.c_str());
uint16 tiffDefaultScale, tiffBaselineExposure, tiffLinearResponseLimit;
if (TIFFGetField(in, TIFFTAG_DEFAULTSCALE, &tiffDefaultScale)) {
printf(" DefaultScale: %d\n", tiffDefaultScale);
}
else
printf(" No DefaultScale value!\n");
if (TIFFGetField(in, TIFFTAG_BASELINEEXPOSURE, &tiffBaselineExposure)) {
printf(" BaselineExposure: %d\n", tiffBaselineExposure);
}
else
printf(" No BaselineExposure value!\n");
if (TIFFGetField(in, TIFFTAG_LINEARRESPONSELIMIT, &tiffLinearResponseLimit)) {
printf(" LinearResponseLimit: %d\n", tiffLinearResponseLimit);
}
else
printf(" No LinearResponseLimit value!\n");
uint16 tiffMinValue, tiffMaxValue;
if (TIFFGetField(in, TIFFTAG_SMINSAMPLEVALUE, &tiffMinValue)) {
printf(" MinValue: %d\n", tiffMinValue);
uint16 tiffMinValue, tiffMaxValue;
if (TIFFGetField(in, TIFFTAG_SMINSAMPLEVALUE, &tiffMinValue)) {
printf(" MinValue: %d\n", tiffMinValue);
}
else
printf(" No minimum value!\n");
if (TIFFGetField(in, TIFFTAG_SMAXSAMPLEVALUE, &tiffMaxValue)) {
printf(" MaxValue: %d\n\n", tiffMaxValue);
}
else
printf(" No maximum value!\n\n");
printf(" Those values are not taken into account, the image data are normalized to a [0;1] range\n\n");
}
else
printf(" No minimum value!\n");
if (TIFFGetField(in, TIFFTAG_SMAXSAMPLEVALUE, &tiffMaxValue)) {
printf(" MaxValue: %d\n\n", tiffMaxValue);
}
else
printf(" No maximum value!\n\n");
printf("\n");
*/
char* profdata;
deleteLoadedProfileData();
@ -811,32 +811,10 @@ int ImageIO::loadTIFF (Glib::ustring fname)
if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &loadedProfileLength, &profdata)) {
embProfile = cmsOpenProfileFromMem (profdata, loadedProfileLength);
// For 32 bits floating point images, gamma is forced to linear in embedded ICC profiles
if ( sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT) ) {
// Modifying the gammaTRG tags
cmsWriteTag(embProfile, cmsSigGreenTRCTag, (void*)Color::linearGammaTRC );
cmsWriteTag(embProfile, cmsSigRedTRCTag, (void*)Color::linearGammaTRC );
cmsWriteTag(embProfile, cmsSigBlueTRCTag, (void*)Color::linearGammaTRC );
// Saving the profile in the memory
cmsUInt32Number bytesNeeded = 0;
cmsSaveProfileToMem(embProfile, nullptr, &bytesNeeded);
if (bytesNeeded > 0) {
loadedProfileData = new char[bytesNeeded + 1];
cmsSaveProfileToMem(embProfile, loadedProfileData, &bytesNeeded);
}
loadedProfileLength = (int)bytesNeeded;
} else {
// Saving the profile in the memory as is
loadedProfileData = new char [loadedProfileLength];
memcpy (loadedProfileData, profdata, loadedProfileLength);
}
loadedProfileData = new char [loadedProfileLength];
memcpy (loadedProfileData, profdata, loadedProfileLength);
} else {
embProfile = nullptr;
embProfile = NULL;
}
allocate (width, height);
@ -859,7 +837,7 @@ int ImageIO::loadTIFF (Glib::ustring fname)
if (sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT)) {
setScanline (row, linebuffer, bitspersample, minValue, maxValue);
} else {
setScanline (row, linebuffer, bitspersample, nullptr, nullptr);
setScanline (row, linebuffer, bitspersample, NULL, NULL);
}
if (pl && !(row % 100)) {
@ -930,7 +908,7 @@ int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps)
pl->setProgress (0.0);
}
png_structp png = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_structp png = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png) {
fclose (file);
@ -940,7 +918,7 @@ int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps)
png_infop info = png_create_info_struct(png);
if (!info) {
png_destroy_write_struct (&png, nullptr);
png_destroy_write_struct (&png, 0);
fclose (file);
return IMIO_HEADERERROR;
}
@ -1123,7 +1101,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
int bytes = 0;
if (!error && (bytes = iptc_jpeg_ps3_save_iptc (nullptr, 0, iptcdata, size, buffer, 65532)) < 0) {
if (!error && (bytes = iptc_jpeg_ps3_save_iptc (NULL, 0, iptcdata, size, buffer, 65532)) < 0) {
if (iptcdata) {
iptc_data_free_buf (iptc, iptcdata);
}
@ -1329,23 +1307,23 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed)
//TODO Even though we are saving EXIF IFD - MakerNote still comes out screwed.
if ((tag = exifRoot->getTag (TIFFTAG_MODEL)) != nullptr) {
if ((tag = exifRoot->getTag (TIFFTAG_MODEL)) != NULL) {
TIFFSetField (out, TIFFTAG_MODEL, tag->getValue());
}
if ((tag = exifRoot->getTag (TIFFTAG_MAKE)) != nullptr) {
if ((tag = exifRoot->getTag (TIFFTAG_MAKE)) != NULL) {
TIFFSetField (out, TIFFTAG_MAKE, tag->getValue());
}
if ((tag = exifRoot->getTag (TIFFTAG_DATETIME)) != nullptr) {
if ((tag = exifRoot->getTag (TIFFTAG_DATETIME)) != NULL) {
TIFFSetField (out, TIFFTAG_DATETIME, tag->getValue());
}
if ((tag = exifRoot->getTag (TIFFTAG_ARTIST)) != nullptr) {
if ((tag = exifRoot->getTag (TIFFTAG_ARTIST)) != NULL) {
TIFFSetField (out, TIFFTAG_ARTIST, tag->getValue());
}
if ((tag = exifRoot->getTag (TIFFTAG_COPYRIGHT)) != nullptr) {
if ((tag = exifRoot->getTag (TIFFTAG_COPYRIGHT)) != NULL) {
TIFFSetField (out, TIFFTAG_COPYRIGHT, tag->getValue());
}
@ -1442,7 +1420,7 @@ void png_flush(png_structp png_ptr)
FILE *io_ptr;
io_ptr = (FILE *)(png_get_io_ptr(png_ptr));
if (io_ptr != nullptr) {
if (io_ptr != NULL) {
fflush(io_ptr);
}
}

View File

@ -41,10 +41,10 @@ class ImageMatrices
{
public:
double rgb_cam[3][3];
double cam_rgb[3][3];
double xyz_cam[3][3];
double cam_xyz[3][3];
double rgb_cam[3][3] = {};
double cam_rgb[3][3] = {};
double xyz_cam[3][3] = {};
double cam_xyz[3][3] = {};
};
class ImageSource : public InitialImage
@ -100,7 +100,7 @@ public:
}
virtual void getFullSize (int& w, int& h, int tr = TR_NONE) {}
virtual void getSize (int tran, PreviewProps pp, int& w, int& h) {}
virtual void getSize (PreviewProps pp, int& w, int& h) = 0;
virtual int getRotateDegree() const
{
return 0;

View File

@ -23,6 +23,7 @@
#include "../rtgui/ppversion.h"
#include "colortemp.h"
#include "improcfun.h"
#include "iccstore.h"
#ifdef _OPENMP
#include <omp.h>
#endif
@ -32,16 +33,15 @@ namespace rtengine
extern const Settings* settings;
ImProcCoordinator::ImProcCoordinator ()
: orig_prev(nullptr), oprevi(nullptr), oprevl(nullptr), nprevl(nullptr), previmg(nullptr), workimg(nullptr),
ncie(nullptr), imgsrc(nullptr), shmap(nullptr), lastAwbEqual(0.), ipf(&params, true), monitorIntent(RI_RELATIVE), scale(10),
highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false),
bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(NAN),
: orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL),
ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(&params, true), monitorIntent(RI_RELATIVE),
softProof(false), gamutCheck(false), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false),
allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(NAN),
ctColorCurve(),
hltonecurve(65536),
shtonecurve(65536),
tonecurve(65536, 0), //,1);
chaut(0.f), redaut(0.f), blueaut(0.f), maxredaut(0.f), maxblueaut(0.f), minredaut(0.f), minblueaut(0.f), nresi(0.f),
chromina(0.f), sigma(0.f), lumema(0.f),
lumacurve(32770, 0), // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation
chroma_acurve(65536, 0),
chroma_bcurve(65536, 0),
@ -84,12 +84,12 @@ ImProcCoordinator::ImProcCoordinator ()
rcurvehist(256), rcurvehistCropped(256), rbeforehist(256),
gcurvehist(256), gcurvehistCropped(256), gbeforehist(256),
bcurvehist(256), bcurvehistCropped(256), bbeforehist(256),
fw(0), fh(0), tr(0),
fullw(1), fullh(1),
pW(-1), pH(-1),
plistener(nullptr), imageListener(nullptr), aeListener(nullptr), acListener(nullptr), abwListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), hListener(nullptr),
resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false), wavcontlutili(false),
butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), conversionBuffer(1, 1)
plistener(NULL), imageListener(NULL), aeListener(NULL), acListener(NULL), abwListener(NULL), actListener(NULL), adnListener(NULL), awavListener(NULL), dehaListener(NULL), hListener(NULL),
resultValid(false), lastOutputProfile("BADFOOD"), lastOutputIntent(RI__COUNT), lastOutputBPC(false), thread(nullptr), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false), wavcontlutili(false),
butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), conversionBuffer(1, 1), colourToningSatLimit(0.f), colourToningSatLimitOpacity(0.f)
{}
void ImProcCoordinator::assign (ImageSource* imgsrc)
@ -138,9 +138,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
int readyphase = 0;
bwAutoR = bwAutoG = bwAutoB = -9000.f;
chaut = redaut = blueaut = maxredaut = maxblueaut = nresi = highresi = 0.f;
chromina = sigma = lumema = 0.f;
minredaut = minblueaut = 10000.f;
if (todo == CROP && ipf.needsPCVignetting()) {
todo |= TRANSFORM; // Change about Crop does affect TRANSFORM
@ -443,11 +440,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh,
params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast,
params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2,
vhist16, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale == 1 ? 1 : 1);
vhist16, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, 1);
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale == 1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale == 1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1);
opautili = false;
@ -471,7 +468,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
if(params.blackwhite.enabled) {
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1);
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, 1);
}
colourToningSatLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f;
@ -539,7 +536,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
DCPProfile::ApplyState as;
DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB, as);
ipf.rgbProc (oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation,
ipf.rgbProc (oprevi, oprevl, NULL, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation,
rCurve, gCurve, bCurve, colourToningSatLimit , colourToningSatLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, dcpProf, as);
if(params.blackwhite.enabled && params.blackwhite.autoc && abwListener) {
@ -611,7 +608,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
// ipf.MSR(nprevl, nprevl->W, nprevl->H, 1);
histCCurve.clear();
histLCurve.clear();
ipf.chromiLuminanceCurve (nullptr, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLCurve);
ipf.chromiLuminanceCurve (NULL, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLCurve);
ipf.vibrance(nprevl);
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) {
@ -765,7 +762,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
delete ncie;
}
ncie = nullptr;
ncie = NULL;
if (CAMBrightCurveJ) {
CAMBrightCurveJ.reset();
@ -778,8 +775,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
// Update the monitor color transform if necessary
if (todo & M_MONITOR) {
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent);
if ((todo & M_MONITOR) || (lastOutputProfile!=params.icm.output) || lastOutputIntent!=params.icm.outputIntent || lastOutputBPC!=params.icm.outputBPC) {
lastOutputProfile = params.icm.output;
lastOutputIntent = params.icm.outputIntent;
lastOutputBPC = params.icm.outputBPC;
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProof, gamutCheck);
}
// process crop, if needed
@ -794,20 +794,12 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
MyMutex::MyLock prevImgLock(previmg->getMutex());
try {
// Computing the preview image, i.e. converting from WCS->Monitor color space (soft-proofing disabled) or WCS->Output profile->Monitor color space (soft-proofing enabled)
ipf.lab2monitorRgb (nprevl, previmg);
// Computing the internal image for analysis, i.e. conversion from WCS->Output profile
delete workimg;
Glib::ustring outProfile = params.icm.output;
if(settings->HistogramWorking) {
Glib::ustring workProfile = params.icm.working;
workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, RI_RELATIVE, true); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ?
} else {
if (params.icm.output.empty() || params.icm.output == ColorManagementParams::NoICMString) {
outProfile = "sRGB";
}
workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, params.icm.outputIntent, false);
}
workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, params.icm);
} catch(char * str) {
progress ("Error converting file...", 0);
return;
@ -849,19 +841,19 @@ void ImProcCoordinator::freeAll ()
delete oprevi;
}
oprevi = nullptr;
oprevi = NULL;
delete orig_prev;
orig_prev = nullptr;
orig_prev = NULL;
delete oprevl;
oprevl = nullptr;
oprevl = NULL;
delete nprevl;
nprevl = nullptr;
nprevl = NULL;
if (ncie) {
delete ncie;
}
ncie = nullptr;
ncie = NULL;
if (imageListener) {
imageListener->delImage (previmg);
@ -875,7 +867,7 @@ void ImProcCoordinator::freeAll ()
delete shmap;
}
shmap = nullptr;
shmap = NULL;
}
@ -905,7 +897,7 @@ void ImProcCoordinator::setScale (int prevscale)
do {
prevscale--;
PreviewProps pp (0, 0, fw, fh, prevscale);
imgsrc->getSize (tr, pp, nW, nH);
imgsrc->getSize (pp, nW, nH);
} while(nH < 400 && prevscale > 1 && (nW * nH < 1000000) ); // sctually hardcoded values, perhaps a better choice is possible
if (settings->verbose) {
@ -1094,7 +1086,7 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &
MyMutex::MyLock lock(mProcessing);
LCPMapper *pLCPMap = nullptr;
LCPMapper *pLCPMap = NULL;
if (params.lensProf.lcpFile.length() && imgsrc->getMetaData()->getFocalLen() > 0) {
LCPProfile *pLCPProf = lcpStore->getProfile(params.lensProf.lcpFile);
@ -1134,6 +1126,18 @@ void ImProcCoordinator::getMonitorProfile (Glib::ustring& profile, RenderingInte
intent = monitorIntent;
}
void ImProcCoordinator::setSoftProofing (bool softProof, bool gamutCheck)
{
this->softProof = softProof;
this->gamutCheck = gamutCheck;
}
void ImProcCoordinator::getSoftProofing (bool &softProof, bool &gamutCheck)
{
softProof = this->softProof;
gamutCheck = this->gamutCheck;
}
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb)
{
@ -1262,7 +1266,7 @@ void ImProcCoordinator::startProcessing ()
if (!destroying) {
if (!updaterRunning) {
updaterThreadStart.lock ();
thread = nullptr;
thread = NULL;
updaterRunning = true;
updaterThreadStart.unlock ();

View File

@ -57,8 +57,8 @@ protected:
Imagefloat *oprevi;
LabImage *oprevl;
LabImage *nprevl;
Image8 *previmg;
Image8 *workimg;
Image8 *previmg; // displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not
Image8 *workimg; // internal image in output color space for analysis
CieImage *ncie;
ImageSource* imgsrc;
@ -73,8 +73,9 @@ protected:
ImProcFunctions ipf;
Glib::ustring monitorProfile;
RenderingIntent monitorIntent;
bool softProof;
bool gamutCheck;
int scale;
bool highDetailPreprocessComputed;
@ -90,7 +91,6 @@ protected:
LUTf hltonecurve;
LUTf shtonecurve;
LUTf tonecurve;
float chaut, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, nresi, highresi, chromina, sigma, lumema;
LUTf lumacurve;
LUTf chroma_acurve;
@ -179,6 +179,13 @@ protected:
MyMutex mProcessing;
ProcParams params;
// for optimization purpose, the output profile, output rendering intent and
// output BPC will trigger a regeneration of the profile on parameter change only
// and automatically
Glib::ustring lastOutputProfile;
RenderingIntent lastOutputIntent;
bool lastOutputBPC;
// members of the updater:
Glib::Thread* thread;
MyMutex updaterThreadStart;
@ -256,6 +263,8 @@ public:
void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent);
void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const;
void setSoftProofing (bool softProof, bool gamutCheck);
void getSoftProofing (bool &softProof, bool &gamutCheck);
bool updateTryLock ()
{
@ -327,7 +336,7 @@ public:
}
struct DenoiseInfoStore {
DenoiseInfoStore () : valid(false) {}
DenoiseInfoStore () : chM(0), max_r{}, max_b{}, ch_M{}, valid(false) {}
float chM;
float max_r[9];
float max_b[9];

View File

@ -61,14 +61,6 @@ ImProcFunctions::~ImProcFunctions ()
if (monitorTransform) {
cmsDeleteTransform (monitorTransform);
}
if (output2monitorTransform) {
cmsDeleteTransform (output2monitorTransform);
}
if (lab2outputTransform) {
cmsDeleteTransform (lab2outputTransform);
}
}
void ImProcFunctions::setScale (double iscale)
@ -76,24 +68,14 @@ void ImProcFunctions::setScale (double iscale)
scale = iscale;
}
void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent)
void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck)
{
// set up monitor transform
if (monitorTransform) {
cmsDeleteTransform (monitorTransform);
}
if (output2monitorTransform) {
cmsDeleteTransform (output2monitorTransform);
}
if (lab2outputTransform) {
cmsDeleteTransform (lab2outputTransform);
}
monitorTransform = nullptr;
output2monitorTransform = nullptr;
lab2outputTransform = nullptr;
#if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB
@ -101,20 +83,57 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, con
if (monitor) {
MyMutex::MyLock lcmsLock (*lcmsMutex);
cmsUInt32Number flags;
cmsHPROFILE iprof = cmsCreateLab4Profile(nullptr);
monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent,
cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision
Glib::ustring outputProfile;
bool softProofCreated = false;
if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) {
outputProfile = icm.output;
cmsHPROFILE jprof = iccStore->getProfile(outputProfile);
if (jprof) {
lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
if (softProof) {
cmsHPROFILE oprof = nullptr;
if(icm.gamma != "default" || icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8
GammaValues ga;
iccStore->getGammaArray(icm, ga);
oprof = iccStore->createGammaProfile (icm, ga);
}
else if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) {
if(icm.gamma != "default" || icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8
GammaValues ga;
iccStore->getGammaArray(icm, ga);
oprof = iccStore->createCustomGammaOutputProfile (icm, ga);
} else {
oprof = iccStore->getProfile(icm.output);
}
}
if (oprof) {
// NOCACHE is for thread safety, NOOPTIMIZE for precision
flags = cmsFLAGS_SOFTPROOFING | cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
if (icm.outputBPC) {
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
}
if (gamutCheck) {
flags |= cmsFLAGS_GAMUTCHECK;
}
monitorTransform = cmsCreateProofingTransform(
iprof, TYPE_Lab_FLT,
monitor, TYPE_RGB_8,
oprof,
monitorIntent, icm.outputIntent,
flags
);
if (monitorTransform) {
softProofCreated = true;
}
}
}
if (!softProofCreated) {
flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
if (settings->monitorBPC) {
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
}
monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, flags);
}
cmsCloseProfile(iprof);
@ -524,7 +543,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
xw2 = xwd;
yw2 = ywd;
zw2 = zwd;
} else if(params->colorappearance.wbmodel == "RawTCAT02") {
} else /*if(params->colorappearance.wbmodel == "RawTCAT02")*/ {
xw1 = xw; // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences
yw1 = yw;
zw1 = zw;
@ -1034,7 +1053,6 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
// if(!params->epd.enabled || !params->colorappearance.tonecie || !settings->autocielab){
// if(!params->epd.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){
int posl, posc;
double brli = 327.;
double chsacol = 327.;
int libr = 0;
@ -1065,9 +1083,10 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
jp = true;
if(pW != 1) { //only with improccoordinator
int posl;
if(libr == 1) {
posl = CLIP((int)(Q * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J
} else if(libr == 0) {
} else /*if(libr == 0)*/ {
posl = CLIP((int)(J * brli)); //327 for J
}
@ -1077,11 +1096,12 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
chropC = true;
if(pW != 1) { //only with improccoordinator
int posc;
if(colch == 0) {
posc = CLIP((int)(C * chsacol)); //450.0 approximative factor for s 320 for M
} else if(colch == 1) {
posc = CLIP((int)(s * chsacol));
} else if(colch == 2) {
} else /*if(colch == 2)*/ {
posc = CLIP((int)(M * chsacol));
}
@ -1303,7 +1323,6 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
ncie->C_p[i][j] = (ncie->M_p[i][j]) / co_e;
//show histogram in CIECAM mode (Q,J, M,s,C)
int posl, posc;
double brli = 327.;
double chsacol = 327.;
int libr = 0;
@ -1335,9 +1354,10 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
jp = true;
if(pW != 1) { //only with improccoordinator
int posl;
if(libr == 1) {
posl = CLIP((int)(ncie->Q_p[i][j] * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J
} else if(libr == 0) {
} else /*if(libr == 0)*/ {
posl = CLIP((int)(ncie->J_p[i][j] * brli)); //327 for J
}
@ -1347,12 +1367,13 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh
chropC = true;
if(pW != 1) { //only with improccoordinator
int posc;
if(colch == 0) {
posc = CLIP((int)(ncie->C_p[i][j] * chsacol)); //450.0 approximative factor for s 320 for M
} else if(colch == 1) {
sa_t = 100.f * sqrt(ncie->C_p[i][j] / ncie->Q_p[i][j]); //Q_p always > 0
posc = CLIP((int)(sa_t * chsacol));
} else if(colch == 2) {
} else /*if(colch == 2)*/ {
posc = CLIP((int)(ncie->M_p[i][j] * chsacol));
}
@ -1822,7 +1843,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
xw2 = xwd;
yw2 = ywd;
zw2 = zwd;
} else if(params->colorappearance.wbmodel == "RawTCAT02") {
} else /*if(params->colorappearance.wbmodel == "RawTCAT02")*/ {
xw1 = xw; // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences
yw1 = yw;
zw1 = zw;
@ -2680,8 +2701,6 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int
for (int i = 0; i < height; i++) { // update CIECAM with new values after tone-mapping
for (int j = 0; j < width; j++) {
float xx, yy, zz;
float x, y, z;
// if(epdEnabled) ncie->J_p[i][j]=(100.0f* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h);
if(epdEnabled) {
@ -4663,7 +4682,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
for (int i = 0; i < tH; i++) {
for (int j = 0; j < tW; j++) {
float h, s, l;
float r = tmpImage->r(i, j);
float g = tmpImage->g(i, j);
float b = tmpImage->b(i, j);
@ -6160,8 +6178,8 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu
if (settings->verbose) {
t2e.set();
printf("Color::AllMunsellLch (correction performed in %d usec):\n", t2e.etime(t1e));
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhuelum[0], MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum);
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%u\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%u\n", MunsDebugInfo->maxdhuelum[0], MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum);
}
delete MunsDebugInfo;

View File

@ -194,27 +194,9 @@ public:
};
double lumimul[3];
// float chau;
// float chred;
// float chblue;
// float maxchred;
// float maxchblue;
// float minchred;
// float minchblue;
// float resid;//used by noise_residual
// float residred;//used by noise_residual
// float residblue;//used by noise_residual
// int nb;
int nbresid;
float redresid;
float blueresid;
// float maxredresid;//used by noise_residual
// float maxblueresid;//used by noise_residual
// int comptlevel;
ImProcFunctions (const ProcParams* iparams, bool imultiThread = true)
: monitorTransform(nullptr), lab2outputTransform(nullptr), output2monitorTransform(nullptr), params(iparams), scale(1), multiThread(imultiThread) {}
: monitorTransform(NULL), lab2outputTransform(NULL), output2monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread), lumimul{} {}
~ImProcFunctions ();
void setScale (double iscale);
@ -223,7 +205,7 @@ public:
bool needsPCVignetting ();
void firstAnalysis (const Imagefloat* const working, const ProcParams &params, LUTu & vhist16);
void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent);
void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck);
void rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn );
@ -279,7 +261,7 @@ public:
void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0);
float *CompressDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed);
void ContrastResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params &cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx);
float *ContrastDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Contrast = nullptr);
float *ContrastDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Contrast = NULL);
void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1);
void EPDToneMapCIE(CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates = 0, int skip = 1);
@ -314,11 +296,11 @@ public:
void Aver(float * HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min);
void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg);
void calckoe(float ** WavCoeffs_LL, const struct cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr);
void calckoe(float ** WavCoeffs_LL, const struct cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = NULL);
void Median_Denoise( float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr);
void Median_Denoise( float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = NULL);
void RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve , const NoiseCurve & noiseCCurve , float &chaut, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &nresi, float &highresi);
void RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, const bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope);
void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false);
@ -335,7 +317,7 @@ public:
const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb);
void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge);
void ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir,
float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = nullptr, bool madCalculated = false);
float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = NULL, bool madCalculated = false);
void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int level,
int W_ab, int H_ab, int skip_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, bool autoch, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc,
float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread);
@ -361,16 +343,15 @@ public:
void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad);
void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom);
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma);
Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw);//without gamma ==>default
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm);
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, GammaValues *ga=NULL);
// CieImage *ciec;
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, const LCPMapper *pLCPMap = nullptr);
bool transCoord (int W, int H, const std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1, const LCPMapper *pLCPMap = nullptr);
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, const LCPMapper *pLCPMap = NULL);
bool transCoord (int W, int H, const std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1, const LCPMapper *pLCPMap = NULL);
static void getAutoExp (const LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh);
static double getAutoDistor (const Glib::ustring& fname, int thumb_size);
double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = nullptr);
double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL);
void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace);
void lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace);
};

View File

@ -32,6 +32,12 @@ namespace rtengine
extern const Settings* settings;
// Used in ImProcCoordinator::updatePreviewImage (rtengine/improccoordinator.cc)
// Crop::update (rtengine/dcrop.cc)
// Thumbnail::processImage (rtengine/rtthumbnail.cc)
//
// If monitorTransform, divide by 327.68 then apply monitorTransform (which can integrate soft-proofing)
// otherwise divide by 327.68, convert to xyz and apply the sRGB transform, before converting with gamma2curve
void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
{
if (monitorTransform) {
@ -61,21 +67,13 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
float* ra = lab->a[i];
float* rb = lab->b[i];
float fy, fx, fz, x_, y_, z_, LL;
for (int j = 0; j < W; j++) {
buffer[iy++] = rL[j] / 327.68f;
buffer[iy++] = ra[j] / 327.68f;
buffer[iy++] = rb[j] / 327.68f;
}
if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) {
AlignedBuffer<float> buf(3 * W);
cmsDoTransform (lab2outputTransform, buffer, buf.data, W);
cmsDoTransform (output2monitorTransform, buf.data, data + ix, W);
} else {
cmsDoTransform (monitorTransform, buffer, data + ix, W);
}
cmsDoTransform (monitorTransform, buffer, data + ix, W);
}
} // End of parallelization
} else {
@ -115,8 +113,18 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
}
}
Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma)
// Used in ImProcCoordinator::updatePreviewImage (rtengine/improccoordinator.cc)
// Crop::update (rtengine/dcrop.cc)
//
// Generate an Image8
//
// If output profile used, divide by 327.68 then apply the "profile" profile (eventually with a standard gamma)
// otherwise divide by 327.68, convert to xyz and apply the RGB transform, before converting with gamma2curve
Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm)
{
//gamutmap(lab);
if (cx < 0) {
cx = 0;
@ -135,9 +143,22 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
}
Image8* image = new Image8 (cw, ch);
Glib::ustring profile;
cmsHPROFILE oprof = iccStore->getProfile (profile);
bool standard_gamma;
if(settings->HistogramWorking) {
profile = icm.working;
standard_gamma = true;
} else {
profile = icm.output;
if (icm.output.empty() || icm.output == ColorManagementParams::NoICMString) {
profile = "sRGB";
}
standard_gamma = false;
}
if (oprof) {
cmsHPROFILE oprofG = oprof;
@ -145,11 +166,16 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
oprofG = ICCStore::makeStdGammaProfile(oprof);
}
cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
if (icm.outputBPC) {
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
printf("lab2rgb / bpc=true\n");
}
else printf("lab2rgb / bpc=false\n");
lcmsMutex->lock ();
cmsHPROFILE hLab = cmsCreateLab4Profile(nullptr);
cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent,
cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety
cmsCloseProfile(hLab);
cmsHPROFILE LabIProf = cmsCreateLab4Profile(NULL);
cmsHTRANSFORM hTransform = cmsCreateTransform (LabIProf, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, icm.outputIntent, flags); // NOCACHE is important for thread safety
cmsCloseProfile(LabIProf);
lcmsMutex->unlock ();
unsigned char *data = image->data;
@ -220,8 +246,24 @@ 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, RenderingIntent intent, bool bw)
/** @brief Convert the final Lab image to the output RGB color space
*
* Used in processImage (rtengine/simpleprocess.cc)
*
* Provide a pointer to a 7 floats array for "ga" (uninitialized ; this array will be filled with the gamma values) if you want
* to use the custom gamma scenario. Thoses gamma values will correspond to the ones of the chosen standard output profile
* (Prophoto if non standard output profile given)
*
* If "ga" is NULL, then we're considering standard gamma with the chosen output profile.
*
* Generate an Image16
*
* If a custom gamma profile can be created, divide by 327.68, convert to xyz and apply the custom gamma transform
* otherwise divide by 327.68, convert to xyz and apply the sRGB transform, before converting with gamma2curve
*/
Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, GammaValues *ga)
{
if (cx < 0) {
@ -241,49 +283,37 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
}
Image16* image = new Image16 (cw, ch);
cmsHPROFILE oprof = iccStore->getProfile (profile);
cmsHPROFILE oprof = NULL;
if (ga) {
lcmsMutex->lock ();
iccStore->getGammaArray(icm, *ga);
oprof = iccStore->createGammaProfile(icm, *ga);
lcmsMutex->unlock ();
printf("iccStore->createGammaProfile(icm, *ga);\n");
} else {
oprof = iccStore->getProfile (icm.output);
printf("iccStore->getProfile (%s);\n", icm.output.c_str());
}
if (oprof) {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#endif
for (int i = cy; i < cy + ch; i++) {
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 x_, y_, z_;
Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_);
xa[j - cx] = float2uint16range(x_);
ya[j - cx] = float2uint16range(y_);
za[j - cx] = float2uint16range(z_);
if(bw && y_ < 65535.f ) { //force Bw value and take highlight into account
xa[j - cx] = float2uint16range(y_ * Color::D50x);
za[j - cx] = float2uint16range(y_ * Color::D50z);
}
}
cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
if (icm.outputBPC) {
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
printf("lab2rgb16 / icm.outputBPC=true / outputIntent=%d\n", icm.outputIntent);
}
cmsHPROFILE iprof = iccStore->getXYZProfile ();
else printf("lab2rgb16 / icm.outputBPC=false / outputIntent=%d\n", icm.outputIntent);
lcmsMutex->lock ();
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
cmsHPROFILE iprof = cmsCreateLab4Profile(nullptr);
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, oprof, TYPE_RGB_16, icm.outputIntent, flags);
lcmsMutex->unlock ();
image->ExecCMSTransform(hTransform);
image->ExecCMSTransform(hTransform, *lab, cx, cy);
cmsDeleteTransform(hTransform);
} else {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#pragma omp parallel for schedule(dynamic,16) if (multiThread)
#endif
for (int i = cy; i < cy + ch; i++) {
float R, G, B;
float* rL = lab->L[i];
@ -297,279 +327,10 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
float fz = fy - (0.005f * rb[j]) / 327.68f;
float LL = rL[j] / 327.68f;
float x_ = 65535.0f * (float) Color::f2xyz(fx) * Color::D50x;
float x_ = 65535.0f * Color::f2xyz(fx) * Color::D50x;
//float y_ = 65535.0 * Color::f2xyz(fy);
float z_ = 65535.0f * (float) Color::f2xyz(fz) * Color::D50z;
float y_ = (LL > Color::epskap) ? (float) 65535.0f * fy * fy * fy : 65535.0f * LL / Color::kappa;
Color::xyz2srgb(x_, y_, z_, R, G, B);
image->r(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(R)];
image->g(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(G)];
image->b(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(B)];
}
}
}
return image;
}
// for gamma options (BT709...sRGB linear...)
Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw)
{
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);
float p1, p2, p3, p4, p5, p6; //primaries
double pwr;
double ts;
ga6 = 0.0;
pwr = 1.0 / gampos;
ts = slpos;
int t50;
int select_temp = 1; //5003K
const double eps = 0.000000001; // not divide by zero
//primaries for 7 working profiles ==> output profiles
// eventually to adapt primaries if RT used special profiles !
if (profi == "WideGamut") {
p1 = 0.7350; //Widegamut primaries
p2 = 0.2650;
p3 = 0.1150;
p4 = 0.8260;
p5 = 0.1570;
p6 = 0.0180;
select_temp = 1;
} else if (profi == "Adobe RGB") {
p1 = 0.6400; //Adobe primaries
p2 = 0.3300;
p3 = 0.2100;
p4 = 0.7100;
p5 = 0.1500;
p6 = 0.0600;
select_temp = 2;
} else if (profi == "sRGB") {
p1 = 0.6400; // sRGB primaries
p2 = 0.3300;
p3 = 0.3000;
p4 = 0.6000;
p5 = 0.1500;
p6 = 0.0600;
select_temp = 2;
} else if (profi == "BruceRGB") {
p1 = 0.6400; // Bruce primaries
p2 = 0.3300;
p3 = 0.2800;
p4 = 0.6500;
p5 = 0.1500;
p6 = 0.0600;
select_temp = 2;
} else if (profi == "Beta RGB") {
p1 = 0.6888; // Beta primaries
p2 = 0.3112;
p3 = 0.1986;
p4 = 0.7551;
p5 = 0.1265;
p6 = 0.0352;
select_temp = 1;
} else if (profi == "BestRGB") {
p1 = 0.7347; // Best primaries
p2 = 0.2653;
p3 = 0.2150;
p4 = 0.7750;
p5 = 0.1300;
p6 = 0.0350;
select_temp = 1;
} else if (profi == "Rec2020") {
p1 = 0.7080; // Rec2020 primaries
p2 = 0.2920;
p3 = 0.1700;
p4 = 0.7970;
p5 = 0.1310;
p6 = 0.0460;
select_temp = 2;
} else {
p1 = 0.7347; //ProPhoto and default primaries
p2 = 0.2653;
p3 = 0.1596;
p4 = 0.8404;
p5 = 0.0366;
p6 = 0.0001;
select_temp = 1;
}
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.22; //BT709 2.2 4.5 - my prefered as D.Coffin
ga1 = 0.909995;
ga2 = 0.090005;
ga3 = 0.222222;
ga4 = 0.081071;
ga5 = 0.0;
} else if (gam == "sRGB_g2.4_s12.92") {
ga0 = 2.40; //sRGB 2.4 12.92 - RT default as Lightroom
ga1 = 0.947858;
ga2 = 0.052142;
ga3 = 0.077399;
ga4 = 0.039293;
ga5 = 0.0;
} else if (gam == "High_g1.3_s3.35") {
ga0 = 1.3 ; //for high dynamic images
ga1 = 0.998279;
ga2 = 0.001721;
ga3 = 0.298507;
ga4 = 0.005746;
ga5 = 0.0;
} else if (gam == "Low_g2.6_s6.9") {
ga0 = 2.6 ; //gamma 2.6 variable : for low contrast images
ga1 = 0.891161;
ga2 = 0.108839;
ga3 = 0.144928;
ga4 = 0.076332;
ga5 = 0.0;
} else if (gam == "linear_g1.0") {
ga0 = 1.0; //gamma=1 linear : for high dynamic images (cf : D.Coffin...)
ga1 = 1.;
ga2 = 0.;
ga3 = 1. / eps;
ga4 = 0.;
ga5 = 0.0;
} else if (gam == "standard_g2.2") {
ga0 = 2.2; //gamma=2.2 (as gamma of Adobe, Widegamut...)
ga1 = 1.;
ga2 = 0.;
ga3 = 1. / eps;
ga4 = 0.;
ga5 = 0.0;
} else if (gam == "standard_g1.8") {
ga0 = 1.8; //gamma=1.8 (as gamma of Prophoto)
ga1 = 1.;
ga2 = 0.;
ga3 = 1. / eps;
ga4 = 0.;
ga5 = 0.0;
}
} else { //free gamma selected
if(slpos == 0) {
slpos = eps;
}
double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5; //gamma parameters
int mode = 0, imax = 0;
Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
ga4 = g_a3 * ts;
ga0 = gampos;
ga1 = 1. / (1.0 + g_a4);
ga2 = g_a4 / (1.0 + g_a4);
ga3 = 1. / slpos;
ga5 = 0.0;
}
if(select_temp == 1) {
t50 = 5003; // for Widegamut, Prophoto Best, Beta D50
} else if (select_temp == 2) {
t50 = 6504; // for sRGB, AdobeRGB, Bruce Rec2020 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] = ga6;
// 7 parameters for smoother curves
cmsWhitePointFromTemp(&xyD, t50);
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(nullptr, 5, Parameters);//5 = more smoother than 4
cmsHPROFILE oprofdef = cmsCreateRGBProfileTHR(nullptr, &xyD, &Primaries, GammaTRC); //oprofdef becomes Outputprofile
cmsFreeToneCurve(GammaTRC[0]);
if (oprofdef) {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#endif
for (int i = cy; i < cy + ch; i++) {
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 x_, y_, z_;
Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_);
xa[j - cx] = float2uint16range(x_);
ya[j - cx] = float2uint16range(y_);
za[j - cx] = float2uint16range(z_);
if(bw && y_ < 65535.f) { //force Bw value and take highlight into account
xa[j - cx] = float2uint16range(y_ * Color::D50x);
za[j - cx] = float2uint16range(y_ * Color::D50z);
}
}
}
cmsHPROFILE iprof = iccStore->getXYZProfile ();
lcmsMutex->lock ();
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
lcmsMutex->unlock ();
image->ExecCMSTransform(hTransform);
cmsDeleteTransform(hTransform);
} else {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#endif
for (int i = cy; i < cy + ch; i++) {
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.0086206897f * rL[j]) / 327.68f + 0.1379310345f; // (L+16)/116
float fx = (0.002f * ra[j]) / 327.68f + fy;
float fz = fy - (0.005f * rb[j]) / 327.68f;
float LL = rL[j] / 327.68f;
float x_ = 65535.0f * (float) Color::f2xyz(fx) * Color::D50x;
//float y_ = 65535.0 * Color::f2xyz(fy);
float z_ = 65535.0f * (float) Color::f2xyz(fz) * Color::D50z;
float y_ = (LL > Color::epskap) ? (float) 65535.0 * fy * fy * fy : 65535.0f * LL / Color::kappa;
float z_ = 65535.0f * Color::f2xyz(fz) * Color::D50z;
float y_ = (LL > (float)Color::epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / (float)Color::kappa;
Color::xyz2srgb(x_, y_, z_, R, G, B);

View File

@ -140,8 +140,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
{
if (deh.enabled) {//enabled
float mean, stddv, maxtr, mintr;
float delta;
float maxtr, mintr;
constexpr float eps = 2.f;
bool useHsl = deh.retinexcolorspace == "HSLLOG";
bool useHslLin = deh.retinexcolorspace == "HSLLIN";
@ -551,8 +550,8 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
delete [] buffer;
delete [] srcBuffer;
mean = 0.f;
stddv = 0.f;
float mean = 0.f;
float stddv = 0.f;
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
@ -658,7 +657,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
maxi = maxtr - epsil;
}
delta = maxi - mini;
float delta = maxi - mini;
//printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr);
if ( !delta ) {
@ -691,7 +690,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
// I call mean_stddv2 instead of mean_stddv ==> logBetaGain
mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr);
float asig, bsig, amax, bmax, amin, bmin;
float asig = 0.f, bsig = 0.f, amax = 0.f, bmax = 0.f, amin = 0.f, bmin = 0.f;
if (dehagaintransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve
asig = 0.166666f / stddv;

View File

@ -744,7 +744,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
printf(" Gamut: G1negat=%iiter G165535=%iiter G2negsat=%iiter G265535=%iiter\n", negat, moreRGB, negsat, moresat);
if (MunsDebugInfo) {
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
}
}

View File

@ -39,6 +39,7 @@
#include "opthelper.h"
#include "median.h"
#include "EdgePreservingDecomposition.h"
#include "iccstore.h"
#ifdef _OPENMP
#include <omp.h>

View File

@ -361,7 +361,7 @@ int fscanf (IMFILE* f, const char* s ...)
// of file data and vsscanf() won't tell us how many characters that
// were parsed. However, only dcraw.cc code use it and only for "%f" and
// "%d", so we make a dummy fscanf here just to support dcraw case.
char buf[50], *endptr;
char buf[50], *endptr = nullptr;
int copy_sz = f->size - f->pos;
if (copy_sz > sizeof(buf)) {
@ -377,6 +377,7 @@ int fscanf (IMFILE* f, const char* s ...)
int i = strtol(buf, &endptr, 10);
if (endptr == buf) {
va_end (ap);
return 0;
}
@ -386,6 +387,7 @@ int fscanf (IMFILE* f, const char* s ...)
float f = strtof(buf, &endptr);
if (endptr == buf) {
va_end (ap);
return 0;
}

View File

@ -37,7 +37,7 @@ public:
: fname(fn), isRaw(iR), initialImage(nullptr), pparams(pp) {}
ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp)
: fname(""), initialImage(iImage), pparams(pp)
: fname(""), isRaw(true), initialImage(iImage), pparams(pp)
{
iImage->increaseRef();
}

View File

@ -469,6 +469,7 @@ enum ProcEvent {
EvcbdlMethod = 439,
EvRetinexgaintransmission = 440,
EvLskal = 441,
EvOBPCompens = 442,
NUMOFEVENTS
};

View File

@ -927,6 +927,7 @@ void ColorManagementParams::setDefaults()
working = "ProPhoto";
output = "RT_sRGB";
outputIntent = RI_RELATIVE;
outputBPC = true;
gamma = "default";
gampos = 2.22;
slpos = 4.5;
@ -2662,6 +2663,10 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b
keyFile.set_string ("Color Management", "OutputProfileIntent", intent);
}
if (!pedited || pedited->icm.outputBPC) {
keyFile.set_boolean ("Color Management", "OutputBPC", icm.outputBPC);
}
if (!pedited || pedited->icm.gamma) {
keyFile.set_string ("Color Management", "Gammafree", icm.gamma);
}
@ -5921,6 +5926,14 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited)
}
}
if (keyFile.has_key ("Color Management", "OutputBPC")) {
icm.outputBPC = keyFile.get_boolean ("Color Management", "OutputBPC");
if (pedited) {
pedited->icm.outputBPC = true;
}
}
if (keyFile.has_key ("Color Management", "Gammafree")) {
icm.gamma = keyFile.get_string ("Color Management", "Gammafree");

View File

@ -65,9 +65,7 @@ public:
protected:
bool initEq1;
bool _isDouble;
#ifndef NDEBUG
unsigned int part[5];
#endif
public:
Threshold (T bottom, T top, bool startAtOne)
{
@ -969,6 +967,7 @@ public:
Glib::ustring working;
Glib::ustring output;
RenderingIntent outputIntent;
bool outputBPC;
static const Glib::ustring NoICMString;
Glib::ustring gamma;

View File

@ -20,11 +20,12 @@ namespace rtengine
extern const Settings* settings;
RawImage::RawImage( const Glib::ustring &name )
: data(nullptr)
: data(NULL)
, prefilters(0)
, filename(name)
, profile_data(nullptr)
, allocation(nullptr)
, profile_data(NULL)
, allocation(NULL)
, rotate_deg(0)
{
memset(maximum_c4, 0, sizeof(maximum_c4));
RT_matrix_from_constant = 0;
@ -44,22 +45,22 @@ RawImage::~RawImage()
if(allocation) {
delete [] allocation;
allocation = nullptr;
allocation = NULL;
}
if(float_raw_image) {
delete [] float_raw_image;
float_raw_image = nullptr;
float_raw_image = NULL;
}
if(data) {
delete [] data;
data = nullptr;
data = NULL;
}
if(profile_data) {
delete [] profile_data;
profile_data = nullptr;
profile_data = NULL;
}
}
@ -400,9 +401,9 @@ skip_block:
int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistener, double progressRange)
{
ifname = filename.c_str();
image = nullptr;
image = NULL;
verbose = settings->verbose;
oprof = nullptr;
oprof = NULL;
ifp = gfopen (ifname); // Maps to either file map or direct fopen
@ -414,18 +415,18 @@ int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistene
thumb_length = 0;
thumb_offset = 0;
thumb_load_raw = nullptr;
thumb_load_raw = 0;
use_camera_wb = 0;
highlight = 1;
half_size = 0;
raw_image = nullptr;
raw_image = 0;
//***************** Read ALL raw file info
identify ();
if (!is_raw) {
fclose(ifp);
ifp = nullptr;
ifp = NULL;
if (plistener) {
plistener->setProgress(1.0 * progressRange);
@ -531,7 +532,7 @@ int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistene
crop_masked_pixels();
free (raw_image);
raw_image = nullptr;
raw_image = NULL;
} else {
if (cc && cc->has_rawCrop()) { // foveon images
int lm, tm, w, h;
@ -643,7 +644,7 @@ int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistene
if ( closeFile ) {
fclose(ifp);
ifp = nullptr;
ifp = NULL;
}
if (plistener) {
@ -656,7 +657,7 @@ int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistene
float** RawImage::compress_image()
{
if( !image ) {
return nullptr;
return NULL;
}
if (isBayer() || isXtrans()) {
@ -699,7 +700,7 @@ float** RawImage::compress_image()
}
delete [] float_raw_image;
float_raw_image = nullptr;
float_raw_image = NULL;
} else if (filters != 0 && !isXtrans()) {
#pragma omp parallel for
@ -733,7 +734,7 @@ float** RawImage::compress_image()
}
free(image); // we don't need this anymore
image = nullptr;
image = NULL;
return data;
}
@ -782,7 +783,7 @@ void RawImage::getRgbCam (float rgbcam[3][4])
bool
RawImage::get_thumbSwap() const
{
return (order == 0x4949) == (ntohs(0x1234) == 0x1234);
return ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) ? true : false;
}
} //namespace rtengine

View File

@ -423,25 +423,49 @@ extern const Settings* settings;
RawImageSource::RawImageSource ()
: ImageSource()
, plistener(nullptr)
, W(0), H(0)
, plistener(NULL)
, border(4)
, ri(nullptr)
, cache(nullptr)
, ri(NULL)
, cache(NULL)
, rawData(0, 0)
, green(0, 0)
, red(0, 0)
, blue(0, 0)
, lc00(0.0)
, lc01(0.0)
, lc02(0.0)
, lc10(0.0)
, lc11(0.0)
, lc12(0.0)
, lc20(0.0)
, lc21(0.0)
, lc22(0.0)
, hlmax{}
, clmax{}
, chmax{}
, scale_mul{}
, c_black{}
, c_white{}
, cblacksom{}
, ref_pre_mul{}
, refwb_red(0.0)
, refwb_green(0.0)
, refwb_blue(0.0)
, rgb_cam{}
, cam_rgb{}
, xyz_cam{}
, cam_xyz{}
, fuji(false)
, d1x(false)
, initialGain(0.0)
, camInitialGain(0.0)
, defGain(0.0)
, threshold(0)
{
hrmap[0] = nullptr;
hrmap[1] = nullptr;
hrmap[2] = nullptr;
//needhr = NULL;
//hpmap = NULL;
camProfile = nullptr;
embProfile = nullptr;
camProfile = NULL;
embProfile = NULL;
rgbSourceModified = false;
hlmax[0] = hlmax[1] = hlmax[2] = hlmax[3] = 0.f;
clmax[0] = clmax[1] = clmax[2] = clmax[3] = 0.f;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -462,13 +486,6 @@ RawImageSource::~RawImageSource ()
delete [] cache;
}
if (hrmap[0] != nullptr) {
int dh = H / HR_SCALE;
freeJaggedArray<float>(hrmap[0]);
freeJaggedArray<float>(hrmap[1]);
freeJaggedArray<float>(hrmap[2]);
}
if (camProfile) {
cmsCloseProfile (camProfile);
}
@ -872,12 +889,12 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, ColorTemp &wb, DCPProfile::ApplyState &as)
{
DCPProfile *dcpProf = nullptr;
DCPProfile *dcpProf = NULL;
cmsHPROFILE dummy;
findInputProfile(cmp.input, nullptr, (static_cast<const ImageData*>(getMetaData()))->getCamera(), &dcpProf, dummy);
findInputProfile(cmp.input, NULL, (static_cast<const ImageData*>(getMetaData()))->getCamera(), &dcpProf, dummy);
if (dcpProf == nullptr) {
return nullptr;
if (dcpProf == NULL) {
return NULL;
}
dcpProf->setStep2ApplyState(cmp.working, cmp.toneCurve, cmp.applyLookTable, cmp.applyBaselineExposureOffset, as);
@ -1453,10 +1470,9 @@ void RawImageSource::getFullSize (int& w, int& h, int tr)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void RawImageSource::getSize (int tran, PreviewProps pp, int& w, int& h)
void RawImageSource::getSize (PreviewProps pp, int& w, int& h)
{
tran = defTransform (tran);
w = pp.w / pp.skip + (pp.w % pp.skip > 0);
h = pp.h / pp.skip + (pp.h % pp.skip > 0);
}
@ -1629,7 +1645,7 @@ int RawImageSource::load (const Glib::ustring &fname, bool batch)
plistener->setProgress (1.0);
}
plistener = nullptr; // This must be reset, because only load() is called through progressConnector
plistener = NULL; // This must be reset, because only load() is called through progressConnector
t2.set();
if( settings->verbose ) {
@ -1648,7 +1664,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
t1.set();
Glib::ustring newDF = raw.dark_frame;
RawImage *rid = nullptr;
RawImage *rid = NULL;
if (!raw.df_autoselect) {
if( !raw.dark_frame.empty()) {
@ -1686,7 +1702,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
}
//FLATFIELD start
RawImage *rif = nullptr;
RawImage *rif = NULL;
if (!raw.ff_AutoSelect) {
if( !raw.ff_file.empty()) {
@ -1697,7 +1713,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
}
bool hasFlatField = (rif != nullptr);
bool hasFlatField = (rif != NULL);
if( hasFlatField && settings->verbose) {
printf( "Flat Field Correction:%s\n", rif->get_filename().c_str());
@ -1723,7 +1739,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
}
// If darkframe selected, correct hotpixels found on darkframe
bp = nullptr;
bp = 0;
if( raw.df_autoselect ) {
bp = dfm.getHotPixels(idata->getMake(), idata->getModel(), idata->getISOSpeed(), idata->getShutterSpeed(), idata->getDateTimeAsTS());
@ -1973,7 +1989,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
} else if(retinexParams.gammaretinex == "hig") {
retinexgamtab = &(Color::gammatab_145_3);
} else if(retinexParams.gammaretinex == "fre") {
double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5;
GammaValues g_a;
double pwr = 1.0 / retinexParams.gam;
double gamm = retinexParams.gam;
double ts = retinexParams.slope;
@ -1984,21 +2000,21 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
}
int mode = 0, imax = 0;
Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope
Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope
// printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4);
double start;
double add;
if(gamm2 < 1.) {
start = g_a2;
add = g_a4;
start = g_a[2];
add = g_a[4];
} else {
start = g_a3;
add = g_a4;
start = g_a[3];
add = g_a[4];
}
double mul = 1. + g_a4;
double mul = 1. + g_a[4];
lutTonereti(65536);
@ -2123,7 +2139,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar
#endif
for (; j < W - border; j++) {
float H, S, L;
float L;
//rgb=>lab
Color::rgb2hslfloat(red[i][j], green[i][j], blue[i][j], conversionBuffer[0][i - border][j - border], conversionBuffer[1][i - border][j - border], L);
L *= 32768.f;
@ -2245,7 +2261,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
} else if(deh.gammaretinex == "hig") {
retinexigamtab = &(Color::igammatab_145_3);
} else if(deh.gammaretinex == "fre") {
double g_a0, g_a1, g_a2, g_a3, g_a4, g_a5;
GammaValues g_a;
double pwr = 1.0 / deh.gam;
double gamm = deh.gam;
double gamm2 = gamm;
@ -2256,18 +2272,18 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
std::swap(pwr, gamm);
}
Color::calcGamma(pwr, ts, mode, imax, g_a0, g_a1, g_a2, g_a3, g_a4, g_a5); // call to calcGamma with selected gamma and slope
Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope
double mul = 1. + g_a4;
double mul = 1. + g_a[4];
double add;
double start;
if(gamm2 < 1.) {
start = g_a3;
add = g_a3;
start = g_a[3];
add = g_a[3];
} else {
add = g_a4;
start = g_a2;
add = g_a[4];
start = g_a[2];
}
// printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4);
@ -2296,7 +2312,6 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
float **temp = conversionBuffer[2]; // one less dereference
LUTf dLcurve;
LUTu hist16RET;
float val;
if(dehacontlutili && histLRETI) {
hist16RET(32768);
@ -2305,7 +2320,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
dLcurve(32768);
}
FlatCurve* chcurve = nullptr;//curve c=f(H)
FlatCurve* chcurve = NULL;//curve c=f(H)
bool chutili = false;
if (deh.enabled && deh.retinexMethod == "highli") {
@ -2314,7 +2329,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
if (!chcurve || chcurve->isIdentity()) {
if (chcurve) {
delete chcurve;
chcurve = nullptr;
chcurve = NULL;
}
} else {
chutili = true;
@ -2369,7 +2384,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
// hist16RET.compressTo(histLRETI);
// also remove declaration and init of dLcurve some lines above then and finally remove this comment :)
for (int i = 0; i < 32768; i++) {
val = (double)i / 32767.0;
float val = (double)i / 32767.0;
dLcurve[i] = val;
}
@ -2393,14 +2408,8 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
for (; j < W - border; j++) {
float valp;
// if(chutili) { // c=f(H)
{
valp = float((chcurve->getVal(conversionBuffer[3][i - border][j - border]) - 0.5f));
conversionBuffer[1][i - border][j - border] *= (1.f + 2.f * valp);
}
// }
float valp = (chcurve->getVal(conversionBuffer[3][i - border][j - border]) - 0.5f);
conversionBuffer[1][i - border][j - border] *= (1.f + 2.f * valp);
}
}
@ -2629,7 +2638,7 @@ void RawImageSource::flushRawData()
{
if(cache) {
delete [] cache;
cache = nullptr;
cache = 0;
}
if (rawData) {
@ -2822,7 +2831,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
if(raw.ff_AutoClipControl) {
// determine maximum calculated value to avoid clipping
int clipControlGui = 0;
// int clipControlGui = 0;
float maxval = 0.f;
// xtrans files have only one black level actually, so we can simplify the code a bit
#ifdef _OPENMP
@ -2857,7 +2866,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
// there's only one white level for xtrans
if(maxval + black[0] > ri->get_white(0)) {
limitFactor = ri->get_white(0) / (maxval + black[0]);
clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
// clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
}
} else {
limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f);
@ -3696,9 +3705,9 @@ void RawImageSource::getProfilePreprocParams(cmsHPROFILE in, float& gammaFac, fl
copyright[0] = 0;
if (cmsGetProfileInfoASCII(in, cmsInfoCopyright, cmsNoLanguage, cmsNoCountry, copyright, 256) > 0) {
if (strstr(copyright, "Phase One") != nullptr) {
if (strstr(copyright, "Phase One") != NULL) {
gammaFac = 0.55556; // 1.8
} else if (strstr(copyright, "Nikon Corporation") != nullptr) {
} else if (strstr(copyright, "Nikon Corporation") != NULL) {
gammaFac = 0.5;
lineFac = -0.4;
lineSum = 1.35; // determined in reverse by measuring NX an RT developed colorchecker PNGs
@ -3767,7 +3776,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
return;
}
if (dcpProf != nullptr) {
if (dcpProf != NULL) {
// DCP processing
const DCPProfile::Triple pre_mul_row = {
pre_mul[0],
@ -3784,7 +3793,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
return;
}
if (in == nullptr) {
if (in == NULL) {
// use default camprofile, supplied by dcraw
// in this case we avoid using the slllllooooooowwww lcms
@ -3860,10 +3869,10 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
camera_icc_type = CAMERA_ICC_TYPE_GENERIC;
// Note: order the identification with the most detailed matching first since the more general ones may also match the more detailed
if ((strstr(copyright, "Leaf") != nullptr ||
strstr(copyright, "Phase One A/S") != nullptr ||
strstr(copyright, "Kodak") != nullptr ||
strstr(copyright, "Creo") != nullptr) &&
if ((strstr(copyright, "Leaf") != NULL ||
strstr(copyright, "Phase One A/S") != NULL ||
strstr(copyright, "Kodak") != NULL ||
strstr(copyright, "Creo") != NULL) &&
(strstr(description, "LF2 ") == description ||
strstr(description, "LF3 ") == description ||
strstr(description, "LeafLF2") == description ||
@ -3872,9 +3881,9 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
strstr(description, "MamiyaLF2") == description ||
strstr(description, "MamiyaLF3") == description)) {
camera_icc_type = CAMERA_ICC_TYPE_LEAF;
} else if (strstr(copyright, "Phase One A/S") != nullptr) {
} else if (strstr(copyright, "Phase One A/S") != NULL) {
camera_icc_type = CAMERA_ICC_TYPE_PHASE_ONE;
} else if (strstr(copyright, "Nikon Corporation") != nullptr) {
} else if (strstr(copyright, "Nikon Corporation") != NULL) {
camera_icc_type = CAMERA_ICC_TYPE_NIKON;
}
}
@ -3893,7 +3902,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
transform_via_pcs_lab = true;
separate_pcs_lab_highlights = true;
// We transform to Lab because we can and that we avoid getting an unnecessary unmatched gamma conversion which we would need to revert.
hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, nullptr, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, NULL, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
@ -3917,14 +3926,14 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
lcmsMutex->unlock ();
if (hTransform == nullptr) {
if (hTransform == NULL) {
// Fallback: create transform from camera profile. Should not happen normally.
lcmsMutex->lock ();
hTransform = cmsCreateTransform (camprofile, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE );
lcmsMutex->unlock ();
}
TMatrix toxyz, torgb;
TMatrix toxyz = {}, torgb = {};
if (!working_space_is_prophoto) {
toxyz = iccStore->workingSpaceMatrix ("ProPhoto");
@ -4127,8 +4136,8 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
// Determine RAW input and output profiles. Returns TRUE on success
bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in)
{
in = nullptr; // cam will be taken on NULL
*dcpProf = nullptr;
in = NULL; // cam will be taken on NULL
*dcpProf = NULL;
if (inProfile == "(none)") {
return false;
@ -4140,7 +4149,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed
// DCPs have higher quality, so use them first
*dcpProf = DCPStore::getInstance()->getStdProfile(camName);
if (*dcpProf == nullptr) {
if (*dcpProf == NULL) {
in = iccStore->getStdProfile(camName);
}
} else if (inProfile != "(camera)" && inProfile != "") {
@ -4154,7 +4163,7 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed
*dcpProf = DCPStore::getInstance()->getProfile(normalName);
}
if (*dcpProf == nullptr) {
if (*dcpProf == NULL) {
in = iccStore->getProfile (inProfile);
}
}
@ -4202,7 +4211,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi
for (int col = 0; col < width; col++) {
float rgb[ColorCount], cam[2][ColorCount], lab[2][ColorCount], sum[2], chratio, lratio = 0;
float L, C, H, Lfrac;
float L, C, H;
// Copy input pixel to rgb so it's easier to access in loops
rgb[0] = rin[col];
@ -4290,7 +4299,7 @@ void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int wi
bin[col] = L + H / 3.0;
if ((L = (rin[col] + gin[col] + bin[col]) / 3) > desatpt) {
Lfrac = max(0.0f, (maxave - L) / (maxave - desatpt));
float Lfrac = max(0.0f, (maxave - L) / (maxave - desatpt));
C = Lfrac * 1.732050808 * (rin[col] - gin[col]);
H = Lfrac * (2 * bin[col] - rin[col] - gin[col]);
rin[col] = L - H / 6.0 + C / 3.464101615;
@ -4887,11 +4896,11 @@ ColorTemp RawImageSource::getSpotWB (std::vector<Coord2D> &red, std::vector<Coor
if (ri->getSensorType() != ST_BAYER) {
if(ri->getSensorType() == ST_FUJI_XTRANS) {
int d[9][2] = {{0, 0}, { -1, -1}, { -1, 0}, { -1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
double rloc, gloc, bloc;
int rnbrs, gnbrs, bnbrs;
for (size_t i = 0; i < red.size(); i++) {
transformPosition (red[i].x, red[i].y, tran, x, y);
double rloc, gloc, bloc;
int rnbrs, gnbrs, bnbrs;
rloc = gloc = bloc = rnbrs = gnbrs = bnbrs = 0;
for (int k = 0; k < 9; k++) {
@ -4959,11 +4968,11 @@ ColorTemp RawImageSource::getSpotWB (std::vector<Coord2D> &red, std::vector<Coor
} else {
int d[9][2] = {{0, 0}, { -1, -1}, { -1, 0}, { -1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
double rloc, gloc, bloc;
int rnbrs, gnbrs, bnbrs;
for (size_t i = 0; i < red.size(); i++) {
transformPosition (red[i].x, red[i].y, tran, x, y);
double rloc, gloc, bloc;
int rnbrs, gnbrs, bnbrs;
rloc = gloc = bloc = rnbrs = gnbrs = bnbrs = 0;
for (int k = 0; k < 9; k++) {

View File

@ -63,17 +63,11 @@ protected:
bool fuji;
bool d1x;
int border;
//char** hpmap;
float** hrmap[3]; // for color propagation
char** needhr; // for color propagation
int max_3[3];
float chmax[4], hlmax[4], clmax[4];
double initialGain; // initial gain calculated after scale_colors
double camInitialGain;
double defGain;
bool full;
cmsHPROFILE camProfile;
cmsHPROFILE embProfile;
bool rgbSourceModified;
RawImage* ri; // Copy of raw pixels, NOT corrected for initial gain, blackpoint etc.
@ -157,7 +151,7 @@ public:
}
void getFullSize (int& w, int& h, int tr = TR_NONE);
void getSize (int tran, PreviewProps pp, int& w, int& h);
void getSize (PreviewProps pp, int& w, int& h);
int getRotateDegree() const
{
return ri->get_rotateDegree();

View File

@ -140,7 +140,7 @@ inline void RawImageSource::interpolate_row_g (float* agh, float* agv, int i)
inline void RawImageSource::interpolate_row_rb (float* ar, float* ab, float* pg, float* cg, float* ng, int i)
{
if (ri->ISRED(i, 0) || ri->ISRED(i, 1)) {
if ((ri->ISRED(i, 0) || ri->ISRED(i, 1)) && pg && ng) {
// RGRGR or GRGRGR line
for (int j = 0; j < W; j++) {
if (ri->ISRED(i, j)) {
@ -172,7 +172,7 @@ inline void RawImageSource::interpolate_row_rb (float* ar, float* ab, float* pg,
b = cg[j] + b / n;
ab[j] = b;
} else {
} else if(ng && pg) {
// linear R-G interp. horizontally
int r;
@ -199,7 +199,7 @@ inline void RawImageSource::interpolate_row_rb (float* ar, float* ab, float* pg,
ab[j] = b;
}
}
} else {
} else if(ng && pg) {
// BGBGB or GBGBGB line
for (int j = 0; j < W; j++) {
if (ri->ISBLUE(i, j)) {
@ -265,7 +265,7 @@ inline void RawImageSource::interpolate_row_rb (float* ar, float* ab, float* pg,
inline void RawImageSource::interpolate_row_rb_mul_pp (float* ar, float* ab, float* pg, float* cg, float* ng, int i, float r_mul, float g_mul, float b_mul, int x1, int width, int skip)
{
if (ri->ISRED(i, 0) || ri->ISRED(i, 1)) {
if ((ri->ISRED(i, 0) || ri->ISRED(i, 1)) && pg && ng) {
// RGRGR or GRGRGR line
for (int j = x1, jx = 0; jx < width; j += skip, jx++) {
if (ri->ISRED(i, j)) {
@ -324,7 +324,7 @@ inline void RawImageSource::interpolate_row_rb_mul_pp (float* ar, float* ab, flo
ab[jx] = b;
}
}
} else {
} else if(pg && ng) {
// BGBGB or GBGBGB line
for (int j = x1, jx = 0; jx < width; j += skip, jx++) {
if (ri->ISBLUE(i, j)) {

View File

@ -119,8 +119,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
ALLNORAW, // EvDPDNLuma,
ALLNORAW, // EvDPDNChroma,
ALLNORAW, // EvDPDNGamma,
ALLNORAW, // EvDirPyrEqualizer,
ALLNORAW, // EvDirPyrEqlEnabled,
ALLNORAW, // EvDirPyrEqualizer,
ALLNORAW, // EvDirPyrEqlEnabled,
LUMINANCECURVE, // EvLSaturation,
LUMINANCECURVE, // EvLaCurve,
LUMINANCECURVE, // EvLbCurve,
@ -275,12 +275,12 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, // EvLCLCurve
LUMINANCECURVE, // EvLLHCurve
LUMINANCECURVE, // EvLHHCurve
ALLNORAW, // EvDirPyrEqualizerThreshold
ALLNORAW, // EvDirPyrEqualizerThreshold
ALLNORAW, // EvDPDNenhance
RGBCURVE, // EvBWMethodalg
ALLNORAW, // EvDirPyrEqualizerSkin
ALLNORAW, // EvDirPyrEqlgamutlab
ALLNORAW, // EvDirPyrEqualizerHueskin
ALLNORAW, // EvDirPyrEqualizerSkin
ALLNORAW, // EvDirPyrEqlgamutlab
ALLNORAW, // EvDirPyrEqualizerHueskin
ALLNORAW, // EvDPDNmedian
ALLNORAW, // EvDPDNmedmet
RGBCURVE, // EvColorToningEnabled
@ -453,7 +453,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
RETINEX, // EvLhighl
DEMOSAIC, // EvLbaselog
DEMOSAIC, // EvRetinexlhcurve
ALLNORAW, // EvOIntent
OUTPUTPROFILE, // EvOIntent
MONITORTRANSFORM, // EvMonitorTransform: no history message
RETINEX, // EvLiter
RETINEX, // EvLgrad
@ -465,10 +465,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
RETINEX, // EvLradius
RETINEX, // EvmapMethod
DEMOSAIC, // EvRetinexmapcurve
DEMOSAIC, // EvviewMethod
ALLNORAW, // EvcbdlMethod
DEMOSAIC, // EvviewMethod
ALLNORAW, // EvcbdlMethod
RETINEX, // EvRetinexgaintransmission
RETINEX //EvLskal
RETINEX, // EvLskal
OUTPUTPROFILE // EvOBPCompens
};

View File

@ -46,7 +46,7 @@
// Bitfield of functions to do to the preview image when an event occurs
// Use those or create new ones for your new events
#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL
#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR|M_MONITOR) // without HIGHQUAL
#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL
#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR)
@ -61,7 +61,7 @@
#define DEFRINGE (M_LUMINANCE|M_COLOR)
#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR)
#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR)
#define GAMMA (M_LUMINANCE|M_COLOR)
#define GAMMA M_MONITOR
#define CROP M_CROP
#define RESIZE M_VOID
#define EXIF M_VOID
@ -69,7 +69,7 @@
#define MINUPDATE M_MINUPDATE
#define RETINEX (M_RETINEX|ALLNORAW)
#define MONITORTRANSFORM M_MONITOR
#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM)
#define OUTPUTPROFILE M_MONITOR
extern int refreshmap[];
#endif

View File

@ -418,6 +418,8 @@ public:
virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0;
virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0;
virtual void setSoftProofing (bool softProof, bool gamutCheck) = 0;
virtual void getSoftProofing (bool &softProof, bool &gamutCheck) = 0;
virtual ~StagedImageProcessor () {}

View File

@ -735,6 +735,7 @@ void Thumbnail::init ()
}
Thumbnail::Thumbnail () :
iColorMatrix{}, cam2xyz{}, scale(1.0), colorMatrix{}, isRaw(true),
camProfile(nullptr), thumbImg(nullptr),
camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0),
redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0),
@ -908,7 +909,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
ImProcFunctions ipf (&params, false);
ipf.setScale (sqrt(double(fw * fw + fh * fh)) / sqrt(double(thumbImg->width * thumbImg->width + thumbImg->height * thumbImg->height))*scale);
ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent);
ipf.updateColorProfiles (params.icm, options.rtSettings.monitorProfile, options.rtSettings.monitorIntent, false, false);
LUTu hist16 (65536);

View File

@ -107,7 +107,7 @@ public:
static ImageIO* resizeToSameType(int nw, int nh, TypeInterpolation interp, ImageIO* srcImg)
{
ImageIO* imgPtr;
ImageIO* imgPtr = nullptr;
if (srcImg->getType() == sImage8) {
Image8* castedSrcImg = static_cast<Image8*>(srcImg);

View File

@ -40,6 +40,7 @@ public:
Glib::ustring monitorProfile; ///< ICC profile name used for the monitor
RenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile
bool monitorBPC; ///< Black Point Compensation for the Labimage->Monitor transform (directly, i.e. not soft-proofing and no WCS in between)
bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile
bool autocielab;
bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode

View File

@ -30,7 +30,7 @@ namespace rtengine
extern const Settings* settings;
SHMap::SHMap (int w, int h, bool multiThread) : W(w), H(h), multiThread(multiThread)
SHMap::SHMap (int w, int h, bool multiThread) : max_f(0.f), min_f(0.f), avg(0.f), W(w), H(h), multiThread(multiThread)
{
map = new float*[H];

View File

@ -54,7 +54,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if (errorCode) {
delete job;
return nullptr;
return NULL;
}
}
@ -165,7 +165,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
NoiseCurve noiseLCurve;
NoiseCurve noiseCCurve;
Imagefloat *calclum = nullptr ;
Imagefloat *calclum = NULL ;
params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve);
float autoNR = (float) settings->nrauto;//
float autoNRmax = (float) settings->nrautomax;//
@ -754,7 +754,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
// update blurmap
SHMap* shmap = nullptr;
SHMap* shmap = NULL;
if (params.sh.enabled) {
shmap = new SHMap (fw, fh, true);
@ -858,7 +858,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
DCPProfile::ApplyState as;
DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB, as);
ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as);
ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as);
if (settings->verbose) {
printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob);
@ -881,13 +881,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// Freeing baseImg because not used anymore
delete baseImg;
baseImg = nullptr;
baseImg = NULL;
if (shmap) {
delete shmap;
}
shmap = nullptr;
shmap = NULL;
if (pl) {
pl->setProgress (0.55);
@ -933,7 +933,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,
params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 1);
ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy);
ipf.chromiLuminanceCurve (NULL, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy);
if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) {
ipf.EPDToneMap(labView, 5, 1);
@ -1071,7 +1071,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
delete cieView;
cieView = nullptr;
cieView = NULL;
@ -1147,217 +1147,31 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
}
Image16* readyImg = nullptr;
cmsHPROFILE jprof = nullptr;
Image16* readyImg = NULL;
cmsHPROFILE jprof = NULL;
bool customGamma = false;
bool useLCMS = false;
bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili ;
if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8
double ga0, ga1, ga2, ga3, ga4, ga5, ga6;
GammaValues ga;
// if(params.blackwhite.enabled) params.toneCurve.hrenabled=false;
readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled );
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly, &ga);
customGamma = true;
//or selected Free gamma
useLCMS = false;
bool pro = false;
Glib::ustring chpro, outProfile;
bool present_space[10] = {false, false, false, false, false, false, false, false, false, false};
std::vector<Glib::ustring> opnames = iccStore->getProfiles ();
//test if files are in system
for (int j = 0; j < 10; j++) {
// one can modify "option" [Color Management] to adapt the profile's name if they are different for windows, MacOS, Linux ??
// some of them are actually provided by RT, thanks to Jacques Desmis
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;
} else if(j == 7) {
chpro = options.rtSettings.srgb10; //gamma 1.0
} else if(j == 8) {
chpro = options.rtSettings.prophoto10; //gamma 1.0
} else if(j == 9) {
chpro = options.rtSettings.rec2020;
}
for (unsigned int i = 0; i < opnames.size(); i++) {
if(chpro.compare(opnames[i]) == 0) {
present_space[j] = true;
}
}
if (!present_space[j] && settings->verbose) {
printf("Missing file: %s\n", chpro.c_str());
}
}
if (params.icm.freegamma && params.icm.gampos < 1.35) {
pro = true; //select profil with gammaTRC modified :
} else if (params.icm.gamma == "linear_g1.0" || (params.icm.gamma == "High_g1.3_s3.35")) {
pro = true; //pro=0 RT_sRGB || Prophoto
}
// Check that output profiles exist, otherwise use LCMS2
// Use the icc/icm profiles associated to possible working profiles, set in "options"
if (params.icm.working == "ProPhoto" && present_space[0] && !pro) {
outProfile = options.rtSettings.prophoto;
} else if (params.icm.working == "Adobe RGB" && present_space[1] ) {
outProfile = options.rtSettings.adobe;
} else if (params.icm.working == "WideGamut" && present_space[2] ) {
outProfile = options.rtSettings.widegamut;
} else if (params.icm.working == "Beta RGB" && present_space[3] ) {
outProfile = options.rtSettings.beta;
} else if (params.icm.working == "BestRGB" && present_space[4] ) {
outProfile = options.rtSettings.best;
} else if (params.icm.working == "BruceRGB" && present_space[5] ) {
outProfile = options.rtSettings.bruce;
} else if (params.icm.working == "sRGB" && present_space[6] && !pro) {
outProfile = options.rtSettings.srgb;
} else if (params.icm.working == "sRGB" && present_space[7] && pro) {
outProfile = options.rtSettings.srgb10;
} else if (params.icm.working == "ProPhoto" && present_space[8] && pro) {
outProfile = options.rtSettings.prophoto10;
} else if (params.icm.working == "Rec2020" && present_space[9]) {
outProfile = options.rtSettings.rec2020;
} else {
// Should not occurs
if (settings->verbose) {
printf("\"%s\": unknown working profile! - use LCMS2 substitution\n", params.icm.working.c_str() );
}
if ((jprof = iccStore->createCustomGammaOutputProfile (params.icm, ga)) == NULL) {
useLCMS = true;
}
//begin adaptation rTRC gTRC bTRC
//"jprof" profile has the same characteristics than RGB values, but TRC are adapted... for applying profile
if (!useLCMS) {
if (settings->verbose) {
printf("Output Gamma - profile: \"%s\"\n", outProfile.c_str() ); //c_str()
}
jprof = iccStore->getProfile(outProfile); //get output profile
if (jprof == nullptr) {
useLCMS = true;
if (settings->verbose) {
printf("\"%s\" ICC output profile not found!\n", outProfile.c_str());
}
} else {
cmsToneCurve* GammaTRC[3] = { nullptr, nullptr, nullptr };
cmsFloat64Number Parameters[7];
Parameters[0] = ga0;
Parameters[1] = ga1;
Parameters[2] = ga2;
Parameters[3] = ga3;
Parameters[4] = ga4;
Parameters[5] = ga5;
Parameters[6] = ga6;
// 7 parameters for smoother curves
//change desc Tag , to "free gamma", or "BT709", etc.
cmsMLU *DescriptionMLU, *CopyrightMLU, *DmndMLU, *DmddMLU;// for modification TAG
cmsContext ContextID = cmsGetProfileContextID(jprof);//modification TAG
DescriptionMLU = cmsMLUalloc(ContextID, 1);
CopyrightMLU = cmsMLUalloc(ContextID, 1);//for ICC
DmndMLU = cmsMLUalloc(ContextID, 1); //for ICC
DmddMLU = cmsMLUalloc(ContextID, 1); // for ICC
// instruction with //ICC are used for generate icc profile
if (DescriptionMLU == nullptr) {
printf("Description error\n");
}
cmsMLUsetWide(CopyrightMLU, "en", "US", L"General Public License - AdobeRGB compatible") ;//adapt to profil
cmsMLUsetWide(DmndMLU, "en", "US", L"RawTherapee") ;
cmsMLUsetWide(DmddMLU, "en", "US", L"RTMedium") ; //adapt to profil
//display Tag desc with : selection of gamma and Primaries
if (!params.icm.freegamma) {
std::wstring gammaStr;
if(params.icm.gamma == "High_g1.3_s3.35") {
gammaStr = std::wstring(L"GammaTRC: High g=1.3 s=3.35");
} else if (params.icm.gamma == "Low_g2.6_s6.9") {
gammaStr = std::wstring(L"GammaTRC: Low g=2.6 s=6.9");
} else if (params.icm.gamma == "sRGB_g2.4_s12.92") {
gammaStr = std::wstring(L"GammaTRC: sRGB g=2.4 s=12.92");
} else if (params.icm.gamma == "BT709_g2.2_s4.5") {
gammaStr = std::wstring(L"GammaTRC: BT709 g=2.2 s=4.5");
} else if (params.icm.gamma == "linear_g1.0") {
gammaStr = std::wstring(L"GammaTRC: Linear g=1.0");
} else if (params.icm.gamma == "standard_g2.2") {
gammaStr = std::wstring(L"GammaTRC: g=2.2");
} else if (params.icm.gamma == "standard_g1.8") {
gammaStr = std::wstring(L"GammaTRC: g=1.8");
}
cmsMLUsetWide(DescriptionMLU, "en", "US", gammaStr.c_str());
//for elaboration ICC profiles
// else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Medium gamma sRGB(AdobeRGB compatible)");
// else if (params.icm.gamma== "BT709_g2.2_s4.5" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma BT709(IEC61966 equivalent)");
// else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma sRGB(IEC61966 equivalent)");
// else if (params.icm.gamma== "linear_g1.0" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma Linear1.0(IEC61966 equivalent)");
//else if (params.icm.gamma== "BT709_g2.2_s4.5" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma BT709(Prophoto compatible)");
// else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma sRGB(Prophoto compatible)");
// else if (params.icm.gamma== "linear_g1.0" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma Linear1.0(Prophoto compatible)");
} else {
// create description with gamma + slope + primaries
std::wostringstream gammaWs;
gammaWs.precision(2);
gammaWs << "Manual GammaTRC: g=" << (float)params.icm.gampos << " s=" << (float)params.icm.slpos;
cmsMLUsetWide(DescriptionMLU, "en", "US", gammaWs.str().c_str());
}
cmsWriteTag(jprof, cmsSigProfileDescriptionTag, DescriptionMLU);//desc changed
// cmsWriteTag(jprof, cmsSigCopyrightTag, CopyrightMLU);
// cmsWriteTag(jprof, cmsSigDeviceMfgDescTag, DmndMLU);
// cmsWriteTag(jprof, cmsSigDeviceModelDescTag, DmddMLU);
// Calculate output profile's rTRC bTRC gTRC
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(nullptr, 5, Parameters);
cmsWriteTag(jprof, cmsSigGreenTRCTag, (void*)GammaTRC[1] );
cmsWriteTag(jprof, cmsSigRedTRCTag, (void*)GammaTRC[0] );
cmsWriteTag(jprof, cmsSigBlueTRCTag, (void*)GammaTRC[2] );
//for generation ICC profiles : here Prophoto ==> Large
// if(params.icm.gamma== "BT709_g2.2_s4.5") cmsSaveProfileToFile(jprof, "RT_sRGB_gBT709.icm");
// else if (params.icm.gamma== "sRGB_g2.4_s12.92") cmsSaveProfileToFile(jprof, "RT_Medium_gsRGB.icc");
// else if (params.icm.gamma== "linear_g1.0") cmsSaveProfileToFile(jprof, "RT_Large_g10.icc");
if (GammaTRC[0]) {
cmsFreeToneCurve(GammaTRC[0]);
}
}
}
} else {
// if Default gamma mode: we use the profile selected in the "Output profile" combobox;
// gamma come from the selected profile, otherwise it comes from "Free gamma" tool
// readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.blackwhite.enabled);
bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled ;
if(autili || butili ) {
bwonly = false;
}
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, bwonly);
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly);
if (settings->verbose) {
printf("Output profile_: \"%s\"\n", params.icm.output.c_str());
@ -1365,21 +1179,19 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
delete labView;
labView = nullptr;
labView = NULL;
if(!autili && !butili ) {
if(params.blackwhite.enabled && !params.colorToning.enabled ) {//force BW r=g=b
if (settings->verbose) {
printf("Force BW\n");
}
if(bwonly) { //force BW r=g=b
if (settings->verbose) {
printf("Force BW\n");
}
for (int ccw = 0; ccw < cw; ccw++) {
for (int cch = 0; cch < ch; cch++) {
readyImg->r(cch, ccw) = readyImg->g(cch, ccw);
readyImg->b(cch, ccw) = readyImg->g(cch, ccw);
}
for (int ccw = 0; ccw < cw; ccw++) {
for (int cch = 0; cch < ch; cch++) {
readyImg->r(cch, ccw) = readyImg->g(cch, ccw);
readyImg->b(cch, ccw) = readyImg->g(cch, ccw);
}
}
}
@ -1405,42 +1217,33 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// Setting the output curve to readyImg
if (customGamma) {
if (!useLCMS) {
// use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16b
// use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16 w/ gamma
ProfileContent pc(jprof);
readyImg->setOutputProfile (pc.data, pc.length);
}
} else {
// use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b
Glib::ustring outputProfile;
// use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma
if (params.icm.output != "" && params.icm.output != ColorManagementParams::NoICMString) {
outputProfile = params.icm.output;
/* if we'd wanted the RT_sRGB profile we would have selected it
else {
// use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b
if (settings->verbose) printf("No output profiles set ; looking for the default sRGB profile (\"%s\")...\n", options.rtSettings.srgb.c_str());
outputProfile = options.rtSettings.srgb;
}*/
// if iccStore->getProfile send back an object, then iccStore->getContent will do too
cmsHPROFILE jprof = iccStore->getProfile(outputProfile); //get outProfile
cmsHPROFILE jprof = iccStore->getProfile(params.icm.output); //get outProfile
if (jprof == nullptr) {
if (jprof == NULL) {
if (settings->verbose) {
printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", outputProfile.c_str());
printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", params.icm.output.c_str());
}
} else {
if (settings->verbose) {
printf("Using \"%s\" output profile\n", outputProfile.c_str());
printf("Using \"%s\" output profile\n", params.icm.output.c_str());
}
ProfileContent pc = iccStore->getContent (outputProfile);
ProfileContent pc = iccStore->getContent (params.icm.output);
readyImg->setOutputProfile (pc.data, pc.length);
}
} else {
// No ICM
readyImg->setOutputProfile (nullptr, 0);
readyImg->setOutputProfile (NULL, 0);
}
}
@ -1483,13 +1286,13 @@ void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bo
if (errorCode) {
bpl->error (M("MAIN_MSG_CANNOTLOAD"));
currentJob = nullptr;
currentJob = NULL;
} else {
try {
currentJob = bpl->imageReady (img);
} catch (Glib::Exception& ex) {
bpl->error (ex.what());
currentJob = nullptr;
currentJob = NULL;
}
}
}

View File

@ -51,15 +51,11 @@ template<class T> T** allocArray (int W, int H)
}
#define HR_SCALE 2
StdImageSource::StdImageSource () : ImageSource(), img(nullptr), plistener(nullptr)
StdImageSource::StdImageSource () : ImageSource(), img(NULL), plistener(NULL), full(false), max{}, rgbSourceModified(false)
{
hrmap[0] = nullptr;
hrmap[1] = nullptr;
hrmap[2] = nullptr;
needhr = nullptr;
embProfile = nullptr;
idata = nullptr;
embProfile = NULL;
idata = NULL;
}
StdImageSource::~StdImageSource ()
@ -67,17 +63,6 @@ StdImageSource::~StdImageSource ()
delete idata;
if (hrmap[0] != nullptr) {
int dh = img->getH() / HR_SCALE;
freeArray<float>(hrmap[0], dh);
freeArray<float>(hrmap[1], dh);
freeArray<float>(hrmap[2], dh);
}
if (needhr) {
freeArray<char>(needhr, img->getH());
}
if (img) {
delete img;
}
@ -178,7 +163,7 @@ int StdImageSource::load (const Glib::ustring &fname, bool batch)
if (error) {
delete img;
img = nullptr;
img = NULL;
return error;
}
@ -243,7 +228,7 @@ void StdImageSource::colorSpaceConversion (Imagefloat* im, const ColorManagement
{
bool skipTransform = false;
cmsHPROFILE in = nullptr;
cmsHPROFILE in = NULL;
cmsHPROFILE out = iccStore->workingSpace (cmp.working);
if (cmp.input == "(embedded)" || cmp.input == "" || cmp.input == "(camera)" || cmp.input == "(cameraICC)") {
@ -260,9 +245,9 @@ void StdImageSource::colorSpaceConversion (Imagefloat* im, const ColorManagement
if (cmp.input != "(none)") {
in = iccStore->getProfile (cmp.input);
if (in == nullptr && embedded) {
if (in == NULL && embedded) {
in = embedded;
} else if (in == nullptr) {
} else if (in == NULL) {
if (sampleFormat & (IIOSF_LOGLUV24 | IIOSF_LOGLUV32 | IIOSF_FLOAT)) {
skipTransform = true;
} else {
@ -311,7 +296,7 @@ void StdImageSource::getFullSize (int& w, int& h, int tr)
}
}
void StdImageSource::getSize (int tran, PreviewProps pp, int& w, int& h)
void StdImageSource::getSize (PreviewProps pp, int& w, int& h)
{
w = pp.w / pp.skip + (pp.w % pp.skip > 0);

View File

@ -32,8 +32,6 @@ protected:
ColorTemp wb;
ProgressListener* plistener;
bool full;
float** hrmap[3];
char** needhr;
int max[3];
bool rgbSourceModified;
@ -66,7 +64,7 @@ public:
}
void getFullSize (int& w, int& h, int tr = TR_NONE);
void getSize (int tran, PreviewProps pp, int& w, int& h);
void getSize (PreviewProps pp, int& w, int& h);
ImageData* getImageData ()
{

View File

@ -168,9 +168,7 @@ void rotate (unsigned char* img, int& w, int& h, int deg)
rotated[3 * (j * h + h - i - 1) + 2] = img[ix++];
}
int tmp = w;
w = h;
h = tmp;
std::swap(w,h);
} else if (deg == 270) {
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++) {
@ -179,10 +177,8 @@ void rotate (unsigned char* img, int& w, int& h, int deg)
rotated[3 * (h * (w - j - 1) + i) + 2] = img[ix++];
}
int tmp = w;
w = h;
h = tmp;
} else if (deg == 180)
std::swap(w,h);
} else /*if (deg == 180) */
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++) {
rotated[3 * (w * (h - i - 1) + w - j - 1) + 0] = img[ix++];

View File

@ -355,7 +355,7 @@ void CurveEditorGroup::setTooltip( Glib::ustring ttip)
void CurveEditorGroup::setBatchMode (bool batchMode)
{
for (std::vector<CurveEditor*>::iterator i = curveEditors.begin(); i != curveEditors.end(); ++i) {
(*i)->curveType->addEntry("curveType-unchanged.png", M("GENERAL_UNCHANGED"));
(*i)->curveType->addEntry("unchanged-18.png", M("GENERAL_UNCHANGED"));
(*i)->curveType->show();
}
}

View File

@ -35,11 +35,13 @@
using namespace rtengine::procparams;
class EditorPanel::MonitorProfileSelector
class EditorPanel::ColorManagementToolbar
{
private:
MyComboBoxText profileBox;
PopUpButton intentBox;
Gtk::ToggleButton softProof;
Gtk::ToggleButton spGamutCheck;
sigc::connection profileConn, intentConn;
rtengine::StagedImageProcessor* const& processor;
@ -57,27 +59,49 @@ private:
profileBox.set_active (0);
#endif
const std::vector<Glib::ustring> profiles = rtengine::iccStore->getProfiles ();
const std::vector<Glib::ustring> profiles = rtengine::iccStore->getProfiles (true);
for (std::vector<Glib::ustring>::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) {
profileBox.append_text (*iterator);
}
profileBox.set_tooltip_text (profileBox.get_active_text ());
}
void prepareIntentBox ()
{
intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE"));
// same order as the enum
intentBox.addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL"));
intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE"));
intentBox.addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE"));
intentBox.setSelected(0);
intentBox.setSelected(1);
intentBox.show ();
}
void prepareSoftProofingBox ()
{
Gtk::Image *softProofImage = Gtk::manage (new RTImage ("softProof.png"));
softProofImage->set_padding(0, 0);
softProof.add(*softProofImage);
softProof.set_relief(Gtk::RELIEF_NONE);
softProof.set_tooltip_markup(M("SOFTPROOF_TOOLTIP"));
softProof.set_active(false);
softProof.show ();
Gtk::Image *spGamutCheckImage = Gtk::manage (new RTImage ("spGamutCheck.png"));
spGamutCheckImage->set_padding(0, 0);
spGamutCheck.add(*spGamutCheckImage);
spGamutCheck.set_relief(Gtk::RELIEF_NONE);
spGamutCheck.set_tooltip_markup(M("SOFTPROOF_GAMUTCHECK_TOOLTIP"));
spGamutCheck.set_active(false);
spGamutCheck.set_sensitive(false);
spGamutCheck.show ();
}
void profileBoxChanged ()
{
updateParameters ();
profileBox.set_tooltip_text (profileBox.get_active_text ());
}
void intentBoxChanged (int)
@ -85,7 +109,17 @@ private:
updateParameters ();
}
void updateParameters ()
void softProofToggled ()
{
updateSoftProofParameters ();
}
void spGamutCheckToggled ()
{
updateSoftProofParameters ();
}
void updateParameters (bool noEvent = false)
{
ConnectionBlocker profileBlocker (profileConn);
ConnectionBlocker intentBlocker (intentConn);
@ -113,33 +147,46 @@ private:
profile.clear();
intentBox.set_sensitive (false);
intentBox.setSelected (0);
intentBox.setSelected (1);
softProof.set_sensitive(false);
spGamutCheck.set_sensitive(false);
profileBox.set_tooltip_text ("");
} else {
const std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile);
const uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile);
const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC;
const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL;
const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC;
if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) {
intentBox.set_sensitive (true);
intentBox.setItemSensitivity(0, supportsRelativeColorimetric);
intentBox.setItemSensitivity(1, supportsPerceptual);
intentBox.setItemSensitivity(0, supportsPerceptual);
intentBox.setItemSensitivity(1, supportsRelativeColorimetric);
intentBox.setItemSensitivity(2, supportsAbsoluteColorimetric);
softProof.set_sensitive(true);
spGamutCheck.set_sensitive(true);
} else {
intentBox.setItemSensitivity(0, true);
intentBox.setItemSensitivity(1, true);
intentBox.setItemSensitivity(2, true);
intentBox.set_sensitive (false);
intentBox.setSelected (0);
intentBox.setSelected (1);
softProof.set_sensitive(false);
spGamutCheck.set_sensitive(false);
}
profileBox.set_tooltip_text (profileBox.get_active_text ());
}
rtengine::RenderingIntent intent;
switch (intentBox.getSelected ()) {
default:
case 0:
intent = rtengine::RI_RELATIVE;
intent = rtengine::RI_PERCEPTUAL;
break;
case 1:
intent = rtengine::RI_PERCEPTUAL;
intent = rtengine::RI_RELATIVE;
break;
case 2:
intent = rtengine::RI_ABSOLUTE;
@ -150,31 +197,63 @@ private:
return;
}
processor->beginUpdateParams ();
if (!noEvent) {
processor->beginUpdateParams ();
}
processor->setMonitorProfile (profile, intent);
processor->endUpdateParams (rtengine::EvMonitorTransform);
processor->setSoftProofing (softProof.get_sensitive() && softProof.get_active(), spGamutCheck.get_sensitive() && spGamutCheck.get_active());
if (!noEvent) {
processor->endUpdateParams (rtengine::EvMonitorTransform);
}
}
void updateSoftProofParameters (bool noEvent = false)
{
spGamutCheck.set_sensitive(softProof.get_active());
if (profileBox.get_active_row_number () > 0) {
if (!noEvent) {
processor->beginUpdateParams ();
}
processor->setSoftProofing (softProof.get_sensitive() && softProof.get_active(), spGamutCheck.get_sensitive() && spGamutCheck.get_active());
if (!noEvent) {
processor->endUpdateParams (rtengine::EvMonitorTransform);
}
}
}
public:
explicit MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) :
explicit ColorManagementToolbar (rtengine::StagedImageProcessor* const& ipc) :
intentBox (Glib::ustring (), true),
processor (ipc)
{
prepareProfileBox ();
prepareIntentBox ();
prepareSoftProofingBox ();
reset ();
profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::profileBoxChanged));
intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::intentBoxChanged));
softProof.signal_toggled().connect(sigc::mem_fun (this, &ColorManagementToolbar::softProofToggled));
spGamutCheck.signal_toggled().connect(sigc::mem_fun (this, &ColorManagementToolbar::spGamutCheckToggled));;
profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &ColorManagementToolbar::profileBoxChanged));
intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &ColorManagementToolbar::intentBoxChanged));
}
void pack_end_in (Gtk::Box* box)
{
box->pack_end (spGamutCheck, Gtk::PACK_SHRINK, 0);
box->pack_end (softProof, Gtk::PACK_SHRINK, 0);
box->pack_end (*intentBox.buttonGroup, Gtk::PACK_SHRINK, 0);
box->pack_end (profileBox, Gtk::PACK_SHRINK, 0);
}
void updateProcessor()
{
if (processor) {
updateParameters(true);
}
}
void reset ()
{
ConnectionBlocker profileBlocker (profileConn);
@ -193,10 +272,10 @@ public:
switch (options.rtSettings.monitorIntent)
{
default:
case rtengine::RI_RELATIVE:
case rtengine::RI_PERCEPTUAL:
intentBox.setSelected (0);
break;
case rtengine::RI_PERCEPTUAL:
case rtengine::RI_RELATIVE:
intentBox.setSelected (1);
break;
case rtengine::RI_ABSOLUTE:
@ -444,9 +523,9 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0);
// Monitor profile buttons
monitorProfile.reset (new MonitorProfileSelector (ipc));
monitorProfile->pack_end_in (iops);
// Color management toolbar
colorMgmtToolBar.reset (new ColorManagementToolbar (ipc));
colorMgmtToolBar->pack_end_in (iops);
editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0);
editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0);
@ -706,6 +785,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
this->isrc = isrc;
ipc = rtengine::StagedImageProcessor::create (isrc);
ipc->setProgressListener (this);
colorMgmtToolBar->updateProcessor();
ipc->setPreviewImageListener (previewHandler);
ipc->setPreviewScale (10); // Important
tpc->initImage (ipc, tmb->getType() == FT_Raw);
@ -754,8 +834,6 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc)
}
history->resetSnapShotNumber();
monitorProfile->reset ();
}
void EditorPanel::close ()

View File

@ -84,8 +84,8 @@ protected:
Gtk::Button* navNext;
Gtk::Button* navPrev;
class MonitorProfileSelector;
std::unique_ptr<MonitorProfileSelector> monitorProfile;
class ColorManagementToolbar;
std::unique_ptr<ColorManagementToolbar> colorMgmtToolBar;
ImageAreaPanel* iareapanel;
PreviewHandler* previewHandler;

View File

@ -1176,6 +1176,7 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
params.icm.working = options.fastexport_icm_working ;
params.icm.output = options.fastexport_icm_output ;
params.icm.outputIntent = options.fastexport_icm_outputIntent ;
params.icm.outputBPC = options.fastexport_icm_outputBPC ;
params.icm.gamma = options.fastexport_icm_gamma ;
params.resize.enabled = options.fastexport_resize_enabled ;
params.resize.scale = options.fastexport_resize_scale ;

View File

@ -26,9 +26,9 @@
#include "../rtengine/improccoordinator.h"
#include "../rtengine/color.h"
#include "../rtengine/opthelper.h"
#include "../rtengine/iccstore.h"
using namespace rtengine;
extern Glib::ustring argv0;
extern Options options;

View File

@ -193,15 +193,21 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
Gtk::HBox *riHBox = Gtk::manage ( new Gtk::HBox());
Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_PROFILEINTENT")+":"));
riHBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK);
ointent = Gtk::manage (new MyComboBoxText ());
riHBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET);
ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL"));
ointent->append_text (M("PREFERENCES_INTENT_RELATIVE"));
ointent->append_text (M("PREFERENCES_INTENT_SATURATION"));
ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE"));
ointent->set_active (1);
ointent = Gtk::manage (new PopUpButton ());
ointent->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL"));
ointent->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE"));
ointent->addEntry("intent-saturation.png", M("PREFERENCES_INTENT_SATURATION"));
ointent->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE"));
ointent->setSelected (1);
ointent->show();
riHBox->pack_start (*ointent->buttonGroup, Gtk::PACK_EXPAND_PADDING);
oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK);
// Black Point Compensation
obpc = Gtk::manage(new Gtk::CheckButton((M("TP_ICM_BPC"))));
obpc->set_active (true);
oVBox->pack_start(*obpc, Gtk::PACK_SHRINK);
// Output gamma
Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ());
@ -295,6 +301,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) );
dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) );
obpcconn = obpc->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::oBPCChanged) );
gamcsconn = freegamma->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::GamChanged));
tcurveconn = ckbToneCurve->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::toneCurveChanged));
ltableconn = ckbApplyLookTable->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::applyLookTableChanged));
@ -313,6 +320,31 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch
show_all ();
}
void ICMPanel::updateRenderingIntent (const Glib::ustring &profile) {
const uint8_t supportedIntents = rtengine::iccStore->getOutputIntents (profile);
const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL;
const bool supportsRelative = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC;
const bool supportsSaturation = supportedIntents & 1 << INTENT_SATURATION;
const bool supportsAbsolute = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC;
//printf("Intents: %d / Perceptual: %d Relative: %d Saturation: %d Absolute: %d\n", supportedIntents, supportsPerceptual, supportsRelative, supportsSaturation, supportsAbsolute);
if (!profile.empty() && (supportsPerceptual || supportsRelative || supportsSaturation || supportsAbsolute)) {
ointent->set_sensitive (true);
ointent->setItemSensitivity(0, supportsPerceptual);
ointent->setItemSensitivity(1, supportsRelative);
ointent->setItemSensitivity(2, supportsSaturation);
ointent->setItemSensitivity(3, supportsAbsolute);
} else {
ointent->setItemSensitivity(0, true);
ointent->setItemSensitivity(1, true);
ointent->setItemSensitivity(2, true);
ointent->setItemSensitivity(3, true);
ointent->set_sensitive (false);
ointent->setSelected (1);
}
}
void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name)
{
@ -455,6 +487,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
disableListener ();
obpcconn.block (true);
ipc.block (true);
gamcsconn.block (true);
tcurveconn.block(true);
@ -469,36 +502,50 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
if (pp->icm.input == "(none)") {
inone->set_active (true);
ckbBlendCMSMatrix->set_sensitive (false);
if (!batchMode) {
ckbBlendCMSMatrix->set_sensitive (false);
}
updateDCP(pp->icm.dcpIlluminant, "");
} else if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() == Gtk::STATE_INSENSITIVE)) {
iembedded->set_active (true);
ckbBlendCMSMatrix->set_sensitive (false);
if (!batchMode) {
ckbBlendCMSMatrix->set_sensitive (false);
}
updateDCP(pp->icm.dcpIlluminant, "");
} else if ((pp->icm.input == "(cameraICC)") && icameraICC->get_state() != Gtk::STATE_INSENSITIVE) {
icameraICC->set_active (true);
ckbBlendCMSMatrix->set_sensitive (true);
if (!batchMode) {
ckbBlendCMSMatrix->set_sensitive (true);
}
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
} else if ((pp->icm.input == "(cameraICC)") && icamera->get_state() != Gtk::STATE_INSENSITIVE && icameraICC->get_state() == Gtk::STATE_INSENSITIVE) {
// this is the case when (cameraICC) is instructed by packaged profiles, but ICC file is not found
// therefore falling back UI to explicitly reflect the (camera) option
icamera->set_active (true);
ckbBlendCMSMatrix->set_sensitive (false);
if (!batchMode) {
ckbBlendCMSMatrix->set_sensitive (false);
}
updateDCP(pp->icm.dcpIlluminant, "");
} else if ((pp->icm.input == "(cameraICC)") && icamera->get_state() == Gtk::STATE_INSENSITIVE && icameraICC->get_state() == Gtk::STATE_INSENSITIVE) {
// If neither (camera) nor (cameraICC) are available, as is the case when loading a non-raw, activate (embedded).
iembedded->set_active (true);
ckbBlendCMSMatrix->set_sensitive (false);
if (!batchMode) {
ckbBlendCMSMatrix->set_sensitive (false);
}
updateDCP(pp->icm.dcpIlluminant, "(cameraICC)");
} else if ((pp->icm.input == "(camera)" || pp->icm.input == "") && icamera->get_state() != Gtk::STATE_INSENSITIVE) {
icamera->set_active (true);
ckbBlendCMSMatrix->set_sensitive (false);
if (!batchMode) {
ckbBlendCMSMatrix->set_sensitive (false);
}
updateDCP(pp->icm.dcpIlluminant, "");
} else {
ifromfile->set_active (true);
oldip = pp->icm.input.substr(5); // cut of "file:"
ipDialog->set_filename (pp->icm.input.substr(5));
ckbBlendCMSMatrix->set_sensitive (true);
if (!batchMode) {
ckbBlendCMSMatrix->set_sensitive (true);
}
updateDCP(pp->icm.dcpIlluminant, pp->icm.input.substr(5));
}
@ -514,8 +561,9 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
if (onames->get_active_row_number() == -1) {
onames->set_active_text (M("TP_ICM_NOICM"));
}
ointent->set_active(pp->icm.outputIntent);
ointent->setSelected (pp->icm.outputIntent);
obpc->set_active (pp->icm.outputBPC);
ckbToneCurve->set_active (pp->icm.toneCurve);
lastToneCurve = pp->icm.toneCurve;
ckbApplyLookTable->set_active (pp->icm.applyLookTable);
@ -528,22 +576,29 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
ckbBlendCMSMatrix->set_active (pp->icm.blendCMSMatrix);
lastBlendCMSMatrix = pp->icm.blendCMSMatrix;
onames->set_sensitive(wgamma->get_active_row_number() == 0 || freegamma->get_active()); //"default"
wgamma->set_sensitive(!freegamma->get_active());
freegamma->set_active (pp->icm.freegamma);
lastgamfree = pp->icm.freegamma;
if (!batchMode) {
onames->set_sensitive(wgamma->get_active_row_number() == 0 && !pp->icm.freegamma); //"default"
wgamma->set_sensitive(!pp->icm.freegamma);
gampos->set_sensitive(pp->icm.freegamma);
slpos->set_sensitive(pp->icm.freegamma);
updateRenderingIntent(pp->icm.output);
}
gampos->setValue (pp->icm.gampos);
slpos->setValue (pp->icm.slpos);
if (pedited) {
iunchanged->set_active (!pedited->icm.input);
obpc->set_inconsistent(!pedited->icm.outputBPC);
ckbToneCurve->set_inconsistent(!pedited->icm.toneCurve);
ckbApplyLookTable->set_inconsistent(!pedited->icm.applyLookTable);
ckbApplyBaselineExposureOffset->set_inconsistent(!pedited->icm.applyBaselineExposureOffset);
ckbApplyHueSatMap->set_inconsistent(!pedited->icm.applyHueSatMap);
ckbBlendCMSMatrix->set_inconsistent(!pedited->icm.blendCMSMatrix);
freegamma->set_inconsistent (!pedited->icm.freegamma);
if (!pedited->icm.working) {
wnames->set_active_text(M("GENERAL_UNCHANGED"));
@ -554,7 +609,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
}
if (!pedited->icm.outputIntent) {
ointent->set_active_text(M("GENERAL_UNCHANGED"));
ointent->setSelected (4);
}
if (!pedited->icm.dcpIlluminant) {
@ -578,6 +633,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited)
hsmconn.block(false);
gamcsconn.block (false);
ipc.block (false);
obpcconn.block (false);
enableListener ();
}
@ -617,7 +673,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
pp->icm.output = onames->get_active_text();
}
int ointentVal = ointent->get_active_row_number();
int ointentVal = ointent->getSelected ();
if (ointentVal >= 0 && ointentVal < RI__COUNT) {
pp->icm.outputIntent = static_cast<RenderingIntent>(ointentVal);
} else {
@ -655,12 +711,14 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
pp->icm.blendCMSMatrix = ckbBlendCMSMatrix->get_active ();
pp->icm.gampos = (double) gampos->getValue();
pp->icm.slpos = (double) slpos->getValue();
pp->icm.outputBPC = obpc->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.outputIntent = ointent->get_active_text() != M("GENERAL_UNCHANGED");
pedited->icm.outputIntent = ointent->getSelected () < 4;
pedited->icm.outputBPC = !obpc->get_inconsistent ();
pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED");
pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent ();
pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent ();
@ -697,7 +755,7 @@ void ICMPanel::setAdjusterBehavior (bool gammaadd, bool slopeadd)
void ICMPanel::adjusterChanged (Adjuster* a, double newval)
{
if (listener && freegamma->get_active()) {
if (listener && (freegamma->get_active() || batchMode)) {
Glib::ustring costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), newval);
@ -735,7 +793,7 @@ void ICMPanel::dcpIlluminantChanged()
void ICMPanel::toneCurveChanged()
{
if (batchMode) {
if (multiImage) {
if (ckbToneCurve->get_inconsistent()) {
ckbToneCurve->set_inconsistent (false);
tcurveconn.block (true);
@ -749,13 +807,19 @@ void ICMPanel::toneCurveChanged()
}
if (listener) {
listener->panelChanged (EvDCPToneCurve, ckbToneCurve->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
if (ckbToneCurve->get_inconsistent()) {
listener->panelChanged (EvDCPToneCurve, M("GENERAL_UNCHANGED"));
} else if (ckbToneCurve->get_active()) {
listener->panelChanged (EvDCPToneCurve, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvDCPToneCurve, M("GENERAL_DISABLED"));
}
}
}
void ICMPanel::applyLookTableChanged()
{
if (batchMode) {
if (multiImage) {
if (ckbApplyLookTable->get_inconsistent()) {
ckbApplyLookTable->set_inconsistent (false);
ltableconn.block (true);
@ -769,13 +833,19 @@ void ICMPanel::applyLookTableChanged()
}
if (listener) {
listener->panelChanged (EvDCPApplyLookTable, ckbApplyLookTable->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
if (ckbApplyLookTable->get_inconsistent()) {
listener->panelChanged (EvDCPApplyLookTable, M("GENERAL_UNCHANGED"));
} else if (ckbApplyLookTable->get_active()) {
listener->panelChanged (EvDCPApplyLookTable, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvDCPApplyLookTable, M("GENERAL_DISABLED"));
}
}
}
void ICMPanel::applyBaselineExposureOffsetChanged()
{
if (batchMode) {
if (multiImage) {
if (ckbApplyBaselineExposureOffset->get_inconsistent()) {
ckbApplyBaselineExposureOffset->set_inconsistent (false);
beoconn.block (true);
@ -789,13 +859,19 @@ void ICMPanel::applyBaselineExposureOffsetChanged()
}
if (listener) {
listener->panelChanged (EvDCPApplyBaselineExposureOffset, ckbApplyBaselineExposureOffset->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
if (ckbApplyBaselineExposureOffset->get_inconsistent()) {
listener->panelChanged (EvDCPApplyBaselineExposureOffset, M("GENERAL_UNCHANGED"));
} else if (ckbApplyBaselineExposureOffset->get_active()) {
listener->panelChanged (EvDCPApplyBaselineExposureOffset, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvDCPApplyBaselineExposureOffset, M("GENERAL_DISABLED"));
}
}
}
void ICMPanel::applyHueSatMapChanged()
{
if (batchMode) {
if (multiImage) {
if (ckbApplyHueSatMap->get_inconsistent()) {
ckbApplyHueSatMap->set_inconsistent (false);
hsmconn.block (true);
@ -809,7 +885,13 @@ void ICMPanel::applyHueSatMapChanged()
}
if (listener) {
listener->panelChanged (EvDCPApplyHueSatMap, ckbApplyHueSatMap->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
if (ckbApplyHueSatMap->get_inconsistent()) {
listener->panelChanged (EvDCPApplyHueSatMap, M("GENERAL_UNCHANGED"));
} else if (ckbApplyHueSatMap->get_active()) {
listener->panelChanged (EvDCPApplyHueSatMap, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvDCPApplyHueSatMap, M("GENERAL_DISABLED"));
}
}
}
@ -846,7 +928,7 @@ void ICMPanel::ipChanged ()
void ICMPanel::blendCMSMatrixChanged()
{
if (batchMode) {
if (multiImage) {
if (ckbBlendCMSMatrix->get_inconsistent()) {
ckbBlendCMSMatrix->set_inconsistent (false);
blendcmsconn.block (true);
@ -860,13 +942,19 @@ void ICMPanel::blendCMSMatrixChanged()
}
if (listener) {
listener->panelChanged (EvBlendCMSMatrix, ckbBlendCMSMatrix->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
if (ckbBlendCMSMatrix->get_inconsistent()) {
listener->panelChanged (EvBlendCMSMatrix, M("GENERAL_UNCHANGED"));
} else if (ckbBlendCMSMatrix->get_active()) {
listener->panelChanged (EvBlendCMSMatrix, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvBlendCMSMatrix, M("GENERAL_DISABLED"));
}
}
}
void ICMPanel::GamChanged()
{
if (batchMode) {
if (multiImage) {
if (freegamma->get_inconsistent()) {
freegamma->set_inconsistent (false);
gamcsconn.block (true);
@ -880,31 +968,90 @@ void ICMPanel::GamChanged()
}
if (listener) {
if (freegamma->get_active()) {
if (freegamma->get_inconsistent()) {
listener->panelChanged (EvGAMFREE, M("GENERAL_UNCHANGED"));
}
else if (freegamma->get_active()) {
listener->panelChanged (EvGAMFREE, M("GENERAL_ENABLED"));
onames->set_sensitive(!freegamma->get_active());//disabled choice
wgamma->set_sensitive(!freegamma->get_active());
if (!batchMode) {
onames->set_sensitive(false);//disabled choice
wgamma->set_sensitive(false);
gampos->set_sensitive(true);
slpos->set_sensitive(true);
}
} else {
listener->panelChanged (EvGAMFREE, M("GENERAL_DISABLED"));
onames->set_sensitive(!freegamma->get_active() && wgamma->get_active_row_number() == 0);
wgamma->set_sensitive(!freegamma->get_active());
if (!batchMode) {
onames->set_sensitive(wgamma->get_active_row_number() == 0);
wgamma->set_sensitive(true);
gampos->set_sensitive(false);
slpos->set_sensitive(false);
}
}
}
}
void ICMPanel::opChanged ()
{
if (!batchMode) {
updateRenderingIntent(onames->get_active_text());
}
if (listener) {
listener->panelChanged (EvOProfile, onames->get_active_text());
}
}
void ICMPanel::oiChanged ()
void ICMPanel::oiChanged (int n)
{
if (listener) {
listener->panelChanged (EvOIntent, ointent->get_active_text());
Glib::ustring str;
switch (n) {
case 0:
str = M("PREFERENCES_INTENT_PERCEPTUAL");
break;
case 1:
str = M("PREFERENCES_INTENT_RELATIVE");
break;
case 2:
str = M("PREFERENCES_INTENT_SATURATION");
break;
case 3:
str = M("PREFERENCES_INTENT_ABSOLUTE");
break;
case 4:
default:
str = M("GENERAL_UNCHANGED");
break;
}
listener->panelChanged (EvOIntent, str);
}
}
void ICMPanel::oBPCChanged ()
{
if (multiImage) {
if (obpc->get_inconsistent()) {
obpc->set_inconsistent (false);
obpcconn.block (true);
obpc->set_active (false);
obpcconn.block (false);
} else if (lastobpc) {
obpc->set_inconsistent (true);
}
lastobpc = obpc->get_active ();
}
if (listener) {
if (obpc->get_inconsistent()) {
listener->panelChanged (EvOBPCompens, M("GENERAL_UNCHANGED"));
} else if (obpc->get_active()) {
listener->panelChanged (EvOBPCompens, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvOBPCompens, M("GENERAL_DISABLED"));
}
}
}
@ -1006,7 +1153,8 @@ void ICMPanel::setBatchMode (bool batchMode)
iVBox->reorder_child (*iunchanged, 5);
removeIfThere (this, saveRef);
onames->append_text (M("GENERAL_UNCHANGED"));
ointent->append_text (M("GENERAL_UNCHANGED"));
ointent->addEntry("unchanged-22.png", M("GENERAL_UNCHANGED"));
ointent->show();
wnames->append_text (M("GENERAL_UNCHANGED"));
wgamma->append_text (M("GENERAL_UNCHANGED"));
dcpIll->append_text (M("GENERAL_UNCHANGED"));

View File

@ -25,6 +25,7 @@
#include "guiutils.h"
#include "toolpanel.h"
#include "popupbutton.h"
#include "../rtengine/imagedata.h"
class ICMPanelListener
@ -53,6 +54,8 @@ protected:
sigc::connection beoconn;
bool lastApplyHueSatMap;
sigc::connection hsmconn;
bool lastobpc;
sigc::connection obpcconn;
bool lastBlendCMSMatrix;
bool isBatchMode;
sigc::connection blendcmsconn;
@ -60,6 +63,7 @@ protected:
private:
Gtk::VBox * iVBox;
Gtk::CheckButton* obpc;
Gtk::CheckButton* freegamma;
Gtk::RadioButton* inone;
@ -78,7 +82,7 @@ private:
MyComboBoxText* wgamma;
MyComboBoxText* onames;
MyComboBoxText* ointent;
PopUpButton* ointent;
Gtk::RadioButton* ofromdir;
Gtk::RadioButton* ofromfile;
Gtk::RadioButton* iunchanged;
@ -95,6 +99,7 @@ private:
Glib::ustring lastRefFilename;
Glib::ustring camName;
void updateDCP(int dcpIlluminant, Glib::ustring dcp_name);
void updateRenderingIntent (const Glib::ustring &profile);
public:
ICMPanel ();
@ -107,7 +112,8 @@ public:
void wpChanged ();
void opChanged ();
void oiChanged ();
void oiChanged (int n);
void oBPCChanged ();
void ipChanged ();
void gpChanged ();
void GamChanged ();

View File

@ -390,8 +390,8 @@ void Options::setDefaults ()
gimpDir = "";
psDir = "";
customEditorProg = "";
CPBKeys = CPBKT_TID;
editorToSendTo = 1;
liveThumbnails = true;
favoriteDirs.clear();
tpOpen.clear ();
//crvOpen.clear ();
@ -468,6 +468,7 @@ void Options::setDefaults ()
fastexport_icm_working = "ProPhoto";
fastexport_icm_output = "RT_sRGB";
fastexport_icm_outputIntent = rtengine::RI_RELATIVE;
fastexport_icm_outputBPC = true;
fastexport_icm_gamma = "default";
fastexport_resize_enabled = true;
fastexport_resize_scale = 1;
@ -633,6 +634,7 @@ void Options::setDefaults ()
rtSettings.monitorProfile = Glib::ustring();
rtSettings.monitorIntent = rtengine::RI_RELATIVE;
rtSettings.monitorBPC = true;
rtSettings.autoMonitorProfile = false;
rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows)
rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile"
@ -1087,10 +1089,6 @@ int Options::readFromFile (Glib::ustring fname)
thumbInterp = keyFile.get_integer ("File Browser", "ThumbnailInterpolation");
}
if (keyFile.has_key ("File Browser", "LiveThumbnails")) {
liveThumbnails = keyFile.get_boolean ("File Browser", "LiveThumbnails");
}
if (keyFile.has_key ("File Browser", "FavoriteDirs")) {
favoriteDirs = keyFile.get_string_list ("File Browser", "FavoriteDirs");
}
@ -1472,6 +1470,10 @@ int Options::readFromFile (Glib::ustring fname)
rtSettings.monitorIntent = static_cast<rtengine::RenderingIntent>(keyFile.get_integer("Color Management", "Intent"));
}
if (keyFile.has_key ("Color Management", "MonitorBPC")) {
rtSettings.monitorBPC = keyFile.get_boolean("Color Management", "MonitorBPC");
}
if (keyFile.has_key ("Color Management", "CRI")) {
rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI");
}
@ -1728,6 +1730,10 @@ int Options::readFromFile (Glib::ustring fname)
fastexport_icm_outputIntent = static_cast<rtengine::RenderingIntent>(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" ));
}
if (keyFile.has_key ("Fast Export", "fastexport_icm_output_bpc" )) {
fastexport_icm_outputBPC = keyFile.get_boolean ("Fast Export", "fastexport_icm_output_bpc" );
}
if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) {
fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" );
}
@ -1787,13 +1793,9 @@ int Options::readFromFile (Glib::ustring fname)
}
} catch (Glib::Error &err) {
if (options.rtSettings.verbose) {
printf("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
}
printf("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
} catch (...) {
if (options.rtSettings.verbose) {
printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str());
}
printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str());
}
return 1;
@ -1884,7 +1886,6 @@ int Options::saveToFile (Glib::ustring fname)
keyFile.set_integer_list ("File Browser", "ParseExtensionsEnabled", pextena);
keyFile.set_integer ("File Browser", "ThumbnailArrangement", fbArrangement);
keyFile.set_integer ("File Browser", "ThumbnailInterpolation", thumbInterp);
keyFile.set_boolean ("File Browser", "LiveThumbnails", liveThumbnails);
Glib::ArrayHandle<Glib::ustring> pfav = favoriteDirs;
keyFile.set_string_list ("File Browser", "FavoriteDirs", pfav);
Glib::ArrayHandle<Glib::ustring> pren = renameTemplates;
@ -2036,6 +2037,7 @@ int Options::saveToFile (Glib::ustring fname)
keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab);
keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut);
keyFile.set_integer ("Color Management", "Intent", rtSettings.monitorIntent);
keyFile.set_boolean ("Color Management", "MonitorBPC", rtSettings.monitorBPC);
keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice);
keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey);
keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc);
@ -2104,6 +2106,7 @@ int Options::saveToFile (Glib::ustring fname)
keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working );
keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output );
keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent );
keyFile.set_boolean ("Fast Export", "fastexport_icm_output_bpc" , fastexport_icm_outputBPC );
keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma );
keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled );
keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale );

View File

@ -180,9 +180,7 @@ public:
int editorToSendTo;
int maxThumbnailHeight;
std::size_t maxCacheEntries;
ThFileType thumbnailFormat;
int thumbInterp; // 0: nearest, 1: bilinear
bool liveThumbnails;
std::vector<Glib::ustring> parseExtensions; // List containing all extensions type
std::vector<int> parseExtensionsEnabled; // List of bool to retain extension or not
std::vector<Glib::ustring> parsedExtensions; // List containing all retained extensions (lowercase)
@ -203,7 +201,6 @@ public:
bool showFileNames;
bool filmStripShowFileNames;
bool tabbedUI;
int previewSizeTab, previewSizeBrowser;
bool rememberZoomAndPan;
int multiDisplayMode; // 0=none, 1=Edit panels on other display
std::vector<double> cutOverlayBrush; // Red;Green;Blue;Alpha , all ranging 0..1
@ -219,7 +216,6 @@ public:
//int histogramWorking; // 0=disabled, 1=left pane, 2=right pane
bool histogramBar;
bool histogramFullMode;
bool showProfileSelector;
bool FileBrowserToolbarSingleRow;
bool hideTPVScrollbar;
bool UseIconNoText;
@ -270,6 +266,7 @@ public:
Glib::ustring fastexport_icm_working;
Glib::ustring fastexport_icm_output;
rtengine::RenderingIntent fastexport_icm_outputIntent;
bool fastexport_icm_outputBPC;
Glib::ustring fastexport_icm_gamma;
bool fastexport_resize_enabled;
double fastexport_resize_scale;

View File

@ -353,8 +353,9 @@ void ParamsEdited::set (bool v)
icm.working = v;
icm.output = v;
icm.outputIntent = v;
icm.outputBPC = v;
icm.gamma = v;
icm.freegamma = v;
icm.freegamma = v;
icm.gampos = v;
icm.slpos = v;
raw.bayersensor.method = v;
@ -847,6 +848,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
icm.working = icm.working && p.icm.working == other.icm.working;
icm.output = icm.output && p.icm.output == other.icm.output;
icm.outputIntent = icm.outputIntent && p.icm.outputIntent == other.icm.outputIntent;
icm.outputBPC = icm.outputBPC && p.icm.outputBPC == other.icm.outputBPC ;
icm.gamma = icm.gamma && p.icm.gamma == other.icm.gamma;
icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma;
icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos;
@ -2210,8 +2212,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.icm.outputIntent = mods.icm.outputIntent;
}
//if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos;
//if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos;
if (icm.outputBPC) {
toEdit.icm.outputBPC = mods.icm.outputBPC;
}
if (icm.gampos) {
toEdit.icm.gampos = dontforceSet && options.baBehav[ADDSET_FREE_OUPUT_GAMMA] ? toEdit.icm.gampos + mods.icm.gampos : mods.icm.gampos;
}

View File

@ -544,6 +544,7 @@ public:
bool working;
bool output;
bool outputIntent;
bool outputBPC;
bool gamma;
bool gampos;
bool slpos;

View File

@ -699,15 +699,19 @@ Gtk::Widget* Preferences::getColorManagementPanel ()
monProfile->append_text (M("PREFERENCES_PROFILE_NONE"));
monProfile->set_active (0);
const std::vector<Glib::ustring> profiles = rtengine::ICCStore::getInstance ()->getProfiles ();
const std::vector<Glib::ustring> profiles = rtengine::ICCStore::getInstance ()->getProfiles (true);
for (std::vector<Glib::ustring>::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile)
monProfile->append_text (*profile);
monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE"));
// same order as the enum
monIntent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL"));
monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE"));
monIntent->append_text (M("PREFERENCES_INTENT_ABSOLUTE"));
monIntent->set_active (1);
monBPC = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_MONBPC")));
monBPC->set_active (true);
iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged));
#if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851
@ -717,22 +721,24 @@ Gtk::Widget* Preferences::getColorManagementPanel ()
Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2));
int row = 0;
colt->attach (*pdlabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2);
colt->attach (*iccDir, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colt->attach (*pdlabel, 0, 1, row, row + 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colt->attach (*iccDir, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
#if !defined(__APPLE__) // monitor profile not supported on apple
++row;
colt->attach (*mplabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2);
colt->attach (*monProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colt->attach (*mplabel, 0, 1, row, row + 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colt->attach (*monProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
#if defined(WIN32)
++row;
colt->attach (*cbAutoMonProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colt->attach (*cbAutoMonProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
#endif
#endif
++row;
colt->attach (*milabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2);
colt->attach (*monIntent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colt->attach (*milabel, 0, 1, row, row + 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colt->attach (*monIntent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4);
mvbcm->pack_start (*monBPC, Gtk::PACK_SHRINK, 4);
#if defined(WIN32)
autoMonProfileToggled();
#endif
@ -1458,15 +1464,16 @@ void Preferences::storePreferences ()
switch (monIntent->get_active_row_number ()) {
default:
case 0:
moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE;
moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL;
break;
case 1:
moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL;
moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE;
break;
case 2:
moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE;
break;
}
moptions.rtSettings.monitorBPC = monBPC->get_active ();
#if defined(WIN32)
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
#endif
@ -1587,16 +1594,17 @@ void Preferences::fillPreferences ()
setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0);
switch (moptions.rtSettings.monitorIntent) {
default:
case rtengine::RI_RELATIVE:
case rtengine::RI_PERCEPTUAL:
monIntent->set_active (0);
break;
case rtengine::RI_PERCEPTUAL:
case rtengine::RI_RELATIVE:
monIntent->set_active (1);
break;
case rtengine::RI_ABSOLUTE:
monIntent->set_active (2);
break;
}
monBPC->set_active (moptions.rtSettings.monitorBPC);
#if defined(WIN32)
cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile);
#endif

View File

@ -97,6 +97,7 @@ protected:
Gtk::FileChooserButton* iccDir;
Gtk::ComboBoxText* monProfile;
Gtk::ComboBoxText* monIntent;
Gtk::CheckButton* monBPC;
Gtk::CheckButton* cbAutoMonProfile;
//Gtk::CheckButton* cbAutocielab;
Gtk::CheckButton* cbciecamfloat;

View File

@ -1,303 +0,0 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rawprocess.h"
#include "options.h"
#include "guiutils.h"
using namespace rtengine;
using namespace rtengine::procparams;
RawProcess::RawProcess () : FoldableToolPanel(this)
{
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4);
dmethod = Gtk::manage (new MyComboBoxText ());
for( size_t i = 0; i < procparams::RAWParams::numMethods; i++) {
dmethod->append_text(procparams::RAWParams::methodstring[i]);
}
dmethod->set_active(0);
hb1->set_tooltip_markup (M("TP_RAW_DMETHOD_TOOLTIP"));
hb1->pack_end (*dmethod, Gtk::PACK_EXPAND_WIDGET, 4);
pack_start( *hb1, Gtk::PACK_SHRINK, 4);
dcbOptions = Gtk::manage (new Gtk::VBox ());
dcbOptions->set_border_width(4);
dcbIterations = Gtk::manage (new Adjuster (M("TP_RAW_DCBITERATIONS"), 0, 5, 1, 2));
dcbIterations->setAdjusterListener (this);
if (dcbIterations->delay < options.adjusterMaxDelay) {
dcbIterations->delay = options.adjusterMaxDelay;
}
dcbIterations->show();
dcbEnhance = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_DCBENHANCE")));
dcbOptions->pack_start(*dcbIterations);
dcbOptions->pack_start(*dcbEnhance);
pack_start( *dcbOptions, Gtk::PACK_SHRINK, 4);
lmmseOptions = Gtk::manage (new Gtk::VBox ());
lmmseOptions->set_border_width(4);
lmmseIterations = Gtk::manage (new Adjuster (M("TP_RAW_LMMSEITERATIONS"), 0, 6, 1, 2));
lmmseIterations->setAdjusterListener (this);
lmmseIterations->set_tooltip_markup (M("TP_RAW_LMMSE_TOOLTIP"));
if (lmmseIterations->delay < options.adjusterMaxDelay) {
lmmseIterations->delay = options.adjusterMaxDelay;
}
lmmseIterations->show();
lmmseOptions->pack_start(*lmmseIterations);
pack_start( *lmmseOptions, Gtk::PACK_SHRINK, 4);
pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 );
ccSteps = Gtk::manage (new Adjuster (M("TP_RAW_FALSECOLOR"), 0, 5, 1, 0 ));
ccSteps->setAdjusterListener (this);
if (ccSteps->delay < options.adjusterMaxDelay) {
ccSteps->delay = options.adjusterMaxDelay;
}
ccSteps->show();
pack_start( *ccSteps, Gtk::PACK_SHRINK, 4);
//pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 );
//allOptions = Gtk::manage (new Gtk::VBox ());
//allOptions->set_border_width(2);
//allEnhance = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_ALLENHANCE")));
//allOptions->pack_start(*allEnhance);
//pack_start( *allOptions, Gtk::PACK_SHRINK, 4);
methodconn = dmethod->signal_changed().connect( sigc::mem_fun(*this, &RawProcess::methodChanged) );
dcbEnhconn = dcbEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &RawProcess::dcbEnhanceChanged), true);
//allEnhconn = allEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &RawProcess::allEnhanceChanged), true);
}
void RawProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
{
disableListener ();
methodconn.block (true);
dcbEnhconn.block (true);
//allEnhconn.block (true);
dmethod->set_active(procparams::RAWParams::numMethods);
for( size_t i = 0; i < procparams::RAWParams::numMethods; i++)
if( pp->raw.dmethod == procparams::RAWParams::methodstring[i]) {
dmethod->set_active(i);
oldSelection = i;
break;
}
if(pedited ) {
ccSteps->setEditedState (pedited->raw.ccSteps ? Edited : UnEdited);
dcbIterations->setEditedState ( pedited->raw.dcbIterations ? Edited : UnEdited);
dcbEnhance->set_inconsistent(!pedited->raw.dcbEnhance);
//allEnhance->set_inconsistent(!pedited->raw.allEnhance);
lmmseIterations->setEditedState ( pedited->raw.lmmseIterations ? Edited : UnEdited);
if( !pedited->raw.dmethod ) {
dmethod->set_active(procparams::RAWParams::numMethods); // No name
}
}
//allEnhance->set_active(pp->raw.all_enhance);
dcbIterations->setValue (pp->raw.dcb_iterations);
dcbEnhance->set_active(pp->raw.dcb_enhance);
ccSteps->setValue (pp->raw.ccSteps);
if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::dcb] ||
dmethod->get_active_row_number() == procparams::RAWParams::numMethods) {
dcbOptions->show();
} else {
dcbOptions->hide();
}
lmmseIterations->setValue (pp->raw.lmmse_iterations);
if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::lmmse] ||
dmethod->get_active_row_number() == procparams::RAWParams::numMethods) {
lmmseOptions->show();
} else {
lmmseOptions->hide();
}
// Flase color suppression is applied to all demozaicing method, so don't hide anything
/*if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::eahd] ||
pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::hphd] ||
pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::vng4])
ccSteps->show();
else
ccSteps->hide();*/
lastDCBen = pp->raw.dcb_enhance;
//lastALLen = pp->raw.all_enhance;
methodconn.block (false);
dcbEnhconn.block (false);
//allEnhconn.block (false);
enableListener ();
}
void RawProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited)
{
pp->raw.ccSteps = ccSteps->getIntValue();
pp->raw.dcb_iterations = dcbIterations->getIntValue();
pp->raw.dcb_enhance = dcbEnhance->get_active();
//pp->raw.all_enhance = allEnhance->get_active();
pp->raw.lmmse_iterations = lmmseIterations->getIntValue();
int currentRow = dmethod->get_active_row_number();
if( currentRow >= 0 && currentRow < procparams::RAWParams::numMethods) {
pp->raw.dmethod = procparams::RAWParams::methodstring[currentRow];
}
if (pedited) {
pedited->raw.ccSteps = ccSteps->getEditedState ();
pedited->raw.dmethod = dmethod->get_active_row_number() != procparams::RAWParams::numMethods;
pedited->raw.dcbIterations = dcbIterations->getEditedState ();
pedited->raw.dcbEnhance = !dcbEnhance->get_inconsistent();
//pedited->raw.allEnhance = !allEnhance->get_inconsistent();
pedited->raw.lmmseIterations = lmmseIterations->getEditedState ();
}
}
void RawProcess::setBatchMode(bool batchMode)
{
dmethod->append_text (M("GENERAL_UNCHANGED"));
dmethod->set_active(procparams::RAWParams::numMethods); // No name
dcbOptions->hide();
lmmseOptions->hide();
ToolPanel::setBatchMode (batchMode);
ccSteps->showEditedCB ();
dcbIterations->showEditedCB ();
lmmseIterations->showEditedCB ();
}
void RawProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited)
{
dcbIterations->setDefault( defParams->raw.dcb_iterations);
lmmseIterations->setDefault( defParams->raw.lmmse_iterations);
ccSteps->setDefault (defParams->raw.ccSteps);
if (pedited) {
dcbIterations->setDefaultEditedState( pedited->raw.dcbIterations ? Edited : UnEdited);
lmmseIterations->setDefaultEditedState( pedited->raw.lmmseIterations ? Edited : UnEdited);
ccSteps->setDefaultEditedState(pedited->raw.ccSteps ? Edited : UnEdited);
} else {
dcbIterations->setDefaultEditedState( Irrelevant );
lmmseIterations->setDefaultEditedState( Irrelevant );
ccSteps->setDefaultEditedState(Irrelevant );
}
}
void RawProcess::adjusterChanged (Adjuster* a, double newval)
{
if (listener) {
if (a == dcbIterations) {
listener->panelChanged (EvDemosaicDCBIter, a->getTextValue() );
} else if (a == ccSteps) {
listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() );
} else if (a == lmmseIterations) {
listener->panelChanged (EvDemosaicLMMSEIter, a->getTextValue() );
}
}
}
void RawProcess::methodChanged ()
{
int curSelection = dmethod->get_active_row_number();
if ( curSelection == procparams::RAWParams::dcb) {
dcbOptions->show();
} else {
dcbOptions->hide();
}
if ( curSelection == procparams::RAWParams::lmmse) {
lmmseOptions->show();
} else {
lmmseOptions->hide();
}
Glib::ustring methodName = "";
bool ppreq = false;
if( curSelection >= 0 && curSelection < procparams::RAWParams::numMethods) {
methodName = procparams::RAWParams::methodstring[curSelection];
if (curSelection == procparams::RAWParams::mono || oldSelection == procparams::RAWParams::mono) {
ppreq = true;
}
}
oldSelection = curSelection;
if (listener) {
listener->panelChanged (ppreq ? EvDemosaicMethodPreProc : EvDemosaicMethod, methodName);
}
}
void RawProcess::dcbEnhanceChanged ()
{
if (batchMode) {
if (dcbEnhance->get_inconsistent()) {
dcbEnhance->set_inconsistent (false);
dcbEnhconn.block (true);
dcbEnhance->set_active (false);
dcbEnhconn.block (false);
} else if (lastDCBen) {
dcbEnhance->set_inconsistent (true);
}
lastDCBen = dcbEnhance->get_active ();
}
if (listener) {
listener->panelChanged (EvDemosaicDCBEnhanced, dcbEnhance->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
}
}
/*void RawProcess::allEnhanceChanged ()
{
if (batchMode) {
if (allEnhance->get_inconsistent()) {
allEnhance->set_inconsistent (false);
allEnhconn.block (true);
allEnhance->set_active (false);
allEnhconn.block (false);
}
else if (lastALLen)
allEnhance->set_inconsistent (true);
lastALLen = allEnhance->get_active ();
}
if (listener)
listener->panelChanged (EvDemosaicALLEnhanced, allEnhance->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED"));
}*/

View File

@ -1,64 +0,0 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _RAWPROCESS_H_
#define _RAWPROCESS_H_
#include <gtkmm.h>
#include "adjuster.h"
#include "guiutils.h"
#include "toolpanel.h"
class RawProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel
{
protected:
MyComboBoxText* dmethod;
Gtk::Label* methodl;
Adjuster* ccSteps;
Gtk::VBox *dcbOptions;
Adjuster* dcbIterations;
Gtk::CheckButton* dcbEnhance;
//Gtk::VBox *allOptions;
//Gtk::CheckButton* allEnhance;
Gtk::VBox *lmmseOptions;
Adjuster* lmmseIterations;
bool lastDCBen;
int oldSelection;
//bool lastALLen;
sigc::connection methodconn, dcbEnhconn; //,allEnhconn;
public:
RawProcess ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = NULL);
void setBatchMode (bool batchMode);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = NULL);
void methodChanged ();
void adjusterChanged (Adjuster* a, double newval);
void dcbEnhanceChanged();
//void allEnhanceChanged();
};
#endif

View File

@ -1,69 +0,0 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include <thumbbrowserentry.h>
FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname)
: ThumbBrowserEntryBase (fname), thumbnail(thm)
{
previewOwner = false;
italicstyle = thumbnail->getType() != FT_Raw;
datetimeline = thumbnail->getDateTimeString ();
exifline = thumbnail->getExifString ();
}
void ThumbBrowserEntry::obtainThumbnailSize ()
{
if (thumbnail) {
thumbnail->getThumbnailSize (prew, preh);
}
}
Glib::RefPtr<Gdk::Pixbuf> ThumbBrowserEntry::editedIcon;
Glib::RefPtr<Gdk::Pixbuf> ThumbBrowserEntry::recentlySavedIcon;
Glib::RefPtr<Gdk::Pixbuf> ThumbBrowserEntry::enqueuedIcon;
std::vector<Glib::RefPtr<Gdk::Pixbuf> > ThumbBrowserEntry::getIconsOnImageArea ()
{
std::vector<Glib::RefPtr<Gdk::Pixbuf> > ret;
if (!thumbnail) {
return ret;
}
if (thumbnail->hasProcParams() && editedIcon) {
ret.push_back (editedIcon);
}
if (thumbnail->isRecentlySaved() && recentlySavedIcon) {
ret.push_back (recentlySavedIcon);
}
if (thumbnail->isEnqueued () && enqueuedIcon) {
ret.push_back (enqueuedIcon);
}
return ret;
}
ThumbnailButtonSet* ThumbBrowserEntry::getThumbButtonSet ()
{
return (ThumbnailButtonSet*)buttonSet;
}

655
tools/color_management.svg Normal file
View File

@ -0,0 +1,655 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="297mm"
height="210mm"
viewBox="0 0 1052.3622 744.09448"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="color_management.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0.0"
refX="0.0"
id="marker10113"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path10115"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#b049e1;stroke-width:1pt;stroke-opacity:1;fill:#b049e1;fill-opacity:1"
transform="scale(0.2) rotate(180) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0.0"
refX="0.0"
id="marker9939"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path9941"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#b049e1;stroke-width:1pt;stroke-opacity:1;fill:#b049e1;fill-opacity:1"
transform="scale(0.2) rotate(180) translate(6,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible;"
id="marker9189"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Send"
inkscape:collect="always">
<path
transform="scale(0.2) rotate(180) translate(6,0)"
style="fill-rule:evenodd;stroke:#b049e1;stroke-width:1pt;stroke-opacity:1;fill:#b049e1;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path9191" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible;"
id="marker4296"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Send">
<path
transform="scale(0.2) rotate(180) translate(6,0)"
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path4298" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0.0"
refX="0.0"
id="marker5710"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path5712"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#dd8a7e;stroke-width:1pt;stroke-opacity:1;fill:#dd8a7e;fill-opacity:1"
transform="scale(0.2) rotate(180) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4281"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#dd8a7e;stroke-width:1pt;stroke-opacity:1;fill:#dd8a7e;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0.0"
refX="0.0"
id="marker5062"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path5064"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
transform="scale(0.2) rotate(180) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0.0"
refX="0.0"
id="marker4998"
style="overflow:visible;"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path5000"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
transform="scale(0.2) rotate(180) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Send"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4287"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#add352;stroke-width:1pt;stroke-opacity:1;fill:#add352;fill-opacity:1"
transform="scale(0.2) rotate(180) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="marker4756"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4758"
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#439872;stroke-opacity:1;fill:#439872;fill-opacity:1"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) rotate(180) translate(1,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4272"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
transform="scale(0.8) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4293"
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#439872;stroke-opacity:1;fill:#439872;fill-opacity:1"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) rotate(180) translate(1,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="marker4574"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4576"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4290"
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#439872;stroke-opacity:1;fill:#439872;fill-opacity:1"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) translate(1,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4275"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#439872;stroke-width:1pt;stroke-opacity:1;fill:#439872;fill-opacity:1"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="489.45925"
inkscape:cy="597.68828"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1018"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-308.26772)">
<path
style="fill:none;fill-rule:evenodd;stroke:#b049e1;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker10113)"
d="m 871.82971,670.64952 0,50.45433"
id="path10111"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path9187"
d="m 548.40112,670.64952 0,50.45433"
style="fill:none;fill-rule:evenodd;stroke:#b049e1;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9189)" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path4996"
d="m 666.10066,635.08041 c 31.37496,-1.49737 37.63639,-52.56259 42.33564,-92.54896 4.49653,-38.26138 50.69343,-47.46535 84.39106,-0.36174"
style="fill:none;fill-rule:evenodd;stroke:#439872;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:28, 7;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker5062)" />
<rect
y="579.82043"
x="423.40112"
height="92.857147"
width="250"
id="rect5442"
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#439872;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:28, 7;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker4998)"
d="m 492.32787,440.64952 c 16.21054,39.59059 30.90653,57.74251 30.90653,98.45433"
id="path4200"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4218"
d="m 534.03112,397.20982 c 130.59165,0 248.85289,32.24077 287.24555,140.161"
style="fill:none;fill-rule:evenodd;stroke:#add352;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send)" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:0.71270716;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect10399"
width="169.52106"
height="31.025021"
x="599.28571"
y="405.36221" />
<path
style="fill:none;fill-rule:evenodd;stroke:#dd8a7e;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5710)"
d="m 394.53933,434.19203 c -31.92389,48.56808 -43.48293,40.68411 -98.97824,105.07044"
id="path4202"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:0.71270716;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect7950"
width="167.56383"
height="42.952511"
x="236.2933"
y="459.36221" />
<rect
style="opacity:1;fill:#e1f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4190"
width="250"
height="29.285715"
x="423.40112"
y="550.53473" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="436.6803"
y="569.3158"
id="text4146"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="436.6803"
y="569.3158"
id="tspan4180"
style="font-size:15px">Output ICC profile &amp; intent</tspan></text>
<rect
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5444"
width="250"
height="92.857147"
x="746.82971"
y="579.82043" />
<rect
y="550.53473"
x="746.82971"
height="29.285715"
width="250"
id="rect5408"
style="opacity:1;fill:#e1f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="762.99524"
y="569.3158"
id="text4152"
sodipodi:linespacing="125%"><tspan
id="tspan4270"
sodipodi:role="line"
x="762.99524"
y="569.3158"
style="font-size:15px">Monitor ICC profile &amp; intent</tspan></text>
<g
id="g9171"
transform="translate(65.286377,16)">
<rect
y="713.55499"
x="731.54333"
height="80"
width="150"
id="rect4196"
style="opacity:1;fill:#dcb7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="125%"
id="text4158"
y="761.94305"
x="762.66943"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="761.94305"
x="762.66943"
id="tspan4160"
sodipodi:role="line">Monitor</tspan></text>
</g>
<g
id="g9176"
transform="translate(68.218231,40)">
<rect
y="832.55505"
x="395.18289"
height="80"
width="170"
id="rect4198"
style="opacity:1;fill:#dcb7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="125%"
id="text4162"
y="880.94312"
x="441.62637"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="880.94312"
x="441.62637"
id="tspan4164"
sodipodi:role="line">Printer</tspan></text>
</g>
<g
id="g9166"
transform="translate(71.411163,20)">
<rect
style="opacity:1;fill:#dcb7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4210"
width="200"
height="80"
x="376.98996"
y="711.33673" />
<text
sodipodi:linespacing="125%"
id="text4170"
y="757.54401"
x="417.12546"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="757.54401"
x="417.12546"
id="tspan4172"
sodipodi:role="line">Output file</tspan></text>
</g>
<rect
y="457.36221"
x="469.28571"
height="31.025021"
width="82.14286"
id="rect7952"
style="opacity:1;fill:#ffffff;fill-opacity:0.71270716;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="471.19366"
y="469.87708"
id="text4182"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4184"
x="471.19366"
y="469.87708"
style="font-size:10px">Soft-proofing path</tspan><tspan
sodipodi:role="line"
x="471.19366"
y="482.37708"
style="font-size:10px"
id="tspan10377">(Output Black Point Compensation)</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4204"
y="471.25275"
x="318.36606"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="471.25275"
x="318.36606"
id="tspan4206"
sodipodi:role="line"
style="font-size:10px;text-align:center;text-anchor:middle">Only if</tspan><tspan
y="483.75275"
x="318.36606"
sodipodi:role="line"
style="font-size:10px;text-align:center;text-anchor:middle"
id="tspan5382">options.rtSettings.HistogramWorking = 1</tspan><tspan
y="496.25275"
x="318.36606"
sodipodi:role="line"
style="font-size:10px;text-align:center;text-anchor:middle"
id="tspan10383">(Output Black Point Compensation)</tspan></text>
<rect
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4186"
width="180"
height="80"
x="359.46707"
y="361.55499" />
<g
id="g4220"
transform="translate(322.64831,127.10442)">
<text
sodipodi:linespacing="125%"
id="text4142"
y="271.17874"
x="56.132729"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="271.17874"
x="56.132729"
id="tspan4144"
sodipodi:role="line">L*a*b image</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4214"
y="291.69702"
x="56.868813"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="291.69702"
x="56.868813"
id="tspan4216"
sodipodi:role="line">End of pipeline</tspan></text>
</g>
<text
sodipodi:linespacing="125%"
id="text5364"
y="417.30566"
x="599.33655"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="417.30566"
x="599.33655"
id="tspan5366"
sodipodi:role="line"
style="font-size:10px">Normal path</tspan><tspan
y="429.80566"
x="599.33655"
sodipodi:role="line"
style="font-size:10px"
id="tspan10375">(Monitor Black Point Compensation)</tspan></text>
<rect
style="opacity:1;fill:#8bd8d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5378"
width="300"
height="92.857147"
x="89.115433"
y="579.82043" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="100.83148"
y="648.47211"
id="text5374"
sodipodi:linespacing="125%"><tspan
style="font-size:10px"
sodipodi:role="line"
id="tspan5376"
x="100.83148"
y="648.47211">Used fo image analysis <tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold'"
id="tspan7948">only</tspan> with</tspan><tspan
style="font-size:10px"
sodipodi:role="line"
x="100.83148"
y="660.97211"
id="tspan5380">options.rtSettings.HistogramWorking = 1</tspan></text>
<text
sodipodi:linespacing="125%"
id="text5394"
y="648.47211"
x="436.97083"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="648.47211"
x="436.97083"
id="tspan5396"
sodipodi:role="line"
style="font-size:10px">Used fo image analysis with</tspan><tspan
id="tspan5398"
y="660.97211"
x="436.97083"
sodipodi:role="line"
style="font-size:10px">options.rtSettings.HistogramWorking = 0</tspan></text>
<rect
y="550.53473"
x="89.115433"
height="29.285715"
width="300"
id="rect5406"
style="opacity:1;fill:#e1f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="100.88519"
y="569.3158"
id="text4136"
sodipodi:linespacing="125%"><tspan
id="tspan4266"
sodipodi:role="line"
x="100.88519"
y="569.3158"
style="font-size:15px">Working space profile (output intent)</tspan></text>
<text
sodipodi:linespacing="125%"
id="text6976"
y="609.3158"
x="99.218933"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:22.5px"
y="609.3158"
x="99.218933"
sodipodi:role="line"
id="tspan6980">&quot;Working&quot; image</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="436.25916"
y="609.3158"
id="text6982"
sodipodi:linespacing="125%"><tspan
id="tspan6986"
sodipodi:role="line"
x="436.25916"
y="609.3158"
style="font-size:22.5px">Output image *</tspan></text>
<text
sodipodi:linespacing="125%"
id="text7002"
y="609.3158"
x="762.25916"
style="font-style:normal;font-weight:normal;font-size:22.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:22.5px"
y="609.3158"
x="762.25916"
sodipodi:role="line"
id="tspan7004">Preview image</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#b049e1;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9939)"
d="m 548.40112,810.64952 0,50.45433"
id="path9937"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="69.700523"
y="1008.9257"
id="text10389"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan10391"
x="69.700523"
y="1008.9257"
style="font-size:12.5px">* When options.rtSettings.HistogramWorking = 1 and soft-proofing is enabled, the Output image does not really exist,</tspan><tspan
sodipodi:role="line"
x="69.700523"
y="1024.5508"
style="font-size:12.5px"
id="tspan10393"> i.e. no memory is allocated, the CMM only makes a double conversion of each pixel of the Lab image</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1 @@
spGamutCheck.png,w22,actions

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -0,0 +1,2 @@
unchanged-22.png,w22,actions
unchanged-18.png,w18,actions

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 45 KiB