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.
* 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 W = this->get_width();
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) {
memset(dsum, 0, sizeof dsum);
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: ;
if (this->isBayer()) {
// calculate number of pixels per color
dsum[FC(0,0)+4] += (int)(((W+1)/2) * ((H+1)/2));
dsum[FC(0,1)+4] += (int)(((W/2) * ((H+1)/2)));
dsum[FC(1,0)+4] += (int)(((W+1)/2) * (H/2));
dsum[FC(1,1)+4] += (int)((W/2) * (H/2));
#pragma omp parallel private(val,row,col,x,y)
{
double dsumthr[8];
memset(dsumthr, 0, sizeof dsumthr);
int sum[4];
// make local copies of the black and white values to avoid calculations and conversions
int cblackint[4];
int whiteint[4];
for (int c = 0; c < 4; c++) {
cblackint[c] = cblack_[c];
whiteint[c] = this->get_white(c) - 25;
}
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++)
if (dsum[c])
pre_mul_[c] = dsum[c + 4] / dsum[c];