Custom TRC Tone response curve and Illuminant - change Histogram - RGB and Lab values - for output (screen, TIF, JPG..) (#5949)
* Change TRC in the process * Improve GUI slope * Add tooltip output profile * Various change to enable and tooltip * Chnage rtthumbnail * Small change tooltip trc * Another small change tooltip * Improve GUI - change default TRC BT709 - change tooltip * Other GUI improvment * Small changes to BT709 values * Various change to TRC - add illuminant working profile * Change labels tooltip TRC illuminant * Display wp in console if wp provided * Change tooltip * Change max wlope * Init trc + illum + primaries * Add black point compensation * Change location abstract * Fixed bug with rtthumbnail... * Added tooltip * Logscale for wslope * Change tooltip abstract * Change labels tooltips abstract profile * Added 6 sliders custom primaries X and Y * Change GUI custom primaries * Use custom primaries abstract profiles * Tooltip with primaries red green blue * Fixed warning gtk * Change one tooltip * Change range custom primaries * Change GUI default Primaries * Change one tooltip * Speedup for trc * Rendering intent for abstract profile * Hide intent abstract * Preserve neutral tones * Chnage settings preserves neutral tones * Improve GUI * Improvment to preserv * Clean code - speedup TRC when illuminant and primaries default * Change label * Change bad default value Blux * Add forgoten illuminant when selecting primaries * clean code * Change labels * improve workingtrc for LA * Change default primaries when select default * Added others working profile to primaries * Change labels and GUI * Change tooltip * CIExy diagram displaying the primaries (interactive) and the white point (#6207) * Ciexy diagram * Change to Ciexy graph * Change graph and defaut coordonates * Various changes to graph - params * Disable setListener(ToolPanelListener) * Add some graduation to graph * Clean comment code graph * Change radius 0 * Enable sensitive graph Ciexy * update Ciexy graph with primaries * Remove reset button graph * Change labels and behavior * First step third spot green * Second step 3rd spot green * First try 3 primaries graph Ciexy * Fixed bad behavior in lab grid * Fixed another bad behavior graph * Clean and comment code * Change default gamma * More accurate graph Cie xy * Added white point to Ciexy graph * Added tooltip Cie xy diagram * Improvment when illuminant change * Refine diagram CIE xy - added WP 2000K * White point D120 + tooltip * Change label * Change labels * Change tooltips * Improve diagram CIE xy with parabolic * Other parabolic to improve Cie xy diagram * Small change GUI * Added Label CIE xy - change labels * Change behavior when none - change labels * Improve gUI and trys to fix LGTM alerts * CIE xy change set sensitive * Improve tooltip primaries sliders * Adapt tooltip to new labels * Fixed crash and some bad behavior * First fix bad behavior with some primaries * Second fixed bad behavior primaries * Third fixed bad behavior primaries * Change white point BestRGB * Change order rgb in history msg Ciexy * Change tooltip * Change tooltip * Improve GUI primaries * Illuminant 1500K - display in console matrix XYZ-RGB * Improve GUI illuminant * Change a tooltip * Somme changes to GUI and verbose * Test code for wprim in read * clean code for wprims * further cleanups, not tested * Some cleanups and bugfixes, #5949 * Simplify `std::unique_ptr<>` dereferencing Also some minor cleanups. * Some changes suggested by Floessie * Others change suggested * Others changes suggested by Floessie * Forgotten change in procparams.cc * Added black and white for use with the primaries channel mixer * Small change behavior GUI - illuminant * Change pragma omp in iplab2rgb * Add enums and clean up * Remove unused code icmpanel.cc * Fix LGTM alert, #5949 Co-authored-by: Ingo Weyrich <heckflosse67@gmx.de> Co-authored-by: Flössie <floessie.mail@gmail.com>
This commit is contained in:
@@ -16,18 +16,20 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "rtengine.h"
|
||||
#include "image8.h"
|
||||
#include "imagefloat.h"
|
||||
#include "labimage.h"
|
||||
#include "improcfun.h"
|
||||
#include <glibmm/ustring.h>
|
||||
#include "iccstore.h"
|
||||
#include "iccmatrices.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "alignedbuffer.h"
|
||||
#include "color.h"
|
||||
#include "iccmatrices.h"
|
||||
#include "iccstore.h"
|
||||
#include "image8.h"
|
||||
#include "imagefloat.h"
|
||||
#include "improcfun.h"
|
||||
#include "labimage.h"
|
||||
#include "procparams.h"
|
||||
#include "rtengine.h"
|
||||
#include "settings.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace rtengine
|
||||
{
|
||||
@@ -120,6 +122,19 @@ inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double r
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
float gammalog(float x, float p, float s, float g3, float g4)
|
||||
{
|
||||
return x <= g3 ? x * s : (1.f + g4) * xexpf(xlogf(x) / p) - g4;//continuous
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
vfloat gammalog(vfloat x, vfloat p, vfloat s, vfloat g3, vfloat g4)
|
||||
{
|
||||
return vself(vmaskf_le(x, g3), x * s, (F2V(1.f) + g4) * xexpf(xlogf(x) / p) - g4);//continuous
|
||||
}
|
||||
#endif
|
||||
|
||||
// Used in ImProcCoordinator::updatePreviewImage (rtengine/improccoordinator.cc)
|
||||
// Crop::update (rtengine/dcrop.cc)
|
||||
// Thumbnail::processImage (rtengine/rtthumbnail.cc)
|
||||
@@ -373,8 +388,31 @@ Imagefloat* ImProcFunctions::lab2rgbOut(LabImage* lab, int cx, int cy, int cw, i
|
||||
return image;
|
||||
}
|
||||
|
||||
void ImProcFunctions::preserv(LabImage *nprevl, LabImage *provis, int cw, int ch)
|
||||
{//avoid too strong in middle values chroma when changing primaries
|
||||
float pres = 0.01f * params->icm.preser;
|
||||
float neutral = 2000000000.f;//if a2 + b2 < 200000000 scale 0..100 a and b about : 140 > a & b > -140 decrease effect
|
||||
float medneutral = 10000000.f;//plein effect 10 > a & b > -10
|
||||
float aaneu = 1.f / (medneutral - neutral);
|
||||
float bbneu = - aaneu * neutral;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic, 16) nowait
|
||||
#endif
|
||||
for (int i = 0; i < ch; ++i)
|
||||
for (int j = 0; j < cw; ++j) {
|
||||
float neu = SQR(provis->a[i][j]) + SQR(provis->b[i][j]);
|
||||
if (neu < medneutral) {//plein effect
|
||||
nprevl->a[i][j] = intp(pres, provis->a[i][j], nprevl->a[i][j]);
|
||||
nprevl->b[i][j] = intp(pres, provis->b[i][j], nprevl->b[i][j]);
|
||||
} else if (neu < neutral) {//decrease effect
|
||||
float presred = aaneu * neu + bbneu;
|
||||
nprevl->a[i][j] = intp(pres * presred, provis->a[i][j], nprevl->a[i][j]);
|
||||
nprevl->b[i][j] = intp(pres * presred, provis->b[i][j], nprevl->b[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, const Glib::ustring &profile, double gampos, double slpos, cmsHTRANSFORM &transform, bool normalizeIn, bool normalizeOut, bool keepTransForm) const
|
||||
void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, Glib::ustring &profile, double gampos, double slpos, int &illum, int prim, cmsHTRANSFORM &transform, bool normalizeIn, bool normalizeOut, bool keepTransForm) const
|
||||
{
|
||||
const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile);
|
||||
|
||||
@@ -394,6 +432,163 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
}
|
||||
};
|
||||
|
||||
if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1") {
|
||||
if (settings->verbose) {
|
||||
printf("Profile=%s\n", profile.c_str());
|
||||
}
|
||||
} else {
|
||||
if (settings->verbose) {
|
||||
printf("profile not accepted\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mul == -5 && gampos == 2.4 && slpos == 12.92310) {//must be change if we change settings RT sRGB
|
||||
//only in this case we can shortcut..all process..no gamut control..because we reduce...leads to very small differences, but big speedup
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic, 16) if (multiThread)
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < ch; ++i)
|
||||
for (int j = 0; j < cw; ++j) {
|
||||
float r = src->r(i, j);
|
||||
float g = src->g(i, j);
|
||||
float b = src->b(i, j);
|
||||
r = (Color::igammatab_srgb[r]) / 65535.f;
|
||||
g = (Color::igammatab_srgb[g]) / 65535.f;
|
||||
b = (Color::igammatab_srgb[b]) / 65535.f;
|
||||
dst->r(i, j) = r;
|
||||
dst->g(i, j) = g;
|
||||
dst->b(i, j) = b;
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (mul == 1 ||(params->icm.wprim == ColorManagementParams::Primaries::DEFAULT && params->icm.will == ColorManagementParams::Illuminant::DEFAULT)) {//shortcut and speedup when no call primaries and illuminant - no gamut control...in this case be carefull
|
||||
GammaValues g_a; //gamma parameters
|
||||
double pwr = 1.0 / static_cast<double>(gampos);
|
||||
Color::calcGamma(pwr, slpos, g_a); // call to calcGamma with selected gamma and slope
|
||||
|
||||
#ifdef _OPENMP
|
||||
# pragma omp parallel for schedule(dynamic,16) if (multiThread)
|
||||
#endif
|
||||
for (int y = 0; y < ch; ++y) {
|
||||
int x = 0;
|
||||
#ifdef __SSE2__
|
||||
for (; x < cw - 3; x += 4) {
|
||||
STVFU(dst->r(y,x), F2V(65536.f) * gammalog(LVFU(src->r(y,x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4])));
|
||||
STVFU(dst->g(y,x), F2V(65536.f) * gammalog(LVFU(src->g(y,x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4])));
|
||||
STVFU(dst->b(y,x), F2V(65536.f) * gammalog(LVFU(src->b(y,x)), F2V(gampos), F2V(slpos), F2V(g_a[3]), F2V(g_a[4])));
|
||||
}
|
||||
#endif
|
||||
for (; x < cw; ++x) {
|
||||
dst->r(y,x) = 65536.f * gammalog(src->r(y,x), gampos, slpos, g_a[3], g_a[4]);
|
||||
dst->g(y,x) = 65536.f * gammalog(src->g(y,x), gampos, slpos, g_a[3], g_a[4]);
|
||||
dst->b(y,x) = 65536.f * gammalog(src->b(y,x), gampos, slpos, g_a[3], g_a[4]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
float redxx = params->icm.redx;
|
||||
float redyy = params->icm.redy;
|
||||
float bluxx = params->icm.blux;
|
||||
float bluyy = params->icm.bluy;
|
||||
float grexx = params->icm.grex;
|
||||
float greyy = params->icm.grey;
|
||||
|
||||
if (prim == 12) {//convert datas area to xy
|
||||
float redgraphx = params->icm.labgridcieALow;
|
||||
float redgraphy = params->icm.labgridcieBLow;
|
||||
float blugraphx = params->icm.labgridcieAHigh;
|
||||
float blugraphy = params->icm.labgridcieBHigh;
|
||||
float gregraphx = params->icm.labgridcieGx;
|
||||
float gregraphy = params->icm.labgridcieGy;
|
||||
redxx = 0.55f * (redgraphx + 1.f) - 0.1f;
|
||||
redxx = rtengine::LIM(redxx, 0.41f, 1.f);//limit values for xy (arbitrary)
|
||||
redyy = 0.55f * (redgraphy + 1.f) - 0.1f;
|
||||
redyy = rtengine::LIM(redyy, 0.f, 0.7f);
|
||||
bluxx = 0.55f * (blugraphx + 1.f) - 0.1f;
|
||||
bluxx = rtengine::LIM(bluxx, -0.1f, 0.5f);
|
||||
bluyy = 0.55f * (blugraphy + 1.f) - 0.1f;
|
||||
bluyy = rtengine::LIM(bluyy, -0.1f, 0.5f);
|
||||
grexx = 0.55f * (gregraphx + 1.f) - 0.1f;
|
||||
grexx = rtengine::LIM(grexx, -0.1f, 0.4f);
|
||||
greyy = 0.55f * (gregraphy + 1.f) - 0.1f;
|
||||
greyy = rtengine::LIM(greyy, 0.5f, 1.f);
|
||||
}
|
||||
|
||||
switch (ColorManagementParams::Primaries(prim)) {
|
||||
case ColorManagementParams::Primaries::DEFAULT: {
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::SRGB: {
|
||||
profile = "sRGB";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::ADOBE_RGB: {
|
||||
profile = "Adobe RGB";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::PRO_PHOTO: {
|
||||
profile = "ProPhoto";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::REC2020: {
|
||||
profile = "Rec2020";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::ACES_P1: {
|
||||
profile = "ACESp1";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::WIDE_GAMUT: {
|
||||
profile = "WideGamut";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::ACES_P0: {
|
||||
profile = "ACESp0";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::BRUCE_RGB: {
|
||||
profile = "BruceRGB";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::BETA_RGB: {
|
||||
profile = "Beta RGB";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::BEST_RGB: {
|
||||
profile = "BestRGB";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::CUSTOM: {
|
||||
profile = "Custom";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Primaries::CUSTOM_GRID: {
|
||||
profile = "Custom";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->verbose && prim != 0) {
|
||||
printf("prim=%i Profile Destination=%s\n", prim, profile.c_str());
|
||||
}
|
||||
cmsHTRANSFORM hTransform = nullptr;
|
||||
if (transform) {
|
||||
hTransform = transform;
|
||||
@@ -418,8 +613,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
D60 = 6005 // for ACES AP0 and AP1
|
||||
|
||||
};
|
||||
ColorTemp temp = ColorTemp::D50;
|
||||
|
||||
double tempv4 = 5003.;
|
||||
float p[6]; //primaries
|
||||
|
||||
//primaries for 10 working profiles ==> output profiles
|
||||
@@ -430,6 +624,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.8260;
|
||||
p[4] = 0.1570;
|
||||
p[5] = 0.0180;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D50);
|
||||
} else if (profile == "Adobe RGB") {
|
||||
p[0] = 0.6400; //Adobe primaries
|
||||
p[1] = 0.3300;
|
||||
@@ -437,7 +632,8 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.7100;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
tempv4 = 6504.;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D65);
|
||||
} else if (profile == "sRGB") {
|
||||
p[0] = 0.6400; // sRGB primaries
|
||||
p[1] = 0.3300;
|
||||
@@ -445,7 +641,8 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.6000;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
tempv4 = 6504.;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D65);
|
||||
} else if (profile == "BruceRGB") {
|
||||
p[0] = 0.6400; // Bruce primaries
|
||||
p[1] = 0.3300;
|
||||
@@ -453,14 +650,16 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.6500;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "Beta RGB") {
|
||||
tempv4 = 6504.;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D65);
|
||||
} else if (profile == "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;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D50);
|
||||
} else if (profile == "BestRGB") {
|
||||
p[0] = 0.7347; // Best primaries
|
||||
p[1] = 0.2653;
|
||||
@@ -468,6 +667,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.7750;
|
||||
p[4] = 0.1300;
|
||||
p[5] = 0.0350;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D50);
|
||||
} else if (profile == "Rec2020") {
|
||||
p[0] = 0.7080; // Rec2020 primaries
|
||||
p[1] = 0.2920;
|
||||
@@ -475,7 +675,8 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.7970;
|
||||
p[4] = 0.1310;
|
||||
p[5] = 0.0460;
|
||||
temp = ColorTemp::D65;
|
||||
tempv4 = 6504.;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D65);
|
||||
} else if (profile == "ACESp0") {
|
||||
p[0] = 0.7347; // ACES P0 primaries
|
||||
p[1] = 0.2653;
|
||||
@@ -483,7 +684,8 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 1.0;
|
||||
p[4] = 0.0001;
|
||||
p[5] = -0.0770;
|
||||
temp = ColorTemp::D60;
|
||||
tempv4 = 6004.;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D60);
|
||||
} else if (profile == "ACESp1") {
|
||||
p[0] = 0.713; // ACES P1 primaries
|
||||
p[1] = 0.293;
|
||||
@@ -491,7 +693,8 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.830;
|
||||
p[4] = 0.128;
|
||||
p[5] = 0.044;
|
||||
temp = ColorTemp::D60;
|
||||
tempv4 = 6004.;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D60);
|
||||
} else if (profile == "ProPhoto") {
|
||||
p[0] = 0.7347; //ProPhoto and default primaries
|
||||
p[1] = 0.2653;
|
||||
@@ -499,6 +702,14 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
p[3] = 0.8404;
|
||||
p[4] = 0.0366;
|
||||
p[5] = 0.0001;
|
||||
illum = toUnderlying(ColorManagementParams::Illuminant::D50);
|
||||
} else if (profile == "Custom") {
|
||||
p[0] = redxx;
|
||||
p[1] = redyy;
|
||||
p[2] = grexx;
|
||||
p[3] = greyy;
|
||||
p[4] = bluxx;
|
||||
p[5] = bluyy;
|
||||
} else {
|
||||
p[0] = 0.7347; //default primaries always unused
|
||||
p[1] = 0.2653;
|
||||
@@ -528,27 +739,145 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
|
||||
|
||||
// 7 parameters for smoother curves
|
||||
cmsCIExyY xyD;
|
||||
cmsWhitePointFromTemp(&xyD, (double)temp);
|
||||
if (profile == "ACESp0") {
|
||||
xyD = {0.32168, 0.33767, 1.0};//refine white point to avoid differences
|
||||
Glib::ustring ills = "D50";
|
||||
switch (ColorManagementParams::Illuminant(illum)) {
|
||||
case ColorManagementParams::Illuminant::DEFAULT:
|
||||
case ColorManagementParams::Illuminant::STDA:
|
||||
case ColorManagementParams::Illuminant::TUNGSTEN_2000K:
|
||||
case ColorManagementParams::Illuminant::TUNGSTEN_1500K: {
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D41: {
|
||||
tempv4 = 4100.;
|
||||
ills = "D41";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D50: {
|
||||
tempv4 = 5003.;
|
||||
ills = "D50";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D55: {
|
||||
tempv4 = 5500.;
|
||||
ills = "D55";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D60: {
|
||||
tempv4 = 6004.;
|
||||
ills = "D60";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D65: {
|
||||
tempv4 = 6504.;
|
||||
ills = "D65";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D80: {
|
||||
tempv4 = 8000.;
|
||||
ills = "D80";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D120: {
|
||||
tempv4 = 12000.;
|
||||
ills = "D120";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cmsWhitePointFromTemp(&xyD, tempv4);
|
||||
|
||||
switch (ColorManagementParams::Illuminant(illum)) {
|
||||
case ColorManagementParams::Illuminant::DEFAULT:
|
||||
case ColorManagementParams::Illuminant::D55:
|
||||
case ColorManagementParams::Illuminant::D80: {
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D41: {
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D50: {
|
||||
xyD = {0.3457, 0.3585, 1.0}; // near LCMS values but not perfect... it's a compromise!!
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D60: {
|
||||
xyD = {0.32168, 0.33767, 1.0};
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D65: {
|
||||
xyD = {0.312700492, 0.329000939, 1.0};
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::D120: {
|
||||
xyD = {0.269669, 0.28078, 1.0};
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::STDA: {
|
||||
xyD = {0.447573, 0.407440, 1.0};
|
||||
ills = "stdA 2875K";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::TUNGSTEN_2000K: {
|
||||
xyD = {0.526591, 0.41331, 1.0};
|
||||
ills = "Tungsten 2000K";
|
||||
break;
|
||||
}
|
||||
|
||||
case ColorManagementParams::Illuminant::TUNGSTEN_1500K: {
|
||||
xyD = {0.585703, 0.393157, 1.0};
|
||||
ills = "Tungsten 1500K";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//D41 0.377984 0.381229
|
||||
//D55 0.332424 0.347426
|
||||
//D80 0.293755 0.309185
|
||||
//D75 0.299021 0.314852
|
||||
cmsToneCurve* GammaTRC[3];
|
||||
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, five, gammaParams);//5 = more smoother than 4
|
||||
cmsHPROFILE oprofdef = nullptr;
|
||||
|
||||
const cmsCIExyYTRIPLE Primaries = {
|
||||
{p[0], p[1], 1.0}, // red
|
||||
{p[2], p[3], 1.0}, // green
|
||||
{p[4], p[5], 1.0} // blue
|
||||
};
|
||||
const cmsHPROFILE oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC);
|
||||
cmsFreeToneCurve(GammaTRC[0]);
|
||||
oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC);
|
||||
cmsWriteTag(oprofdef, cmsSigRedTRCTag, GammaTRC[0]);
|
||||
cmsWriteTag(oprofdef, cmsSigGreenTRCTag, GammaTRC[1]);
|
||||
cmsWriteTag(oprofdef, cmsSigBlueTRCTag, GammaTRC[2]);
|
||||
|
||||
//to read XYZ values and illuminant
|
||||
if (rtengine::settings->verbose) {
|
||||
cmsCIEXYZ *redT = static_cast<cmsCIEXYZ*>(cmsReadTag(oprofdef, cmsSigRedMatrixColumnTag));
|
||||
cmsCIEXYZ *greenT = static_cast<cmsCIEXYZ*>(cmsReadTag(oprofdef, cmsSigGreenMatrixColumnTag));
|
||||
cmsCIEXYZ *blueT = static_cast<cmsCIEXYZ*>(cmsReadTag(oprofdef, cmsSigBlueMatrixColumnTag));
|
||||
printf("Illuminant=%s\n", ills.c_str());
|
||||
printf("rX=%f gX=%f bX=%f\n", redT->X, greenT->X, blueT->X);
|
||||
printf("rY=%f gY=%f bY=%f\n", redT->Y, greenT->Y, blueT->Y);
|
||||
printf("rZ=%f gZ=%f bZ=%f\n", redT->Z, greenT->Z, blueT->Z);
|
||||
}
|
||||
|
||||
cmsFreeToneCurve(GammaTRC[0]);
|
||||
if (oprofdef) {
|
||||
constexpr cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||
constexpr cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_BLACKPOINTCOMPENSATION | cmsFLAGS_GAMUTCHECK;
|
||||
const cmsHPROFILE iprof = ICCStore::getInstance()->getXYZProfile();
|
||||
lcmsMutex->lock();
|
||||
hTransform = cmsCreateTransform(iprof, TYPE_RGB_FLT, oprofdef, TYPE_RGB_FLT, params->icm.outputIntent, flags);
|
||||
hTransform = cmsCreateTransform(iprof, TYPE_RGB_FLT, oprofdef, TYPE_RGB_FLT, params->icm.aRendIntent, flags);
|
||||
lcmsMutex->unlock();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user