Optimization of RawImage::get_colorsCoeff, Issue 2227

This commit is contained in:
Ingo
2014-02-05 23:09:55 +01:00
parent f2c4846dce
commit 906cd4ba3a

View File

@@ -47,9 +47,8 @@ RawImage::~RawImage()
/* Similar to dcraw scale_colors for coeff. calculation, but without actual pixels scaling. /* Similar to dcraw scale_colors for coeff. calculation, but without actual pixels scaling.
* need pixels in data[][] available * need pixels in data[][] available
*/ */
void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblack_, bool forceAutoWB) void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblack_, bool forceAutoWB) {
{
unsigned row, col, x, y, c, sum[8]; unsigned row, col, x, y, c, sum[8];
unsigned W = this->get_width(); unsigned W = this->get_width();
unsigned H = this->get_height(); unsigned H = this->get_height();
@@ -71,30 +70,90 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
} }
if ( this->get_cam_mul(0) == -1 || forceAutoWB) { if ( this->get_cam_mul(0) == -1 || forceAutoWB) {
memset(dsum, 0, sizeof dsum); memset(dsum, 0, sizeof dsum);
for (row = 0; row < H; row += 8) if (this->isBayer()) {
for (col = 0; col < W ; col += 8) { // calculate number of pixels per color
memset(sum, 0, sizeof sum); dsum[FC(0,0)+4] += (int)(((W+1)/2) * ((H+1)/2));
for (y = row; y < row + 8 && y < H; y++) dsum[FC(0,1)+4] += (int)(((W/2) * ((H+1)/2)));
for (x = col; x < col + 8 && x < W; x++) dsum[FC(1,0)+4] += (int)(((W+1)/2) * (H/2));
for (int c = 0; c < 3; c++) { dsum[FC(1,1)+4] += (int)((W/2) * (H/2));
if (this->isBayer()) {
c = FC(y, x); #pragma omp parallel private(val,row,col,x,y)
val = data[y][x]; {
} else double dsumthr[8];
val = data[y][3*x+c]; memset(dsumthr, 0, sizeof dsumthr);
if (val > this->get_white(c) - 25) int sum[4];
goto skip_block; // make local copies of the black and white values to avoid calculations and conversions
if ((val -= cblack_[c]) < 0) int cblackint[4];
val = 0; int whiteint[4];
sum[c] += val; for (int c = 0; c < 4; c++) {
sum[c + 4]++; cblackint[c] = cblack_[c];
if ( this->isBayer()) whiteint[c] = this->get_white(c) - 25;
break;
}
for (c = 0; c < 8; c++)
dsum[c] += sum[c];
skip_block: ;
} }
unsigned short *tempdata = data[0];
#pragma omp for nowait
for (row = 0; row < H; row += 8) {
int ymax = row + 8 < H ? row + 8 : H;
for (col = 0; col < W ; col += 8) {
int xmax = col + 8 < W ? col + 8 : W;
memset(sum, 0, sizeof sum);
for (y = row; y < ymax; y++)
for (x = col; x < xmax; x++) {
int c = FC(y, x);
val = tempdata[y*W+x];
if (val > whiteint[c]) { // calculate number of pixels to be substracted from sum and skip the block
dsumthr[FC(row,col)+4] += (int)(((xmax - col + 1)/2) * ((ymax - row + 1)/2));
dsumthr[FC(row,col+1)+4] += (int)(((xmax - col)/2) * ((ymax - row + 1)/2));
dsumthr[FC(row+1,col)+4] += (int)(((xmax - col + 1)/2) * ((ymax - row)/2));
dsumthr[FC(row+1,col+1)+4] += (int)(((xmax - col)/2) * ((ymax - row)/2));
goto skip_block2;
}
if (val < cblackint[c])
val = cblackint[c];
sum[c] += val;
}
for (int c = 0; c < 4; c++)
dsumthr[c] += sum[c];
skip_block2: ;
}
}
#pragma omp critical
{
for (int c = 0; c < 4; c++)
dsum[c] += dsumthr[c];
for (int c = 4; c < 8; c++)
dsum[c] -= dsumthr[c];
}
}
for(int c=0;c<4;c++)
dsum[c] -= cblack_[c] * dsum[c+4];
} else {
for (row = 0; row < H; row += 8)
for (col = 0; col < W ; col += 8) {
memset(sum, 0, sizeof sum);
for (y = row; y < row + 8 && y < H; y++)
for (x = col; x < col + 8 && x < W; x++)
for (int c = 0; c < 3; c++) {
if (this->isBayer()) {
c = FC(y, x);
val = data[y][x];
} else
val = data[y][3*x+c];
if (val > this->get_white(c) - 25)
goto skip_block;
if ((val -= cblack_[c]) < 0)
val = 0;
sum[c] += val;
sum[c + 4]++;
if ( this->isBayer())
break;
}
for (c = 0; c < 8; c++)
dsum[c] += sum[c];
skip_block: ;
}
}
for (int c = 0; c < 4; c++) for (int c = 0; c < 4; c++)
if (dsum[c]) if (dsum[c])
pre_mul_[c] = dsum[c + 4] / dsum[c]; pre_mul_[c] = dsum[c + 4] / dsum[c];