Merge pull request #3215 from Beep6581/falsecoloursuppression

Speedups for raw false colour suppression
This commit is contained in:
Ingo Weyrich 2016-03-13 23:25:36 +01:00
commit bc38a58297
5 changed files with 183 additions and 118 deletions

View File

@ -22,7 +22,6 @@
#include "rawimagesource.h" #include "rawimagesource.h"
#include "rawimagesource_i.h" #include "rawimagesource_i.h"
#include "jaggedarray.h" #include "jaggedarray.h"
#include "median.h"
#include "rawimage.h" #include "rawimage.h"
#include "mytime.h" #include "mytime.h"
#include "iccmatrices.h" #include "iccmatrices.h"

View File

@ -18,17 +18,8 @@
*/ */
#include "rt_math.h" #include "rt_math.h"
#define SORT3(a1,a2,a3,b1,b2,b3) \ // middle 4 of 6 elements,
{ \ #define MIDDLE4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \
b2 = min(a1,a2);\
b1 = min(b2,a3);\
b3 = max(a1,a2);\
b2 = max(b2, min(b3,a3));\
b3 = max(b3,a3);\
}
#define NETWORKSORT4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \
{\ {\
d1 = min(s1,s2);\ d1 = min(s1,s2);\
d2 = max(s1,s2);\ d2 = max(s1,s2);\
@ -39,28 +30,35 @@ d1 = max(d0,d1);\
d0 = temp;\ d0 = temp;\
d4 = min(s4,s5);\ d4 = min(s4,s5);\
d5 = max(s4,s5);\ d5 = max(s4,s5);\
temp = min(s3,d5);\ d3 = min(s3,d5);\
d5 = max(s3,d5);\ d5 = max(s3,d5);\
d3 = temp;\
temp = min(d3,d4);\ temp = min(d3,d4);\
d4 = max(d3,d4);\ d4 = max(d3,d4);\
d3 = temp;\ d3 = max(d0,temp);\
d3 = max(d0,d3);\
temp = min(d1,d4);\
d4 = max(d1,d4);\
d1 = temp;\
d2 = min(d2,d5);\ d2 = min(d2,d5);\
temp = min(d2,d4);\
d4 = max(d2,d4);\
d2 = temp;\
temp = min(d1,d3);\
d3 = max(d1,d3);\
d1 = temp;\
temp = min(d2,d3);\
d3 = max(d2,d3);\
d2 = temp;\
} }
// middle 4 of 6 elements, vectorized
#define VMIDDLE4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \
{\
d1 = vminf(s1,s2);\
d2 = vmaxf(s1,s2);\
d0 = vminf(s0,d2);\
d2 = vmaxf(s0,d2);\
temp = vminf(d0,d1);\
d1 = vmaxf(d0,d1);\
d0 = temp;\
d4 = vminf(s4,s5);\
d5 = vmaxf(s4,s5);\
d3 = vminf(s3,d5);\
d5 = vmaxf(s3,d5);\
temp = vminf(d3,d4);\
d4 = vmaxf(d3,d4);\
d3 = vmaxf(d0,temp);\
d2 = vminf(d2,d5);\
}
#define MEDIAN7(s0,s1,s2,s3,s4,s5,s6,t0,t1,t2,t3,t4,t5,t6,median) \ #define MEDIAN7(s0,s1,s2,s3,s4,s5,s6,t0,t1,t2,t3,t4,t5,t6,median) \
{\ {\
t0 = min(s0,s5);\ t0 = min(s0,s5);\
@ -77,13 +75,36 @@ t5 = max(t3,t5);\
t3 = median;\ t3 = median;\
median = min(t2,t6);\ median = min(t2,t6);\
t6 = max(t2,t6);\ t6 = max(t2,t6);\
t2 = median;\ t3 = max(median,t3);\
t3 = max(t2,t3);\
t3 = min(t3,t6);\ t3 = min(t3,t6);\
t4 = min(t4,t5);\ t4 = min(t4,t5);\
median = min(t1,t4);\ median = min(t1,t4);\
t4 = max(t1,t4);\ t4 = max(t1,t4);\
t1 = median;\ t3 = max(median,t3);\
t3 = max(t1,t3);\
median = min(t3,t4);\ median = min(t3,t4);\
} }
#define VMEDIAN7(s0,s1,s2,s3,s4,s5,s6,t0,t1,t2,t3,t4,t5,t6,median) \
{\
t0 = vminf(s0,s5);\
t5 = vmaxf(s0,s5);\
t3 = vmaxf(t0,s3);\
t0 = vminf(t0,s3);\
t1 = vminf(s1,s6);\
t6 = vmaxf(s1,s6);\
t2 = vminf(s2,s4);\
t4 = vmaxf(s2,s4);\
t1 = vmaxf(t0,t1);\
median = vminf(t3,t5);\
t5 = vmaxf(t3,t5);\
t3 = median;\
median = vminf(t2,t6);\
t6 = vmaxf(t2,t6);\
t3 = vmaxf(median,t3);\
t3 = vminf(t3,t6);\
t4 = vminf(t4,t5);\
median = vminf(t1,t4);\
t4 = vmaxf(t1,t4);\
t3 = vmaxf(median,t3);\
median = vminf(t3,t4);\
}

