Histogram now shows output space (with gamma normalized to 569/256) instead of working space
This commit is contained in:
@@ -302,7 +302,7 @@ void Crop::update (int todo) {
|
||||
// this in output space held in parallel to allow analysis like shadow/highlight
|
||||
Glib::ustring outProfile=params.icm.output;
|
||||
if (params.icm.output=="" || params.icm.output==ColorManagementParams::NoICMString) outProfile="sRGB";
|
||||
Image8 *cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0,0,cropw,croph, outProfile);
|
||||
Image8 *cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0,0,cropw,croph, outProfile, false);
|
||||
|
||||
int finalW = rqcropw;
|
||||
if (cropImg->getWidth()-leftBorder < finalW)
|
||||
|
||||
@@ -77,6 +77,94 @@ std::vector<Glib::ustring> ICCStore::getOutputProfiles () {
|
||||
}
|
||||
|
||||
|
||||
cmsHPROFILE
|
||||
ICCStore::makeStdGammaProfile(cmsHPROFILE iprof)
|
||||
{
|
||||
// forgive me for the messy code, quick hack to change gamma of an ICC profile to the RT standard gamma
|
||||
void *buf = NULL;
|
||||
if (!iprof) {
|
||||
return NULL;
|
||||
}
|
||||
cmsUInt32Number bytesNeeded = 0;
|
||||
cmsSaveProfileToMem(iprof, 0, &bytesNeeded);
|
||||
if (bytesNeeded == 0) {
|
||||
return NULL;
|
||||
}
|
||||
uint8_t *data = new uint8_t[bytesNeeded+1];
|
||||
cmsSaveProfileToMem(iprof, data, &bytesNeeded);
|
||||
const size_t len = (int)bytesNeeded;
|
||||
const uint8_t *p = &data[128]; // skip 128 byte header
|
||||
uint32_t tag_count;
|
||||
memcpy(&tag_count, p, 4);
|
||||
p += 4;
|
||||
tag_count = ntohl(tag_count);
|
||||
|
||||
struct icctag {
|
||||
uint32_t sig;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
} tags[tag_count];
|
||||
|
||||
const uint32_t gamma = 0x239;
|
||||
int gamma_size = (gamma == 0 || gamma == 256) ? 12 : 14;
|
||||
int data_size = (gamma_size + 3) & ~3;
|
||||
for (int i = 0; i < tag_count; i++) {
|
||||
memcpy(&tags[i], p, 12);
|
||||
tags[i].sig = ntohl(tags[i].sig);
|
||||
tags[i].offset = ntohl(tags[i].offset);
|
||||
tags[i].size = ntohl(tags[i].size);
|
||||
p += 12;
|
||||
if (tags[i].sig != 0x62545243 && // bTRC
|
||||
tags[i].sig != 0x67545243 && // gTRC
|
||||
tags[i].sig != 0x72545243 && // rTRC
|
||||
tags[i].sig != 0x6B545243) // kTRC
|
||||
{
|
||||
data_size += (tags[i].size + 3) & ~3;
|
||||
}
|
||||
}
|
||||
uint32_t sz = 128 + 4 + tag_count * 12 + data_size;
|
||||
uint8_t *nd = new uint8_t[sz];
|
||||
memset(nd, 0, sz);
|
||||
memcpy(nd, data, 128 + 4);
|
||||
sz = htonl(sz);
|
||||
memcpy(nd, &sz, 4);
|
||||
uint32_t offset = 128 + 4 + tag_count * 12;
|
||||
uint32_t gamma_offset = 0;
|
||||
for (int i = 0; i < tag_count; i++) {
|
||||
struct icctag tag;
|
||||
tag.sig = htonl(tags[i].sig);
|
||||
if (tags[i].sig == 0x62545243 || // bTRC
|
||||
tags[i].sig == 0x67545243 || // gTRC
|
||||
tags[i].sig == 0x72545243 || // rTRC
|
||||
tags[i].sig == 0x6B545243) // kTRC
|
||||
{
|
||||
if (gamma_offset == 0) {
|
||||
gamma_offset = offset;
|
||||
uint32_t pcurve[] = { htonl(0x63757276), htonl(0), htonl(gamma_size == 12 ? 0 : 1) };
|
||||
memcpy(&nd[offset], pcurve, 12);
|
||||
if (gamma_size == 14) {
|
||||
uint16_t gm = htons(gamma);
|
||||
memcpy(&nd[offset+12], &gm, 2);
|
||||
}
|
||||
offset += (gamma_size + 3) & ~3;
|
||||
}
|
||||
tag.offset = htonl(gamma_offset);
|
||||
tag.size = htonl(gamma_size);
|
||||
} else {
|
||||
tag.offset = htonl(offset);
|
||||
tag.size = htonl(tags[i].size);
|
||||
memcpy(&nd[offset], &data[tags[i].offset], tags[i].size);
|
||||
offset += (tags[i].size + 3) & ~3;
|
||||
}
|
||||
memcpy(&nd[128 + 4 + i * 12], &tag, 12);
|
||||
}
|
||||
|
||||
cmsHPROFILE oprof = cmsOpenProfileFromMem (nd, ntohl(sz));
|
||||
delete [] nd;
|
||||
delete [] data;
|
||||
return oprof;
|
||||
}
|
||||
|
||||
ICCStore*
|
||||
ICCStore::getInstance(void)
|
||||
{
|
||||
|
||||
@@ -70,6 +70,7 @@ class ICCStore {
|
||||
public:
|
||||
|
||||
static ICCStore* getInstance(void);
|
||||
static cmsHPROFILE makeStdGammaProfile(cmsHPROFILE iprof);
|
||||
|
||||
Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS
|
||||
void findDefaultMonitorProfile();
|
||||
|
||||
@@ -513,7 +513,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
{
|
||||
ipf.lab2monitorRgb (nprevl, previmg);
|
||||
delete workimg;
|
||||
workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, params.icm.working);
|
||||
Glib::ustring outProfile=params.icm.output;
|
||||
if (params.icm.output=="" || params.icm.output==ColorManagementParams::NoICMString) outProfile="sRGB";
|
||||
workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, outProfile, true);
|
||||
}
|
||||
catch(char * str)
|
||||
{
|
||||
|
||||
@@ -284,7 +284,7 @@ class ImProcFunctions {
|
||||
void PF_correct_RTcam (CieImage * src, CieImage * dst, double radius, int thresh);
|
||||
void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode);
|
||||
|
||||
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
|
||||
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma);
|
||||
Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, 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);// for gamma output
|
||||
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);//without gamma ==>default
|
||||
// CieImage *ciec;
|
||||
|
||||
@@ -148,7 +148,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) {
|
||||
//printf("lab2rgb %i %d\n", lab->W, tEnd.etime(tBeg));
|
||||
}
|
||||
|
||||
Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile) {
|
||||
Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma) {
|
||||
|
||||
//gamutmap(lab);
|
||||
|
||||
@@ -162,9 +162,13 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
||||
cmsHPROFILE oprof = iccStore->getProfile (profile);
|
||||
|
||||
if (oprof) {
|
||||
cmsHPROFILE oprofG = oprof;
|
||||
if (standard_gamma) {
|
||||
oprofG = ICCStore::makeStdGammaProfile(oprof);
|
||||
}
|
||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
||||
lcmsMutex->lock ();
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_8, settings->colorimetricIntent,
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofG, TYPE_RGB_8, settings->colorimetricIntent,
|
||||
cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
@@ -213,6 +217,8 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
|
||||
} // End of parallelization
|
||||
|
||||
cmsDeleteTransform(hTransform);
|
||||
if (oprofG != oprof)
|
||||
cmsCloseProfile(oprofG);
|
||||
} else {
|
||||
|
||||
double rgb_xyz[3][3];
|
||||
@@ -300,7 +306,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
|
||||
|
||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
||||
lcmsMutex->lock ();
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE);
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
image->ExecCMSTransform(hTransform);
|
||||
@@ -444,7 +450,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int
|
||||
|
||||
cmsHPROFILE iprof = iccStore->getXYZProfile ();
|
||||
lcmsMutex->lock ();
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE);
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
|
||||
lcmsMutex->unlock ();
|
||||
|
||||
image->ExecCMSTransform(hTransform);
|
||||
|
||||
@@ -408,7 +408,7 @@ void ProcParams::setDefaults () {
|
||||
icm.blendCMSMatrix = false;
|
||||
icm.toneCurve = false;
|
||||
icm.dcpIlluminant = 0;
|
||||
icm.working = "sRGB";
|
||||
icm.working = "ProPhoto";
|
||||
icm.output = "sRGB";
|
||||
icm.gamma = "default";
|
||||
icm.gampos =2.22;
|
||||
|
||||
Reference in New Issue
Block a user