Clip H-C vectorscope according to color profile
This commit is contained in:
parent
698b2e1842
commit
f779527833
@ -1853,6 +1853,13 @@ void ImProcCoordinator::updateVectorscope()
|
||||
constexpr int size = HistogramListener::vectorscope_size;
|
||||
memset(vectorscope, 0, size * size * sizeof(vectorscope[0][0]));
|
||||
|
||||
const int lab_img_size = (hListener->vectorscopeType() == 1) ? (x2 - x1) * (y2 - y1) : 0;
|
||||
float L[lab_img_size], a[lab_img_size], b[lab_img_size];
|
||||
if (lab_img_size) {
|
||||
ipf.rgb2lab(*workimg, x1, y1, x2 - x1, y2 - y1, L, a, b, params->icm);
|
||||
}
|
||||
|
||||
int ofs_lab = 0;
|
||||
for (int i = y1; i < y2; i++) {
|
||||
int ofs = (i * pW + x1) * 3;
|
||||
|
||||
@ -1875,12 +1882,13 @@ void ImProcCoordinator::updateVectorscope()
|
||||
|
||||
case 1: {
|
||||
// CH
|
||||
const int col = (size / 96000.0) * nprevl->a[i][j] + size / 2;
|
||||
const int row = (size / 96000.0) * nprevl->b[i][j] + size / 2;
|
||||
const int col = (size / 96000.0) * a[ofs_lab] + size / 2;
|
||||
const int row = (size / 96000.0) * b[ofs_lab] + size / 2;
|
||||
|
||||
if (col >= 0 && col < size && row >= 0 && row < size) {
|
||||
vectorscope[row][col]++;
|
||||
}
|
||||
ofs_lab++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5716,6 +5716,130 @@ void ImProcFunctions::rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::
|
||||
}
|
||||
}
|
||||
|
||||
void ImProcFunctions::rgb2lab(const Image8 &src, int x, int y, int w, int h, float L[], float a[], float b[], const procparams::ColorManagementParams &icm, bool consider_histogram_settings) const
|
||||
{ // Adapted from ImProcFunctions::lab2rgb
|
||||
const int src_width = src.getWidth();
|
||||
const int src_height = src.getHeight();
|
||||
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (x + w > src_width) {
|
||||
w = src_width - x;
|
||||
}
|
||||
|
||||
if (y + h > src_height) {
|
||||
h = src_height - y;
|
||||
}
|
||||
|
||||
Glib::ustring profile;
|
||||
|
||||
bool standard_gamma;
|
||||
|
||||
if (settings->HistogramWorking && consider_histogram_settings) {
|
||||
profile = icm.workingProfile;
|
||||
standard_gamma = true;
|
||||
} else {
|
||||
profile = icm.outputProfile;
|
||||
|
||||
if (icm.outputProfile.empty() || icm.outputProfile == ColorManagementParams::NoICMString) {
|
||||
profile = "sRGB";
|
||||
}
|
||||
|
||||
standard_gamma = false;
|
||||
}
|
||||
|
||||
cmsHPROFILE oprof = ICCStore::getInstance()->getProfile(profile);
|
||||
|
||||
if (oprof) {
|
||||
cmsHPROFILE oprofG = oprof;
|
||||
|
||||
if (standard_gamma) {
|
||||
oprofG = ICCStore::makeStdGammaProfile(oprof);
|
||||
}
|
||||
|
||||
cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||
|
||||
if (icm.outputBPC) {
|
||||
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
|
||||
}
|
||||
|
||||
lcmsMutex->lock();
|
||||
cmsHPROFILE LabIProf = cmsCreateLab4Profile(nullptr);
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform (oprofG, TYPE_RGB_8, LabIProf, TYPE_Lab_FLT, icm.outputIntent, flags); // NOCACHE is important for thread safety
|
||||
cmsCloseProfile(LabIProf);
|
||||
lcmsMutex->unlock();
|
||||
|
||||
// cmsDoTransform is relatively expensive
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
AlignedBuffer<float> oBuf(3 * w);
|
||||
float *outbuffer = oBuf.data;
|
||||
int condition = y + h;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic,16)
|
||||
#endif
|
||||
|
||||
for (int i = y; i < condition; i++) {
|
||||
const int ix = 3 * (x + i * src_width);
|
||||
int iy = 0;
|
||||
float* rL = L + (i - y) * w;
|
||||
float* ra = a + (i - y) * w;
|
||||
float* rb = b + (i - y) * w;
|
||||
|
||||
cmsDoTransform (hTransform, src.data + ix, outbuffer, w);
|
||||
|
||||
for (int j = 0; j < w; j++) {
|
||||
rL[j] = outbuffer[iy++] * 327.68f;
|
||||
ra[j] = outbuffer[iy++] * 327.68f;
|
||||
rb[j] = outbuffer[iy++] * 327.68f;
|
||||
}
|
||||
}
|
||||
} // End of parallelization
|
||||
|
||||
cmsDeleteTransform(hTransform);
|
||||
|
||||
if (oprofG != oprof) {
|
||||
cmsCloseProfile(oprofG);
|
||||
}
|
||||
} else {
|
||||
TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(profile);
|
||||
const float wp[3][3] = {
|
||||
{static_cast<float>(wprof[0][0]), static_cast<float>(wprof[0][1]), static_cast<float>(wprof[0][2])},
|
||||
{static_cast<float>(wprof[1][0]), static_cast<float>(wprof[1][1]), static_cast<float>(wprof[1][2])},
|
||||
{static_cast<float>(wprof[2][0]), static_cast<float>(wprof[2][1]), static_cast<float>(wprof[2][2])}
|
||||
};
|
||||
|
||||
const int x2 = x + w;
|
||||
const int y2 = y + h;
|
||||
constexpr float rgb_factor = 65355.f / 255.f;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic,16) if (multiThread)
|
||||
#endif
|
||||
|
||||
for (int i = y; i < y2; i++) {
|
||||
int offset = (i - y) * w;
|
||||
for (int j = x; j < x2; j++) {
|
||||
float X, Y, Z;
|
||||
// lab2rgb uses gamma2curve, which is gammatab_srgb.
|
||||
const auto& igamma = Color::igammatab_srgb;
|
||||
Color::rgbxyz(igamma[rgb_factor * src.r(i, j)], igamma[rgb_factor * src.g(i, j)], igamma[rgb_factor * src.b(i, j)], X, Y, Z, wp);
|
||||
Color::XYZ2Lab(X, Y, Z, L[offset], a[offset], b[offset]);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace)
|
||||
{
|
||||
TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(workingSpace);
|
||||
|
@ -449,6 +449,7 @@ public:
|
||||
void labColorCorrectionRegions(LabImage *lab);
|
||||
|
||||
Image8* lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool consider_histogram_settings = true);
|
||||
void rgb2lab(const Image8 &src, int x, int y, int w, int h, float L[], float a[], float b[], const procparams::ColorManagementParams &icm, bool consider_histogram_settings = true) const;
|
||||
Imagefloat* lab2rgbOut(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm);
|
||||
// CieImage *ciec;
|
||||
void workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, const Glib::ustring &profile, double gampos, double slpos, cmsHTRANSFORM &transform, bool normalizeIn = true, bool normalizeOut = true, bool keepTransForm = false) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user