View File

@ -3387,33 +3387,30 @@ int RawImageSource::defTransform (int tran)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Thread called part // Thread called part
void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, const int row_from, const int row_to) void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D<float> &rbconv_Y, array2D<float> &rbconv_I, array2D<float> &rbconv_Q, array2D<float> &rbout_I, array2D<float> &rbout_Q, const int row_from, const int row_to)
{ {
int W = im->width; const int W = im->width;
constexpr float onebynine = 1.f / 9.f;
array2D<float> rbconv_Y (W, 3); #ifdef __SSE2__
array2D<float> rbconv_I (W, 3); vfloat buffer[12];
array2D<float> rbconv_Q (W, 3); vfloat* pre1 = &buffer[0];
array2D<float> rbout_I (W, 3); vfloat* pre2 = &buffer[3];
array2D<float> rbout_Q (W, 3); vfloat* post1 = &buffer[6];
vfloat* post2 = &buffer[9];
float row_I[W]; vfloat middle[6];
float row_Q[W];
float buffer[3 * 8]; #else
float* pre1_I = &buffer[0]; float buffer[12];
float* pre2_I = &buffer[3]; float* pre1 = &buffer[0];
float* post1_I = &buffer[6]; float* pre2 = &buffer[3];
float* post2_I = &buffer[9]; float* post1 = &buffer[6];
float* pre1_Q = &buffer[12]; float* post2 = &buffer[9];
float* pre2_Q = &buffer[15];
float* post1_Q = &buffer[18];
float* post2_Q = &buffer[21];
float middle_I[6]; float middle[6];
float middle_Q[6]; #endif
float* tmp;
int px = (row_from - 1) % 3, cx = row_from % 3, nx = 0; int px = (row_from - 1) % 3, cx = row_from % 3, nx = 0;
@ -3433,82 +3430,113 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, const i
convert_row_to_YIQ (im->r(i + 1), im->g(i + 1), im->b(i + 1), rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W); convert_row_to_YIQ (im->r(i + 1), im->g(i + 1), im->b(i + 1), rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W);
SORT3(rbconv_I[px][0], rbconv_I[cx][0], rbconv_I[nx][0], pre1_I[0], pre1_I[1], pre1_I[2]); #ifdef __SSE2__
SORT3(rbconv_I[px][1], rbconv_I[cx][1], rbconv_I[nx][1], pre2_I[0], pre2_I[1], pre2_I[2]); pre1[0] = _mm_setr_ps(rbconv_I[px][0], rbconv_Q[px][0], 0, 0) , pre1[1] = _mm_setr_ps(rbconv_I[cx][0], rbconv_Q[cx][0], 0, 0), pre1[2] = _mm_setr_ps(rbconv_I[nx][0], rbconv_Q[nx][0], 0, 0);
SORT3(rbconv_Q[px][0], rbconv_Q[cx][0], rbconv_Q[nx][0], pre1_Q[0], pre1_Q[1], pre1_Q[2]); pre2[0] = _mm_setr_ps(rbconv_I[px][1], rbconv_Q[px][1], 0, 0) , pre2[1] = _mm_setr_ps(rbconv_I[cx][1], rbconv_Q[cx][1], 0, 0), pre2[2] = _mm_setr_ps(rbconv_I[nx][1], rbconv_Q[nx][1], 0, 0);
SORT3(rbconv_Q[px][1], rbconv_Q[cx][1], rbconv_Q[nx][1], pre2_Q[0], pre2_Q[1], pre2_Q[2]); vfloat temp[7];
// fill first element in rbout_I and rbout_Q
rbout_I[cx][0] = rbconv_I[cx][0];
rbout_Q[cx][0] = rbconv_Q[cx][0];
// median I channel // median I channel
float temp[7];
for (int j = 1; j < W - 2; j += 2) { for (int j = 1; j < W - 2; j += 2) {
SORT3(rbconv_I[px][j + 1], rbconv_I[cx][j + 1], rbconv_I[nx][j + 1], post1_I[0], post1_I[1], post1_I[2]); post1[0] = _mm_setr_ps(rbconv_I[px][j + 1], rbconv_Q[px][j + 1], 0, 0), post1[1] = _mm_setr_ps(rbconv_I[cx][j + 1], rbconv_Q[cx][j + 1], 0, 0), post1[2] = _mm_setr_ps(rbconv_I[nx][j + 1], rbconv_Q[nx][j + 1], 0, 0);
NETWORKSORT4OF6(pre2_I[0], pre2_I[1], pre2_I[2], post1_I[0], post1_I[1], post1_I[2], middle_I[0], middle_I[1], middle_I[2], middle_I[3], middle_I[4], middle_I[5], temp[0]); VMIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]);
SORT3(rbconv_I[px][j + 2], rbconv_I[cx][j + 2], rbconv_I[nx][j + 2], post2_I[0], post2_I[1], post2_I[2]); vfloat medianval;
MEDIAN7(pre1_I[0], pre1_I[1], pre1_I[2], middle_I[1], middle_I[2], middle_I[3], middle_I[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j]); VMEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], medianval);
MEDIAN7(post2_I[0], post2_I[1], post2_I[2], middle_I[1], middle_I[2], middle_I[3], middle_I[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j + 1]); rbout_I[cx][j] = medianval[0];
tmp = pre1_I; rbout_Q[cx][j] = medianval[1];
pre1_I = post1_I; post2[0] = _mm_setr_ps(rbconv_I[px][j + 2], rbconv_Q[px][j + 2], 0, 0), post2[1] = _mm_setr_ps(rbconv_I[cx][j + 2], rbconv_Q[cx][j + 2], 0, 0), post2[2] = _mm_setr_ps(rbconv_I[nx][j + 2], rbconv_Q[nx][j + 2], 0, 0);
post1_I = tmp; VMEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], medianval);
tmp = pre2_I; rbout_I[cx][j + 1] = medianval[0];
pre2_I = post2_I; rbout_Q[cx][j + 1] = medianval[1];
post2_I = tmp; std::swap(pre1, post1);
std::swap(pre2, post2);
} }
// median Q channel // fill last elements in rbout_I and rbout_Q
for (int j = 1; j < W - 2; j += 2) {
SORT3(rbconv_Q[px][j + 1], rbconv_Q[cx][j + 1], rbconv_Q[nx][j + 1], post1_Q[0], post1_Q[1], post1_Q[2]);
NETWORKSORT4OF6(pre2_Q[0], pre2_Q[1], pre2_Q[2], post1_Q[0], post1_Q[1], post1_Q[2], middle_Q[0], middle_Q[1], middle_Q[2], middle_Q[3], middle_Q[4], middle_Q[5], temp[0]);
SORT3(rbconv_Q[px][j + 2], rbconv_Q[cx][j + 2], rbconv_Q[nx][j + 2], post2_Q[0], post2_Q[1], post2_Q[2]);
MEDIAN7(pre1_Q[0], pre1_Q[1], pre1_Q[2], middle_Q[1], middle_Q[2], middle_Q[3], middle_Q[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j]);
MEDIAN7(post2_Q[0], post2_Q[1], post2_Q[2], middle_Q[1], middle_Q[2], middle_Q[3], middle_Q[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j + 1]);
tmp = pre1_Q;
pre1_Q = post1_Q;
post1_Q = tmp;
tmp = pre2_Q;
pre2_Q = post2_Q;
post2_Q = tmp;
}
// fill first and last element in rbout
rbout_I[cx][0] = rbconv_I[cx][0];
rbout_I[cx][W - 1] = rbconv_I[cx][W - 1]; rbout_I[cx][W - 1] = rbconv_I[cx][W - 1];
rbout_I[cx][W - 2] = rbconv_I[cx][W - 2]; rbout_I[cx][W - 2] = rbconv_I[cx][W - 2];
rbout_Q[cx][0] = rbconv_Q[cx][0];
rbout_Q[cx][W - 1] = rbconv_Q[cx][W - 1]; rbout_Q[cx][W - 1] = rbconv_Q[cx][W - 1];
rbout_Q[cx][W - 2] = rbconv_Q[cx][W - 2]; rbout_Q[cx][W - 2] = rbconv_Q[cx][W - 2];
#else
pre1[0] = rbconv_I[px][0], pre1[1] = rbconv_I[cx][0], pre1[2] = rbconv_I[nx][0];
pre2[0] = rbconv_I[px][1], pre2[1] = rbconv_I[cx][1], pre2[2] = rbconv_I[nx][1];
float temp[7];
// fill first element in rbout_I
rbout_I[cx][0] = rbconv_I[cx][0];
// median I channel
for (int j = 1; j < W - 2; j += 2) {
post1[0] = rbconv_I[px][j + 1], post1[1] = rbconv_I[cx][j + 1], post1[2] = rbconv_I[nx][j + 1];
MIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]);
MEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j]);
post2[0] = rbconv_I[px][j + 2], post2[1] = rbconv_I[cx][j + 2], post2[2] = rbconv_I[nx][j + 2];
MEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j + 1]);
std::swap(pre1, post1);
std::swap(pre2, post2);
}
// fill last elements in rbout_I
rbout_I[cx][W - 1] = rbconv_I[cx][W - 1];
rbout_I[cx][W - 2] = rbconv_I[cx][W - 2];
pre1[0] = rbconv_Q[px][0], pre1[1] = rbconv_Q[cx][0], pre1[2] = rbconv_Q[nx][0];
pre2[0] = rbconv_Q[px][1], pre2[1] = rbconv_Q[cx][1], pre2[2] = rbconv_Q[nx][1];
// fill first element in rbout_Q
rbout_Q[cx][0] = rbconv_Q[cx][0];
// median Q channel
for (int j = 1; j < W - 2; j += 2) {
post1[0] = rbconv_Q[px][j + 1], post1[1] = rbconv_Q[cx][j + 1], post1[2] = rbconv_Q[nx][j + 1];
MIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]);
MEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j]);
post2[0] = rbconv_Q[px][j + 2], post2[1] = rbconv_Q[cx][j + 2], post2[2] = rbconv_Q[nx][j + 2];
MEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j + 1]);
std::swap(pre1, post1);
std::swap(pre2, post2);
}
// fill last elements in rbout_Q
rbout_Q[cx][W - 1] = rbconv_Q[cx][W - 1];
rbout_Q[cx][W - 2] = rbconv_Q[cx][W - 2];
#endif
// blur i-1th row // blur i-1th row
if (i > row_from) { if (i > row_from) {
convert_to_RGB (im->r(i - 1, 0), im->g(i - 1, 0), im->b(i - 1, 0), rbconv_Y[px][0], rbout_I[px][0], rbout_Q[px][0]);
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp simd #pragma omp simd
#endif #endif
for (int j = 1; j < W - 1; j++) { for (int j = 1; j < W - 1; j++) {
row_I[j] = (rbout_I[px][j - 1] + rbout_I[px][j] + rbout_I[px][j + 1] + rbout_I[cx][j - 1] + rbout_I[cx][j] + rbout_I[cx][j + 1] + rbout_I[nx][j - 1] + rbout_I[nx][j] + rbout_I[nx][j + 1]) / 9; float I = (rbout_I[px][j - 1] + rbout_I[px][j] + rbout_I[px][j + 1] + rbout_I[cx][j - 1] + rbout_I[cx][j] + rbout_I[cx][j + 1] + rbout_I[nx][j - 1] + rbout_I[nx][j] + rbout_I[nx][j + 1]) * onebynine;
row_Q[j] = (rbout_Q[px][j - 1] + rbout_Q[px][j] + rbout_Q[px][j + 1] + rbout_Q[cx][j - 1] + rbout_Q[cx][j] + rbout_Q[cx][j + 1] + rbout_Q[nx][j - 1] + rbout_Q[nx][j] + rbout_Q[nx][j + 1]) / 9; float Q = (rbout_Q[px][j - 1] + rbout_Q[px][j] + rbout_Q[px][j + 1] + rbout_Q[cx][j - 1] + rbout_Q[cx][j] + rbout_Q[cx][j + 1] + rbout_Q[nx][j - 1] + rbout_Q[nx][j] + rbout_Q[nx][j + 1]) * onebynine;
convert_to_RGB (im->r(i - 1, j), im->g(i - 1, j), im->b(i - 1, j), rbconv_Y[px][j], I, Q);
} }
row_I[0] = rbout_I[px][0]; convert_to_RGB (im->r(i - 1, W - 1), im->g(i - 1, W - 1), im->b(i - 1, W - 1), rbconv_Y[px][W - 1], rbout_I[px][W - 1], rbout_Q[px][W - 1]);
row_Q[0] = rbout_Q[px][0];
row_I[W - 1] = rbout_I[px][W - 1];
row_Q[W - 1] = rbout_Q[px][W - 1];
convert_row_to_RGB (im->r(i - 1), im->g(i - 1), im->b(i - 1), rbconv_Y[px], row_I, row_Q, W);
} }
} }
// blur last 3 row and finalize H-1th row // blur last 3 row and finalize H-1th row
convert_to_RGB (im->r(row_to - 1, 0), im->g(row_to - 1, 0), im->b(row_to - 1, 0), rbconv_Y[cx][0], rbout_I[cx][0], rbout_Q[cx][0]);
#ifdef _OPENMP
#pragma omp simd
#endif
for (int j = 1; j < W - 1; j++) { for (int j = 1; j < W - 1; j++) {
row_I[j] = (rbout_I[px][j - 1] + rbout_I[px][j] + rbout_I[px][j + 1] + rbout_I[cx][j - 1] + rbout_I[cx][j] + rbout_I[cx][j + 1] + rbconv_I[nx][j - 1] + rbconv_I[nx][j] + rbconv_I[nx][j + 1]) / 9; float I = (rbout_I[px][j - 1] + rbout_I[px][j] + rbout_I[px][j + 1] + rbout_I[cx][j - 1] + rbout_I[cx][j] + rbout_I[cx][j + 1] + rbconv_I[nx][j - 1] + rbconv_I[nx][j] + rbconv_I[nx][j + 1]) * onebynine;
row_Q[j] = (rbout_Q[px][j - 1] + rbout_Q[px][j] + rbout_Q[px][j + 1] + rbout_Q[cx][j - 1] + rbout_Q[cx][j] + rbout_Q[cx][j + 1] + rbconv_Q[nx][j - 1] + rbconv_Q[nx][j] + rbconv_Q[nx][j + 1]) / 9; float Q = (rbout_Q[px][j - 1] + rbout_Q[px][j] + rbout_Q[px][j + 1] + rbout_Q[cx][j - 1] + rbout_Q[cx][j] + rbout_Q[cx][j + 1] + rbconv_Q[nx][j - 1] + rbconv_Q[nx][j] + rbconv_Q[nx][j + 1]) * onebynine;
convert_to_RGB (im->r(row_to - 1, j), im->g(row_to - 1, j), im->b(row_to - 1, j), rbconv_Y[cx][j], I, Q);
} }
row_I[0] = rbout_I[cx][0]; convert_to_RGB (im->r(row_to - 1, W - 1), im->g(row_to - 1, W - 1), im->b(row_to - 1, W - 1), rbconv_Y[cx][W - 1], rbout_I[cx][W - 1], rbout_Q[cx][W - 1]);
row_Q[0] = rbout_Q[cx][0];
row_I[W - 1] = rbout_I[cx][W - 1];
row_Q[W - 1] = rbout_Q[cx][W - 1];
convert_row_to_RGB (im->r(row_to - 1), im->g(row_to - 1), im->b(row_to - 1), rbconv_Y[cx], row_I, row_Q, W);
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -3521,24 +3549,33 @@ void RawImageSource::processFalseColorCorrection (Imagefloat* im, const int ste
return; return;
} }
for (int t = 0; t < steps; t++) {
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel #pragma omp parallel
{ {
int tid = omp_get_thread_num(); multi_array2D<float, 5> buffer (W, 3);
int nthreads = omp_get_num_threads(); int tid = omp_get_thread_num();
int blk = (im->height - 2) / nthreads; int nthreads = omp_get_num_threads();
int blk = (im->height - 2) / nthreads;
if (tid < nthreads - 1) for (int t = 0; t < steps; t++) {
{
processFalseColorCorrectionThread (im, 1 + tid * blk, 1 + (tid + 1)*blk); if (tid < nthreads - 1) {
} else processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, 1 + (tid + 1)*blk);
{ processFalseColorCorrectionThread (im, 1 + tid * blk, im->height - 1); } } else {
processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 + tid * blk, im->height - 1);
}
#pragma omp barrier
} }
#else
processFalseColorCorrectionThread (im, 1 , im->height - 1);
#endif
} }
#else
multi_array2D<float, 5> buffer (W, 3);
for (int t = 0; t < steps; t++) {
processFalseColorCorrectionThread (im, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], 1 , im->height - 1);
}
#endif
} }
// Some camera input profiles need gamma preprocessing // Some camera input profiles need gamma preprocessing

