From 894fb8d9b3d847b9515742501af5f50e36c750a6 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 30 Oct 2018 13:45:44 +0100 Subject: [PATCH] vng4 demosaic: another small speedup, #4633 --- rtengine/vng4_demosaic_RT.cc | 216 ++++++++++++++++++++++++----------- 1 file changed, 148 insertions(+), 68 deletions(-) diff --git a/rtengine/vng4_demosaic_RT.cc b/rtengine/vng4_demosaic_RT.cc index ed3ef8802..1c7f27dea 100644 --- a/rtengine/vng4_demosaic_RT.cc +++ b/rtengine/vng4_demosaic_RT.cc @@ -22,12 +22,41 @@ #include "rtengine.h" #include "rawimagesource.h" -#include "rawimagesource_i.h" #include "../rtgui/multilangmgr.h" //#define BENCHMARK #include "StopWatch.h" +namespace { + +using namespace rtengine; + +inline void vng4interpolate_row_redblue (const RawImage *ri, const array2D &rawData, float* ar, float* ab, const float * const pg, const float * const cg, const float * const ng, int i, int width) +{ + if (ri->ISBLUE(i, 0) || ri->ISBLUE(i, 1)) { + std::swap(ar, ab); + } + + // RGRGR or GRGRGR line + for (int j = 3; j < width - 3; ++j) { + if (!ri->ISGREEN(i, j)) { + // keep original value + ar[j] = rawData[i][j]; + // cross interpolation of red/blue + float rb = (rawData[i - 1][j - 1] - pg[j - 1] + rawData[i + 1][j - 1] - ng[j - 1]); + rb += (rawData[i - 1][j + 1] - pg[j + 1] + rawData[i + 1][j + 1] - ng[j + 1]); + ab[j] = cg[j] + rb * 0.25f; + } else { + // linear R/B-G interpolation horizontally + ar[j] = cg[j] + (rawData[i][j - 1] - cg[j - 1] + rawData[i][j + 1] - cg[j + 1]) / 2; + // linear B/R-G interpolation vertically + ab[j] = cg[j] + (rawData[i - 1][j] - pg[j] + rawData[i + 1][j] - ng[j]) / 2; + } + } +} +} + namespace rtengine + { #define fc(row,col) (prefilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) @@ -74,65 +103,106 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D firstRow) { + int row = ii - 1; + for (int col = 1; col < width - 1; col++) { + float * pix = image[row * width + col]; + int * ip = lcode[row & 15][col & 15]; + float sum[4] = {}; + + for (int i = 0; i < 8; i++, ip += 2) { + sum[ip[1]] += pix[ip[0]] * mul[row & 15][col & 15][i]; + } + + for (unsigned int i = 0; i < colors - 1; i++, ip++) { + pix[ip[0]] = sum[ip[0]] * csum[row & 15][col & 15][i]; + } + } + } + } + + // now all rows are processed except the first and last row of each chunk + // let's process them now but skip row 0 and row H - 1 + if (firstRow > 0 && firstRow < H - 1) { + const int row = firstRow; for (int col = 1; col < width - 1; col++) { float * pix = image[row * width + col]; int * ip = lcode[row & 15][col & 15]; - float sum[4]; - memset (sum, 0, sizeof sum); + float sum[4] = {}; + + for (int i = 0; i < 8; i++, ip += 2) { + sum[ip[1]] += pix[ip[0]] * mul[row & 15][col & 15][i]; + } + + for (unsigned int i = 0; i < colors - 1; i++, ip++) { + pix[ip[0]] = sum[ip[0]] * csum[row & 15][col & 15][i]; + } + } + } + + if (lastRow > 0 && lastRow < H - 1) { + const int row = lastRow; + for (int col = 1; col < width - 1; col++) { + float * pix = image[row * width + col]; + int * ip = lcode[row & 15][col & 15]; + float sum[4] = {}; for (int i = 0; i < 8; i++, ip += 2) { sum[ip[1]] += pix[ip[0]] * mul[row & 15][col & 15][i]; @@ -145,16 +215,15 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D &rawData, array2D(ip++) = 1 << weight; +#else *ip++ = 1 << weight; - - for (g = 0; g < 8; g++) +#endif + for (int g = 0; g < 8; g++) if (grads & (1 << g)) { *ip++ = g; } @@ -187,7 +260,8 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D &rawData, array2DsetProgress (progress); } @@ -211,7 +285,7 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D &rawData, array2D float conversions + const float diff = std::fabs(pix[ip[0]] - pix[ip[1]]) * reinterpret_cast(ip)[2]; +#else const float diff = std::fabs(pix[ip[0]] - pix[ip[1]]) * ip[2]; +#endif gval[ip[3]] += diff; ip += 5; if (UNLIKELY(ip[-1] != -1)) { @@ -246,17 +325,18 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D &rawData, array2D firstRow) { - interpolate_row_rb_mul_pp(rawData, red[row - 1], blue[row - 1], green[row - 2], green[row - 1], green[row], row - 1, 1.0, 1.0, 1.0, 0, W, 1); + vng4interpolate_row_redblue(ri, rawData, red[row - 1], blue[row - 1], green[row - 2], green[row - 1], green[row], row - 1, W); } if(plistenerActive) { @@ -292,11 +372,11 @@ void RawImageSource::vng4_demosaic (const array2D &rawData, array2D 2 && firstRow < H - 3) { - interpolate_row_rb_mul_pp(rawData, red[firstRow], blue[firstRow], green[firstRow - 1], green[firstRow], green[firstRow + 1], firstRow, 1.0, 1.0, 1.0, 0, W, 1); + vng4interpolate_row_redblue(ri, rawData, red[firstRow], blue[firstRow], green[firstRow - 1], green[firstRow], green[firstRow + 1], firstRow, W); } if (lastRow > 2 && lastRow < H - 3) { - interpolate_row_rb_mul_pp(rawData, red[lastRow], blue[lastRow], green[lastRow - 1], green[lastRow], green[lastRow + 1], lastRow, 1.0, 1.0, 1.0, 0, W, 1); + vng4interpolate_row_redblue(ri, rawData, red[lastRow], blue[lastRow], green[lastRow - 1], green[lastRow], green[lastRow + 1], lastRow, W); } #ifdef _OPENMP #pragma omp single