Moved some helper functions to anonymous namespace and did some further cleanups

This commit is contained in:
heckflosse
2016-02-07 00:27:19 +01:00
parent 036114c604
commit 23db45b3a2
2 changed files with 409 additions and 365 deletions

View File

@@ -25,13 +25,10 @@
#include "median.h"
#include "rawimage.h"
#include "mytime.h"
#include "iccmatrices.h"
#include "iccstore.h"
#include "image8.h"
#include "curves.h"
#include "dfmanager.h"
#include "ffmanager.h"
#include "../rtgui/options.h"
#include "dcp.h"
#include "rt_math.h"
#include "improcfun.h"
@@ -39,11 +36,375 @@
#include <omp.h>
#endif
#include "opthelper.h"
#include "StopWatch.h"
#define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val )
#undef CLIPD
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
namespace
{
void rotateLine (const float* const line, rtengine::PlanarPtr<float> &channel, const int tran, const int i, const int w, const int h)
{
switch(tran & TR_ROT) {
case TR_R180:
for (int j = 0; j < w; j++) {
channel(h - 1 - i, w - 1 - j) = line[j];
}
break;
case TR_R90:
for (int j = 0; j < w; j++) {
channel(j, h - 1 - i) = line[j];
}
break;
case TR_R270:
for (int j = 0; j < w; j++) {
channel(w - 1 - j, i) = line[j];
}
break;
case TR_NONE:
for (int j = 0; j < w; j++) {
channel(i, j) = line[j];
}
}
}
void transLineStandard (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)
{
// conventional CCD coarse rotation
rotateLine (red, image->r, tran, i, imwidth, imheight);
rotateLine (green, image->g, tran, i, imwidth, imheight);
rotateLine (blue, image->b, tran, i, imwidth, imheight);
}
void transLineFuji (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 int fw)
{
// Fuji SuperCCD rotation + coarse rotation
int start = ABS(fw - i);
int w = fw * 2 + 1;
int h = (imheight - fw) * 2 + 1;
int end = min(h + fw - i, w - fw + i);
switch(tran & TR_ROT) {
case TR_R180:
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && y < image->height && y >= 0 && x < image->width) {
image->r(image->height - 1 - y, image->width - 1 - x) = red[j];
image->g(image->height - 1 - y, image->width - 1 - x) = green[j];
image->b(image->height - 1 - y, image->width - 1 - x) = blue[j];
}
}
break;
case TR_R270:
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && x < image->height && y >= 0 && y < image->width) {
image->r(image->height - 1 - x, y) = red[j];
image->g(image->height - 1 - x, y) = green[j];
image->b(image->height - 1 - x, y) = blue[j];
}
}
break;
case TR_R90:
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && y < image->width && y >= 0 && x < image->height) {
image->r(x, image->width - 1 - y) = red[j];
image->g(x, image->width - 1 - y) = green[j];
image->b(x, image->width - 1 - y) = blue[j];
}
}
break;
case TR_NONE:
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && y < image->height && y >= 0 && x < image->width) {
image->r(y, x) = red[j];
image->g(y, x) = green[j];
image->b(y, x) = blue[j];
}
}
}
}
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.
// Vertical sensel size is 2x horizontal sensel size
// We have to do vertical interpolation for the 'missing' rows
// We do that in combination with coarse rotation
switch(tran & TR_ROT) {
case TR_R180: // rotate 180 degree
for (int j = 0; j < imwidth; j++) {
image->r(2 * (imheight - 1 - i), imwidth - 1 - j) = red[j];
image->g(2 * (imheight - 1 - i), imwidth - 1 - j) = green[j];
image->b(2 * (imheight - 1 - i), imwidth - 1 - j) = blue[j];
}
if (i == 0) {
for (int j = 0; j < imwidth; j++) {
image->r(2 * imheight - 1, imwidth - 1 - j) = red[j];
image->g(2 * imheight - 1, imwidth - 1 - j) = green[j];
image->b(2 * imheight - 1, imwidth - 1 - j) = blue[j];
}
}
if (i == 1 || i == 2) { // linear interpolation
int row = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2;
image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2;
}
if(i == 2 && oddHeight) {
int row = 2 * imheight;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row - 2, col)) / 2;
image->g(row, col) = (green[j] + image->g(row - 2, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row - 2, col)) / 2;
}
}
} else if (i == imheight - 1 || i == imheight - 2) {
int row = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2;
image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2;
}
row = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2;
image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2;
}
} else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation
int row = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
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->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);
}
}
}
break;
case TR_R90: // rotate right
if( i == 0) {
for (int j = 0; j < imwidth; j++) {
image->r(j, 2 * imheight - 1) = red[j];
image->g(j, 2 * imheight - 1) = green[j];
image->b(j, 2 * imheight - 1) = blue[j];
}
}
for (int j = 0; j < imwidth; j++) {
image->r(j, 2 * (imheight - 1 - i)) = red[j];
image->g(j, 2 * (imheight - 1 - i)) = green[j];
image->b(j, 2 * (imheight - 1 - i)) = blue[j];
}
if (i == 1 || i == 2) { // linear interpolation
int col = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2;
image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2;
image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2;
if(oddHeight && i == 2) {
image->r(j, 2 * imheight) = (red[j] + image->r(j, 2 * imheight - 2)) / 2;
image->g(j, 2 * imheight) = (green[j] + image->g(j, 2 * imheight - 2)) / 2;
image->b(j, 2 * imheight) = (blue[j] + image->b(j, 2 * imheight - 2)) / 2;
}
}
} else if (i == imheight - 1) {
int col = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2;
image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2;
image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2;
}
col = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2;
image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2;
image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2;
}
} else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation
int col = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
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->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);
}
}
}
break;
case TR_R270: // rotate left
if (i == 0) {
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i) = red[j];
image->g(row, 2 * i) = green[j];
image->b(row, 2 * i) = blue[j];
}
} else if (i == 1 || i == 2) { // linear interpolation
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i) = red[j];
image->g(row, 2 * i) = green[j];
image->b(row, 2 * i) = blue[j];
image->r(row, 2 * i - 1) = (red[j] + image->r(row, 2 * i - 2)) * 0.5f;
image->g(row, 2 * i - 1) = (green[j] + image->g(row, 2 * i - 2)) * 0.5f;
image->b(row, 2 * i - 1) = (blue[j] + image->b(row, 2 * i - 2)) * 0.5f;
}
} else if (i > 0 && i < imheight) { // vertical bicubic interpolation
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i - 3) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 6)) + 0.5625f * (image->r(row, 2 * i - 2) + image->r(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)));
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->g(row, 2 * i) = green[j];
image->b(row, 2 * i) = blue[j];
}
}
if (i == imheight - 1) {
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i - 1) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 4)) + 0.5625f * (image->r(row, 2 * i) + image->r(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)));
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->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;
if (oddHeight) {
image->r(row, 2 * i + 2) = (red[j] + image->r(row, 2 * i - 2)) / 2;
image->g(row, 2 * i + 2) = (green[j] + image->g(row, 2 * i - 2)) / 2;
image->b(row, 2 * i + 2) = (blue[j] + image->b(row, 2 * i - 2)) / 2;
}
}
}
break;
case TR_NONE: // no coarse rotation
rotateLine (red, image->r, tran, 2 * i, imwidth, imheight);
rotateLine (green, image->g, tran, 2 * i, imwidth, imheight);
rotateLine (blue, image->b, tran, 2 * i, imwidth, imheight);
if (i == 1 || i == 2) { // linear interpolation
for (int j = 0; j < imwidth; j++) {
image->r(2 * i - 1, j) = (red[j] + image->r(2 * i - 2, j)) / 2;
image->g(2 * i - 1, j) = (green[j] + image->g(2 * i - 2, j)) / 2;
image->b(2 * i - 1, j) = (blue[j] + image->b(2 * i - 2, j)) / 2;
}
} else if (i > 2 && i < imheight) { // vertical bicubic interpolation
for (int j = 0; j < imwidth; 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->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);
}
}
}
if (i == imheight - 1) {
for (int j = 0; j < imwidth; j++) {
image->r(2 * i - 1, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 4, j)) + 0.5625f * (image->r(2 * i, j) + image->r(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)));
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->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;
if (oddHeight) {
image->r(2 * i + 2, j) = (red[j] + image->r(2 * i - 2, j)) / 2;
image->g(2 * i + 2, j) = (green[j] + image->g(2 * i - 2, j)) / 2;
image->b(2 * i + 2, j) = (blue[j] + image->b(2 * i - 2, j)) / 2;
}
}
}
}
}
}
namespace rtengine
{
@@ -323,8 +684,12 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
}
if (d1x) {
// D1X has only half of the required rows
// we interpolate the missing ones later to get correct aspect ratio
// if the height is odd we also have to add an additional row to avoid a black line
d1xHeightOdd = maximheight & 1;
maximheight /= 2;
imheight = maximheight;
}
// correct if overflow (very rare), but not fuji because it is corrected in transline
@@ -342,9 +707,9 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
hlmax[0] = clmax[0] * rm;
hlmax[1] = clmax[1] * gm;
hlmax[2] = clmax[2] * bm;
const bool has_clipping = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]);
//if (sx1+skip*imwidth>maxx) imwidth --; // very hard to fix this situation without an 'if' in the loop.
const bool doClip = (chmax[0] >= clmax[0] || chmax[1] >= clmax[1] || chmax[2] >= clmax[2]) && !hrp.hrenabled;
float area = skip * skip;
rm /= area;
gm /= area;
@@ -355,17 +720,15 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
{
#endif
// render the requested image part
float* line_red = new float[imwidth];
float* line_grn = new float[imwidth];
float* line_blue = new float[imwidth];
//printf("clip[0]=%f clip[1]=%f clip[2]=%f\n",hlmax[0],hlmax[1],hlmax[2]);
float line_red[imwidth] ALIGNED16;
float line_grn[imwidth] ALIGNED16;
float line_blue[imwidth] ALIGNED16;
#ifdef _OPENMP
#pragma omp for
#endif
for (int ix = 0; ix < (d1x ? maximheight : imheight); ix++) {
for (int ix = 0; ix < imheight; ix++) {
int i = sy1 + skip * ix;
if (i >= maxy - skip) {
@@ -374,12 +737,9 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
if (ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) {
for (int j = 0, jx = sx1; j < imwidth; j++, jx += skip) {
if (jx >= maxx - skip) {
jx = maxx - skip - 1; // avoid trouble
}
jx = jx >= (maxx - skip) ? jx = maxx - skip - 1 : jx; // avoid trouble
float rtot, gtot, btot;
rtot = gtot = btot = 0;
float rtot = 0.f, gtot = 0.f, btot = 0.f;
for (int m = 0; m < skip; m++)
for (int n = 0; n < skip; n++) {
@@ -392,7 +752,7 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
gtot *= gm;
btot *= bm;
if (!hrp.hrenabled && has_clipping) {
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
@@ -427,7 +787,7 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
gtot *= gm;
btot *= bm;
if (!hrp.hrenabled && has_clipping) {
if (doClip) {
rtot = CLIP(rtot);
gtot = CLIP(gtot);
btot = CLIP(btot);
@@ -445,13 +805,16 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
hlRecovery (hrp.method, line_red, line_grn, line_blue, i, sx1, imwidth, skip, raw, hlmax);
}
transLine (line_red, line_grn, line_blue, ix, image, tran, imwidth, d1x ? maximheight : imheight, fw, d1xHeightOdd, !hrp.hrenabled && has_clipping);
if(d1x) {
transLineD1x (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, d1xHeightOdd, doClip);
} else if(fuji) {
transLineFuji (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, fw);
} else {
transLineStandard (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight);
}
}
delete [] line_red;
delete [] line_grn;
delete [] line_blue;
#ifdef _OPENMP
}
#endif
@@ -504,8 +867,6 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
}
}
// Flip if needed
if (tran & TR_HFLIP) {
hflip (image);
@@ -515,11 +876,14 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
vflip (image);
}
// Color correction (only when running on full resolution)
if (ri->getSensorType() != ST_NONE && pp.skip == 1) {
if (ri->getSensorType() == ST_BAYER) {
// Colour correction (only when running on full resolution)
if(pp.skip == 1) {
switch(ri->getSensorType()) {
case ST_BAYER:
processFalseColorCorrection (image, raw.bayersensor.ccSteps);
} else if (ri->getSensorType() == ST_FUJI_XTRANS) {
break;
case ST_FUJI_XTRANS:
processFalseColorCorrection (image, raw.xtranssensor.ccSteps);
}
}
@@ -548,7 +912,7 @@ void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/* interpolateBadPixelsBayer: correct raw pixels looking at the bitmap
* takes into consideration if there are multiple bad pixels in the neighborhood
* takes into consideration if there are multiple bad pixels in the neighbourhood
*/
int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads )
{
@@ -575,8 +939,8 @@ int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads )
// diagonal interpolation
if(FC(row, col) == 1) {
// green channel. We can use closer pixels than for red or blue channel. Distance to center pixel is sqrt(2) => weighting is 0.70710678
// For green channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
// green channel. We can use closer pixels than for red or blue channel. Distance to centre pixel is sqrt(2) => weighting is 0.70710678
// For green channel following pixels will be used for interpolation. Pixel to be interpolated is in centre.
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
// 0 0 0 0 0
// 0 1 0 1 0
@@ -593,8 +957,8 @@ int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads )
norm += dirwt;
}
} else {
// red and blue channel. Distance to center pixel is sqrt(8) => weighting is 0.35355339
// For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
// red and blue channel. Distance to centre pixel is sqrt(8) => weighting is 0.35355339
// For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in centre.
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
// 1 0 0 0 1
// 0 0 0 0 0
@@ -612,8 +976,8 @@ int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads )
}
}
// channel independent. Distance to center pixel is 2 => weighting is 0.5
// Additionally for all channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
// channel independent. Distance to centre pixel is 2 => weighting is 0.5
// Additionally for all channel following pixels will be used for interpolation. Pixel to be interpolated is in centre.
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
// 0 0 1 0 0
// 0 0 0 0 0
@@ -635,7 +999,7 @@ int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads )
norm += dirwt;
}
if (LIKELY(norm > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999%
if (LIKELY(norm > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelihood of this case is about 99.999%
rawData[row][col] = wtdsum / (2.f * norm); //gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
counter++;
} else { //backup plan -- simple average. Same method for all channels. We could improve this, but it's really unlikely that this case happens
@@ -665,7 +1029,7 @@ int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads )
}
/* interpolateBadPixels3Colours: correct raw pixels looking at the bitmap
* takes into consideration if there are multiple bad pixels in the neighborhood
* takes into consideration if there are multiple bad pixels in the neighbourhood
*/
int RawImageSource::interpolateBadPixelsNColours( PixelsMap &bitmapBads, const int colours )
{
@@ -1078,318 +1442,6 @@ SSEFUNCTION int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thres
return counter;
}
void RawImageSource::rotateLine (const float* const line, PlanarPtr<float> &channel, const int tran, const int i, const int w, const int h)
{
if ((tran & TR_ROT) == TR_R180)
for (int j = 0; j < w; j++) {
channel(h - 1 - i, w - 1 - j) = line[j];
}
else if ((tran & TR_ROT) == TR_R90)
for (int j = 0; j < w; j++) {
channel(j, h - 1 - i) = line[j];
}
else if ((tran & TR_ROT) == TR_R270)
for (int j = 0, cj = w - 1; j < w; j++, cj--) {
channel(cj, i) = line[j];
}
else
for (int j = 0; j < w; j++) {
channel(i, j) = line[j];
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void RawImageSource::transLine (float* red, float* green, float* blue, int i, Imagefloat* image, int tran, int imwidth, int imheight, int fw, bool d1xHeightOdd, bool d1xClip)
{
// Fuji SuperCCD rotation + coarse rotation
if (fuji) {
int start = ABS(fw - i);
int w = fw * 2 + 1;
int h = (imheight - fw) * 2 + 1;
if ((tran & TR_ROT) == TR_R180) {
int end = min(h + fw - i, w - fw + i);
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && y < image->height && y >= 0 && x < image->width) {
image->r(image->height - 1 - y, image->width - 1 - x) = red[j];
image->g(image->height - 1 - y, image->width - 1 - x) = green[j];
image->b(image->height - 1 - y, image->width - 1 - x) = blue[j];
}
}
} else if ((tran & TR_ROT) == TR_R270) {
int end = min(h + fw - i, w - fw + i);
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && x < image->height && y >= 0 && y < image->width) {
image->r(image->height - 1 - x, y) = red[j];
image->g(image->height - 1 - x, y) = green[j];
image->b(image->height - 1 - x, y) = blue[j];
}
}
} else if ((tran & TR_ROT) == TR_R90) {
int end = min(h + fw - i, w - fw + i);
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && y < image->width && y >= 0 && x < image->height) {
image->r(x, image->width - 1 - y) = red[j];
image->g(x, image->width - 1 - y) = green[j];
image->b(x, image->width - 1 - y) = blue[j];
}
}
} else {
int end = min(h + fw - i, w - fw + i);
for (int j = start; j < end; j++) {
int y = i + j - fw;
int x = fw - i + j;
if (x >= 0 && y < image->height && y >= 0 && x < image->width) {
image->r(y, x) = red[j];
image->g(y, x) = green[j];
image->b(y, x) = blue[j];
}
}
}
}
// Nikon D1X vertical interpolation + coarse rotation
else if (d1x) {
// copy new pixels
if ((tran & TR_ROT) == TR_R180) { // rotate 2 times left or two times right
for (int j = 0; j < imwidth; j++) {
image->r(2 * imheight - 2 - 2 * i, imwidth - 1 - j) = red[j];
image->g(2 * imheight - 2 - 2 * i, imwidth - 1 - j) = green[j];
image->b(2 * imheight - 2 - 2 * i, imwidth - 1 - j) = blue[j];
}
if (i == 0) {
for (int j = 0; j < imwidth; j++) {
image->r(2 * imheight - 1, imwidth - 1 - j) = red[j];
image->g(2 * imheight - 1, imwidth - 1 - j) = green[j];
image->b(2 * imheight - 1, imwidth - 1 - j) = blue[j];
}
}
if (i == 1 || i == 2) { // linear interpolation
int row = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2;
image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2;
}
if(i == 2 && d1xHeightOdd) {
int row = 2 * imheight;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row - 2, col)) / 2;
image->g(row, col) = (green[j] + image->g(row - 2, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row - 2, col)) / 2;
}
}
} else if (i == imheight - 1 || i == imheight - 2) {
int row = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2;
image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2;
}
row = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
image->r(row, col) = (red[j] + image->r(row + 1, col)) / 2;
image->g(row, col) = (green[j] + image->g(row + 1, col)) / 2;
image->b(row, col) = (blue[j] + image->b(row + 1, col)) / 2;
}
} else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation
int row = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
int col = imwidth - 1 - j;
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->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(d1xClip) {
image->r(row, col) = MIN(image->r(row, col), MAXVALF);
image->g(row, col) = MIN(image->g(row, col), MAXVALF);
image->b(row, col) = MIN(image->b(row, col), MAXVALF);
}
}
}
} else if ((tran & TR_ROT) == TR_R90) { // rotate right
if( i == 0) {
for (int j = 0; j < imwidth; j++) {
image->r(j, 2 * imheight - 1) = red[j];
image->g(j, 2 * imheight - 1) = green[j];
image->b(j, 2 * imheight - 1) = blue[j];
}
}
for (int j = 0; j < imwidth; j++) {
image->r(j, 2 * imheight - 2 - 2 * i) = red[j];
image->g(j, 2 * imheight - 2 - 2 * i) = green[j];
image->b(j, 2 * imheight - 2 - 2 * i) = blue[j];
}
if (i == 1 || i == 2) { // linear interpolation
int col = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2;
image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2;
image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2;
if(d1xHeightOdd && i == 2) {
image->r(j, 2 * imheight) = (red[j] + image->r(j, 2 * imheight - 2)) / 2;
image->g(j, 2 * imheight) = (green[j] + image->g(j, 2 * imheight - 2)) / 2;
image->b(j, 2 * imheight) = (blue[j] + image->b(j, 2 * imheight - 2)) / 2;
}
}
} else if (i == imheight - 1) {
int col = 2 * imheight - 1 - 2 * i;
for (int j = 0; j < imwidth; j++) {
image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2;
image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2;
image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2;
}
col = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
image->r(j, col) = (red[j] + image->r(j, col + 1)) / 2;
image->g(j, col) = (green[j] + image->g(j, col + 1)) / 2;
image->b(j, col) = (blue[j] + image->b(j, col + 1)) / 2;
}
} else if (i > 2 && i < imheight - 1) { // vertical bicubic interpolation
int col = 2 * imheight - 1 - 2 * i + 2;
for (int j = 0; j < imwidth; j++) {
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->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(d1xClip) {
image->r(j, col) = MIN(image->r(j, col), MAXVALF);
image->g(j, col) = MIN(image->g(j, col), MAXVALF);
image->b(j, col) = MIN(image->b(j, col), MAXVALF);
}
}
}
} else if ((tran & TR_ROT) == TR_R270) { // rotate left
if (i == 0) {
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i) = red[j];
image->g(row, 2 * i) = green[j];
image->b(row, 2 * i) = blue[j];
}
} else if (i == 1 || i == 2) { // linear interpolation
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i) = red[j];
image->g(row, 2 * i) = green[j];
image->b(row, 2 * i) = blue[j];
image->r(row, 2 * i - 1) = (red[j] + image->r(row, 2 * i - 2)) * 0.5f;
image->g(row, 2 * i - 1) = (green[j] + image->g(row, 2 * i - 2)) * 0.5f;
image->b(row, 2 * i - 1) = (blue[j] + image->b(row, 2 * i - 2)) * 0.5f;
}
} else if (i > 0 && i < imheight) { // vertical bicubic interpolation
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i - 3) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 6)) + 0.5625f * (image->r(row, 2 * i - 2) + image->r(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)));
if(d1xClip) {
image->r(row, 2 * i - 3) = MIN(image->r(row, 2 * i - 3), MAXVALF);
image->g(row, 2 * i - 3) = MIN(image->g(row, 2 * i - 3), MAXVALF);
image->b(row, 2 * i - 3) = MIN(image->b(row, 2 * i - 3), MAXVALF);
}
image->r(row, 2 * i) = red[j];
image->g(row, 2 * i) = green[j];
image->b(row, 2 * i) = blue[j];
}
}
if (i == imheight - 1) {
for (int j = imwidth - 1, row = 0; j >= 0; j--, row++) {
image->r(row, 2 * i - 1) = MAX(0.f, -0.0625f * (red[j] + image->r(row, 2 * i - 4)) + 0.5625f * (image->r(row, 2 * i) + image->r(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)));
if(d1xClip) {
image->r(j, 2 * i - 1) = MIN(image->r(j, 2 * i - 1), MAXVALF);
image->g(j, 2 * i - 1) = MIN(image->g(j, 2 * i - 1), MAXVALF);
image->b(j, 2 * i - 1) = MIN(image->b(j, 2 * i - 1), MAXVALF);
}
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->b(row, 2 * i + 1) = (blue[j] + image->b(row, 2 * i - 1)) / 2;
if (d1xHeightOdd) {
image->r(row, 2 * i + 2) = (red[j] + image->r(row, 2 * i - 2)) / 2;
image->g(row, 2 * i + 2) = (green[j] + image->g(row, 2 * i - 2)) / 2;
image->b(row, 2 * i + 2) = (blue[j] + image->b(row, 2 * i - 2)) / 2;
}
}
}
} else { // no coarse rotation
rotateLine (red, image->r, tran, 2 * i, imwidth, imheight);
rotateLine (green, image->g, tran, 2 * i, imwidth, imheight);
rotateLine (blue, image->b, tran, 2 * i, imwidth, imheight);
if (i == 1 || i == 2) { // linear interpolation
for (int j = 0; j < imwidth; j++) {
image->r(2 * i - 1, j) = (red[j] + image->r(2 * i - 2, j)) / 2;
image->g(2 * i - 1, j) = (green[j] + image->g(2 * i - 2, j)) / 2;
image->b(2 * i - 1, j) = (blue[j] + image->b(2 * i - 2, j)) / 2;
}
} else if (i > 2 && i < imheight) { // vertical bicubic interpolation
for (int j = 0; j < imwidth; 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->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(d1xClip) {
image->r(2 * i - 3, j) = MIN(image->r(2 * i - 3, j), MAXVALF);
image->g(2 * i - 3, j) = MIN(image->g(2 * i - 3, j), MAXVALF);
image->b(2 * i - 3, j) = MIN(image->b(2 * i - 3, j), MAXVALF);
}
}
} if (i == imheight - 1) {
for (int j = 0; j < imwidth; j++) {
image->r(2 * i - 1, j) = MAX(0.f, -0.0625f * (red[j] + image->r(2 * i - 4, j)) + 0.5625f * (image->r(2 * i, j) + image->r(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)));
if(d1xClip) {
image->r(2 * i - 1, j) = MIN(image->r(2 * i - 1, j), MAXVALF);
image->g(2 * i - 1, j) = MIN(image->g(2 * i - 1, j), MAXVALF);
image->b(2 * i - 1, j) = MIN(image->b(2 * i - 1, j), MAXVALF);
}
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->b(2 * i + 1, j) = (blue[j] + image->b(2 * i - 1, j)) / 2;
if (d1xHeightOdd) {
image->r(2 * i + 2, j) = (red[j] + image->r(2 * i - 2, j)) / 2;
image->g(2 * i + 2, j) = (green[j] + image->g(2 * i - 2, j)) / 2;
image->b(2 * i + 2, j) = (blue[j] + image->b(2 * i - 2, j)) / 2;
}
}
}
}
} // if nikon dx1
// other (conventional) CCD coarse rotation
else {
rotateLine (red, image->r, tran, i, imwidth, imheight);
rotateLine (green, image->g, tran, i, imwidth, imheight);
rotateLine (blue, image->b, tran, i, imwidth, imheight);
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void RawImageSource::getFullSize (int& w, int& h, int tr)
@@ -2172,6 +2224,7 @@ void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdc
} else {
CurveFactory::curveDehaContL (retinexcontlutili, retinexParams.cdcurve, cdcurve, 1, lhist16RETI, histLRETI);
}
CurveFactory::mapcurve (mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI);
retinexParams.getCurves(retinextransmissionCurve);
@@ -2498,6 +2551,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC
}
}
}
rgbSourceModified = false; // tricky handling for Color propagation
t5.set();
@@ -2804,8 +2858,9 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, Raw
{
// TODO: Change type of black[] to float to avoid conversions
unsigned short black[4] = {
(unsigned short)ri->get_cblack(0), (unsigned short)ri->get_cblack(1),
(unsigned short)ri->get_cblack(2), (unsigned short)ri->get_cblack(3)};
(unsigned short)ri->get_cblack(0), (unsigned short)ri->get_cblack(1),
(unsigned short)ri->get_cblack(2), (unsigned short)ri->get_cblack(3)
};
if (ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS) {
if (!rawData) {
@@ -4281,7 +4336,8 @@ void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LU
const float mult[4] = { 65535.0f / ri->get_white(0),
65535.0f / ri->get_white(1),
65535.0f / ri->get_white(2),
65535.0f / ri->get_white(3) };
65535.0f / ri->get_white(3)
};
#ifdef _OPENMP
int numThreads;

View File

@@ -59,7 +59,6 @@ template<class T> void freeArray (T** a, int H)
template<class T> void freeArray2 (T** a, int H)
{
//for (int i=0; i<H; i++)
delete [] a[0];
}
@@ -130,7 +129,6 @@ protected:
void processFalseColorCorrectionThread (Imagefloat* im, int row_from, int row_to);
void hlRecovery (std::string method, float* red, float* green, float* blue, int i, int sx1, int width, int skip, const RAWParams &raw, float* hlmax);
int defTransform (int tran);
void rotateLine (const float* const line, PlanarPtr<float> &channel, const int tran, const int i, const int w, const int h);
void transformRect (PreviewProps pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw);
void transformPosition (int x, int y, int tran, int& tx, int& ty);
@@ -151,7 +149,6 @@ public:
int load (Glib::ustring fname, bool batch = false);
void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse);
void demosaic (const RAWParams &raw);
// void retinex (RAWParams raw, ColorManagementParams cmp, RetinexParams lcur, LUTf & cdcurve, bool dehacontlutili);
void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI);
void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI);
void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI);
@@ -231,13 +228,7 @@ public:
void boxblur2(float** src, float** dst, float** temp, int H, int W, int box );
void boxblur_resamp(float **src, float **dst, float** temp, int H, int W, int box, int samp );
void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax);
// void MSR(LabImage* lab, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve);
//void boxblur_resamp(float **red, float **green, float **blue, int H, int W, float thresh[3], float max[3],
// multi_array2D<float,3> & hfsize, multi_array2D<float,3> & hilite, int box );
void HLRecovery_inpaint (float** red, float** green, float** blue);
//void HLRecovery_inpaint ();
static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval);
static void HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]);
static void HLRecovery_blend (float* rin, float* gin, float* bin, int width, float maxval, float* hlmax);
@@ -277,8 +268,6 @@ protected:
void jdl_interpolate_omp();
void igv_interpolate(int winw, int winh);
void lmmse_interpolate_omp(int winw, int winh, int iterations);
// void MSR(LabImage* lab, int width, int height, int skip, const LCurveParams &lcur);
void amaze_demosaic_RT(int winx, int winy, int winw, int winh);//Emil's code for AMaZE
void fast_demosaic(int winx, int winy, int winw, int winh );//Emil's code for fast demosaicing
void dcb_demosaic(int iterations, bool dcb_enhance);
@@ -303,7 +292,6 @@ protected:
void xtransborder_interpolate (int border);
void xtrans_interpolate (int passes, bool useCieLab);
void fast_xtrans_interpolate ();
void transLine (float* red, float* green, float* blue, int i, Imagefloat* image, int tran, int imw, int imh, int fw, bool d1xHeightOdd = false, bool d1xClip = false);
void hflip (Imagefloat* im);
void vflip (Imagefloat* im);