apply clipping in RAW if the "clip OOG" parameter is set

This commit is contained in:
Alberto Griggio
2018-04-30 17:49:55 +02:00
parent 483c0ae3e5
commit 5d9dadae6e
2 changed files with 58 additions and 3 deletions

View File

@@ -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 {

View File

@@ -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);