Optimization of RawImage::get_colorsCoeff, Issue 2227
This commit is contained in:
@@ -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];
|
||||
|
Reference in New Issue
Block a user