View File

@ -95,7 +95,7 @@ protected:
void hphd_vertical (float** hpmap, int col_from, int col_to); void hphd_vertical (float** hpmap, int col_from, int col_to);
void hphd_horizontal (float** hpmap, int row_from, int row_to); void hphd_horizontal (float** hpmap, int row_from, int row_to);
void hphd_green (float** hpmap); void hphd_green (float** hpmap);
void processFalseColorCorrectionThread (Imagefloat* im, const int row_from, const int row_to); void processFalseColorCorrectionThread (Imagefloat* im, array2D<float> &rbconv_Y, array2D<float> &rbconv_I, array2D<float> &rbconv_Q, array2D<float> &rbout_I, array2D<float> &rbout_Q, const int row_from, const 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); 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); int defTransform (int tran);
void transformRect (PreviewProps pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw); void transformRect (PreviewProps pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw);
@ -209,6 +209,7 @@ protected:
void processFalseColorCorrection (Imagefloat* i, const int steps); void processFalseColorCorrection (Imagefloat* i, const int steps);
inline void convert_row_to_YIQ (const float* const r, const float* const g, const float* const b, float* Y, float* I, float* Q, const int W); inline void convert_row_to_YIQ (const float* const r, const float* const g, const float* const b, float* Y, float* I, float* Q, const int W);
inline void convert_row_to_RGB (float* r, float* g, float* b, const float* const Y, const float* const I, const float* const Q, const int W); inline void convert_row_to_RGB (float* r, float* g, float* b, const float* const Y, const float* const I, const float* const Q, const int W);
inline void convert_to_RGB (float &r, float &g, float &b, const float Y, const float I, const float Q);
inline void convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob); inline void convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob);
inline void interpolate_row_g (float* agh, float* agv, int i); inline void interpolate_row_g (float* agh, float* agv, int i);

View File

@ -51,6 +51,13 @@ inline void RawImageSource::convert_row_to_RGB (float* r, float* g, float* b, co
} }
} }
inline void RawImageSource::convert_to_RGB (float &r, float &g, float &b, const float Y, const float I, const float Q)
{
r = Y + 0.956f * I + 0.621f * Q;
g = Y - 0.272f * I - 0.647f * Q;
b = Y - 1.105f * I + 1.702f * Q;
}
inline void RawImageSource::convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob) inline void RawImageSource::convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob)
{ {