apply clipping in RAW if the "clip OOG" parameter is set
This commit is contained in:
@@ -154,7 +154,7 @@ void transLineFuji (const float* const red, const float* const green, const floa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void transLineD1x (const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight, const bool oddHeight)
|
void transLineD1x (const float* const red, const float* const green, const float* const blue, const int i, rtengine::Imagefloat* const image, const int tran, const int imwidth, const int imheight, const bool oddHeight, const bool clip)
|
||||||
{
|
{
|
||||||
// Nikon D1X has an uncommon sensor with 4028 x 1324 sensels.
|
// Nikon D1X has an uncommon sensor with 4028 x 1324 sensels.
|
||||||
// Vertical sensel size is 2x horizontal sensel size
|
// Vertical sensel size is 2x horizontal sensel size
|
||||||
@@ -223,6 +223,12 @@ void transLineD1x (const float* const red, const float* const green, const float
|
|||||||
image->r(row, col) = MAX(0.f, -0.0625f * (red[j] + image->r(row + 3, col)) + 0.5625f * (image->r(row - 1, col) + image->r(row + 1, col)));
|
image->r(row, col) = MAX(0.f, -0.0625f * (red[j] + image->r(row + 3, col)) + 0.5625f * (image->r(row - 1, col) + image->r(row + 1, col)));
|
||||||
image->g(row, col) = MAX(0.f, -0.0625f * (green[j] + image->g(row + 3, col)) + 0.5625f * (image->g(row - 1, col) + image->g(row + 1, col)));
|
image->g(row, col) = MAX(0.f, -0.0625f * (green[j] + image->g(row + 3, col)) + 0.5625f * (image->g(row - 1, col) + image->g(row + 1, col)));
|
||||||
image->b(row, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(row + 3, col)) + 0.5625f * (image->b(row - 1, col) + image->b(row + 1, col)));
|
image->b(row, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(row + 3, col)) + 0.5625f * (image->b(row - 1, col) + image->b(row + 1, col)));
|
||||||
|
|
||||||
|
if(clip) {
|
||||||
|
image->r(row, col) = MIN(image->r(row, col), rtengine::MAXVALF);
|
||||||
|
image->g(row, col) = MIN(image->g(row, col), rtengine::MAXVALF);
|
||||||
|
image->b(row, col) = MIN(image->b(row, col), rtengine::MAXVALF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +286,12 @@ void transLineD1x (const float* const red, const float* const green, const float
|
|||||||
image->r(j, col) = MAX(0.f, -0.0625f * (red[j] + image->r(j, col + 3)) + 0.5625f * (image->r(j, col - 1) + image->r(j, col + 1)));
|
image->r(j, col) = MAX(0.f, -0.0625f * (red[j] + image->r(j, col + 3)) + 0.5625f * (image->r(j, col - 1) + image->r(j, col + 1)));
|
||||||
image->g(j, col) = MAX(0.f, -0.0625f * (green[j] + image->g(j, col + 3)) + 0.5625f * (image->g(j, col - 1) + image->g(j, col + 1)));
|
image->g(j, col) = MAX(0.f, -0.0625f * (green[j] + image->g(j, col + 3)) + 0.5625f * (image->g(j, col - 1) + image->g(j, col + 1)));
|
||||||
image->b(j, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(j, col + 3)) + 0.5625f * (image->b(j, col - 1) + image->b(j, col + 1)));
|
image->b(j, col) = MAX(0.f, -0.0625f * (blue[j] + image->b(j, col + 3)) + 0.5625f * (image->b(j, col - 1) + image->b(j, col + 1)));
|
||||||
|
|
||||||
|
if(clip) {
|
||||||
|
image->r(j, col) = MIN(image->r(j, col), rtengine::MAXVALF);
|
||||||
|
image->g(j, col) = MIN(image->g(j, col), rtengine::MAXVALF);
|
||||||
|
image->b(j, col) = MIN(image->b(j, col), rtengine::MAXVALF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,6 +319,12 @@ void transLineD1x (const float* const red, const float* const green, const float
|
|||||||
image->g(row, 2 * i - 3) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 6)) + 0.5625f * (image->g(row, 2 * i - 2) + image->g(row, 2 * i - 4)));
|
image->g(row, 2 * i - 3) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 6)) + 0.5625f * (image->g(row, 2 * i - 2) + image->g(row, 2 * i - 4)));
|
||||||
image->b(row, 2 * i - 3) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 6)) + 0.5625f * (image->b(row, 2 * i - 2) + image->b(row, 2 * i - 4)));
|
image->b(row, 2 * i - 3) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 6)) + 0.5625f * (image->b(row, 2 * i - 2) + image->b(row, 2 * i - 4)));
|
||||||
|
|
||||||
|
if(clip) {
|
||||||
|
image->r(row, 2 * i - 3) = MIN(image->r(row, 2 * i - 3), rtengine::MAXVALF);
|
||||||
|
image->g(row, 2 * i - 3) = MIN(image->g(row, 2 * i - 3), rtengine::MAXVALF);
|
||||||
|
image->b(row, 2 * i - 3) = MIN(image->b(row, 2 * i - 3), rtengine::MAXVALF);
|
||||||
|
}
|
||||||
|
|
||||||
image->r(row, 2 * i) = red[j];
|
image->r(row, 2 * i) = red[j];
|
||||||
image->g(row, 2 * i) = green[j];
|
image->g(row, 2 * i) = green[j];
|
||||||
image->b(row, 2 * i) = blue[j];
|
image->b(row, 2 * i) = blue[j];
|
||||||
@@ -319,6 +337,12 @@ void transLineD1x (const float* const red, const float* const green, const float
|
|||||||
image->g(row, 2 * i - 1) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 4)) + 0.5625f * (image->g(row, 2 * i) + image->g(row, 2 * i - 2)));
|
image->g(row, 2 * i - 1) = MAX(0.f, -0.0625f * (green[j] + image->g(row, 2 * i - 4)) + 0.5625f * (image->g(row, 2 * i) + image->g(row, 2 * i - 2)));
|
||||||
image->b(row, 2 * i - 1) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 4)) + 0.5625f * (image->b(row, 2 * i) + image->b(row, 2 * i - 2)));
|
image->b(row, 2 * i - 1) = MAX(0.f, -0.0625f * (blue[j] + image->b(row, 2 * i - 4)) + 0.5625f * (image->b(row, 2 * i) + image->b(row, 2 * i - 2)));
|
||||||
|
|
||||||
|
if(clip) {
|
||||||
|
image->r(j, 2 * i - 1) = MIN(image->r(j, 2 * i - 1), rtengine::MAXVALF);
|
||||||
|
image->g(j, 2 * i - 1) = MIN(image->g(j, 2 * i - 1), rtengine::MAXVALF);
|
||||||
|
image->b(j, 2 * i - 1) = MIN(image->b(j, 2 * i - 1), rtengine::MAXVALF);
|
||||||
|
}
|
||||||
|
|
||||||
image->r(row, 2 * i + 1) = (red[j] + image->r(row, 2 * i - 1)) / 2;
|
image->r(row, 2 * i + 1) = (red[j] + image->r(row, 2 * i - 1)) / 2;
|
||||||
image->g(row, 2 * i + 1) = (green[j] + image->g(row, 2 * i - 1)) / 2;
|
image->g(row, 2 * i + 1) = (green[j] + image->g(row, 2 * i - 1)) / 2;
|
||||||
image->b(row, 2 * i + 1) = (blue[j] + image->b(row, 2 * i - 1)) / 2;
|
image->b(row, 2 * i + 1) = (blue[j] + image->b(row, 2 * i - 1)) / 2;
|
||||||
@@ -350,6 +374,12 @@ void transLineD1x (const float* const red, const float* const green, const float
|
|||||||
image->r(2 * i - 3, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 6, j)) + 0.5625f * (image->r(2 * i - 2, j) + image->r(2 * i - 4, j)));
|
image->r(2 * i - 3, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 6, j)) + 0.5625f * (image->r(2 * i - 2, j) + image->r(2 * i - 4, j)));
|
||||||
image->g(2 * i - 3, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 6, j)) + 0.5625f * (image->g(2 * i - 2, j) + image->g(2 * i - 4, j)));
|
image->g(2 * i - 3, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 6, j)) + 0.5625f * (image->g(2 * i - 2, j) + image->g(2 * i - 4, j)));
|
||||||
image->b(2 * i - 3, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 6, j)) + 0.5625f * (image->b(2 * i - 2, j) + image->b(2 * i - 4, j)));
|
image->b(2 * i - 3, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 6, j)) + 0.5625f * (image->b(2 * i - 2, j) + image->b(2 * i - 4, j)));
|
||||||
|
|
||||||
|
if(clip) {
|
||||||
|
image->r(2 * i - 3, j) = MIN(image->r(2 * i - 3, j), rtengine::MAXVALF);
|
||||||
|
image->g(2 * i - 3, j) = MIN(image->g(2 * i - 3, j), rtengine::MAXVALF);
|
||||||
|
image->b(2 * i - 3, j) = MIN(image->b(2 * i - 3, j), rtengine::MAXVALF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,6 +389,12 @@ void transLineD1x (const float* const red, const float* const green, const float
|
|||||||
image->g(2 * i - 1, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 4, j)) + 0.5625f * (image->g(2 * i, j) + image->g(2 * i - 2, j)));
|
image->g(2 * i - 1, j) = MAX(0.f, -0.0625f * (green[j] + image->g(2 * i - 4, j)) + 0.5625f * (image->g(2 * i, j) + image->g(2 * i - 2, j)));
|
||||||
image->b(2 * i - 1, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 4, j)) + 0.5625f * (image->b(2 * i, j) + image->b(2 * i - 2, j)));
|
image->b(2 * i - 1, j) = MAX(0.f, -0.0625f * (blue[j] + image->b(2 * i - 4, j)) + 0.5625f * (image->b(2 * i, j) + image->b(2 * i - 2, j)));
|
||||||
|
|
||||||
|
if(clip) {
|
||||||
|
image->r(2 * i - 1, j) = MIN(image->r(2 * i - 1, j), rtengine::MAXVALF);
|
||||||
|
image->g(2 * i - 1, j) = MIN(image->g(2 * i - 1, j), rtengine::MAXVALF);
|
||||||
|
image->b(2 * i - 1, j) = MIN(image->b(2 * i - 1, j), rtengine::MAXVALF);
|
||||||
|
}
|
||||||
|
|
||||||
image->r(2 * i + 1, j) = (red[j] + image->r(2 * i - 1, j)) / 2;
|
image->r(2 * i + 1, j) = (red[j] + image->r(2 * i - 1, j)) / 2;
|
||||||
image->g(2 * i + 1, j) = (green[j] + image->g(2 * i - 1, j)) / 2;
|
image->g(2 * i + 1, j) = (green[j] + image->g(2 * i - 1, j)) / 2;
|
||||||
image->b(2 * i + 1, j) = (blue[j] + image->b(2 * i - 1, j)) / 2;
|
image->b(2 * i + 1, j) = (blue[j] + image->b(2 * i - 1, j)) / 2;
|
||||||
@@ -688,6 +724,8 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
|
|||||||
hlmax[1] = clmax[1] * gm;
|
hlmax[1] = clmax[1] * gm;
|
||||||
hlmax[2] = clmax[2] * bm;
|
hlmax[2] = clmax[2] * bm;
|
||||||
|
|
||||||
|
const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled && hrp.clampOOG;
|
||||||
|
|
||||||
float area = skip * skip;
|
float area = skip * skip;
|
||||||
rm /= area;
|
rm /= area;
|
||||||
gm /= area;
|
gm /= area;
|
||||||
@@ -730,6 +768,17 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
|
|||||||
gtot *= gm;
|
gtot *= gm;
|
||||||
btot *= bm;
|
btot *= bm;
|
||||||
|
|
||||||
|
if (doClip) {
|
||||||
|
// note: as hlmax[] can be larger than CLIP and we can later apply negative
|
||||||
|
// exposure this means that we can clip away local highlights which actually
|
||||||
|
// are not clipped. We have to do that though as we only check pixel by pixel
|
||||||
|
// and don't know if this will transition into a clipped area, if so we need
|
||||||
|
// to clip also surrounding to make a good colour transition
|
||||||
|
rtot = CLIP(rtot);
|
||||||
|
gtot = CLIP(gtot);
|
||||||
|
btot = CLIP(btot);
|
||||||
|
}
|
||||||
|
|
||||||
line_red[j] = rtot;
|
line_red[j] = rtot;
|
||||||
line_grn[j] = gtot;
|
line_grn[j] = gtot;
|
||||||
line_blue[j] = btot;
|
line_blue[j] = btot;
|
||||||
@@ -754,6 +803,12 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
|
|||||||
gtot *= gm;
|
gtot *= gm;
|
||||||
btot *= bm;
|
btot *= bm;
|
||||||
|
|
||||||
|
if (doClip) {
|
||||||
|
rtot = CLIP(rtot);
|
||||||
|
gtot = CLIP(gtot);
|
||||||
|
btot = CLIP(btot);
|
||||||
|
}
|
||||||
|
|
||||||
line_red[j] = rtot;
|
line_red[j] = rtot;
|
||||||
line_grn[j] = gtot;
|
line_grn[j] = gtot;
|
||||||
line_blue[j] = btot;
|
line_blue[j] = btot;
|
||||||
@@ -767,7 +822,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(d1x) {
|
if(d1x) {
|
||||||
transLineD1x (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, d1xHeightOdd);
|
transLineD1x (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, d1xHeightOdd, doClip);
|
||||||
} else if(fuji) {
|
} else if(fuji) {
|
||||||
transLineFuji (line_red, line_grn, line_blue, ix, image, tran, imheight, fw);
|
transLineFuji (line_red, line_grn, line_blue, ix, image, tran, imheight, fw);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -32,7 +32,7 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA
|
|||||||
auto m = ProcEventMapper::getInstance();
|
auto m = ProcEventMapper::getInstance();
|
||||||
EvHistMatching = m->newEvent(AUTOEXP, "HISTORY_MSG_HISTMATCHING");
|
EvHistMatching = m->newEvent(AUTOEXP, "HISTORY_MSG_HISTMATCHING");
|
||||||
EvHistMatchingBatch = m->newEvent(M_VOID, "HISTORY_MSG_HISTMATCHING");
|
EvHistMatchingBatch = m->newEvent(M_VOID, "HISTORY_MSG_HISTMATCHING");
|
||||||
EvClampOOG = m->newEvent(RGBCURVE, "HISTORY_MSG_CLAMPOOG");
|
EvClampOOG = m->newEvent(DARKFRAME, "HISTORY_MSG_CLAMPOOG");
|
||||||
|
|
||||||
CurveListener::setMulti(true);
|
CurveListener::setMulti(true);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user