From 906cd4ba3af3de9677e13688d1eb27f713a1a2b7 Mon Sep 17 00:00:00 2001 From: Ingo Date: Wed, 5 Feb 2014 23:09:55 +0100 Subject: [PATCH] Optimization of RawImage::get_colorsCoeff, Issue 2227 --- rtengine/rawimage.cc | 109 +++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 25 deletions(-) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 0a8d17d0e..acc7960d6 100755 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -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];