color propagation: small speedup, also some code formating

This commit is contained in:
Ingo Weyrich
2019-07-09 17:39:53 +02:00
parent fe43bf1bf2
commit c56106beae

View File

@@ -22,9 +22,7 @@
// //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
#ifndef NDEBUG
#include <cassert> #include <cassert>
#endif
#include <cstddef> #include <cstddef>
#include <cmath> #include <cmath>
@@ -118,7 +116,7 @@ void boxblur2(const float* const* src, float** dst, float** temp, int startY, in
} }
} }
void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int box, int samp ) void boxblur_resamp(const float * const *src, float **dst, float ** temp, int H, int W, int box, int samp )
{ {
#ifdef _OPENMP #ifdef _OPENMP
@@ -290,8 +288,6 @@ void boxblur_resamp(float **src, float **dst, float ** temp, int H, int W, int b
} }
} }
} }
} }
} }
@@ -311,8 +307,8 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
plistener->setProgress (progress); plistener->setProgress (progress);
} }
int height = H; const int height = H;
int width = W; const int width = W;
constexpr int range = 2; constexpr int range = 2;
constexpr int pitch = 4; constexpr int pitch = 4;
@@ -360,7 +356,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
} }
} }
float clipFactor = clmax[maxpos] / maxValNew; const float clipFactor = clmax[maxpos] / maxValNew;
if (clipFactor < maxpct) if (clipFactor < maxpct)
@@ -384,10 +380,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
max_f[c] = chmax[c] * maxpct / factor[c]; max_f[c] = chmax[c] * maxpct / factor[c];
} }
float whitept = max(max_f[0], max_f[1], max_f[2]); const float whitept = max(max_f[0], max_f[1], max_f[2]);
float clippt = min(max_f[0], max_f[1], max_f[2]); const float clippt = min(max_f[0], max_f[1], max_f[2]);
float medpt = max_f[0] + max_f[1] + max_f[2] - whitept - clippt; const float medpt = max_f[0] + max_f[1] + max_f[2] - whitept - clippt;
float blendpt = blendthresh * clippt; const float blendpt = blendthresh * clippt;
float medFactor[3]; float medFactor[3];
for (int c = 0; c < ColorCount; c++) { for (int c = 0; c < ColorCount; c++) {
@@ -410,10 +406,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
} }
} }
std::cout << "minx : " << minx << std::endl; if (plistener) {
std::cout << "maxx : " << maxx << std::endl; progress += 0.05;
std::cout << "miny : " << miny << std::endl; plistener->setProgress(progress);
std::cout << "maxy : " << maxy << std::endl; }
constexpr int blurBorder = 256; constexpr int blurBorder = 256;
minx = std::max(0, minx - blurBorder); minx = std::max(0, minx - blurBorder);
@@ -424,10 +420,16 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
const int blurHeight = maxy - miny + 1; const int blurHeight = maxy - miny + 1;
const int bufferWidth = blurWidth + ((16 - (blurWidth % 16)) & 15); const int bufferWidth = blurWidth + ((16 - (blurWidth % 16)) & 15);
std::cout << "minx : " << minx << std::endl;
std::cout << "maxx : " << maxx << std::endl;
std::cout << "miny : " << miny << std::endl;
std::cout << "maxy : " << maxy << std::endl;
std::cout << "blurWidth : " << blurWidth << std::endl; std::cout << "blurWidth : " << blurWidth << std::endl;
std::cout << "bufferWidth : " << bufferWidth << std::endl; std::cout << "bufferWidth : " << bufferWidth << std::endl;
std::cout << "Corrected area reduced by factor: " << (((float)width * height) / (blurWidth * blurHeight)) << std::endl; std::cout << "Corrected area reduced by factor: " << (((float)width * height) / (bufferWidth * blurHeight)) << std::endl;
std::cout << "Peak memory usage reduced from ~" << (30ul * ((size_t)width * (size_t)height)) / (1024*1024) << " Mb to ~" << (30ul * ((size_t)bufferWidth * (size_t)blurHeight)) / (1024*1024) << " Mb" << std::endl;
multi_array2D<float, 3> channelblur(bufferWidth, blurHeight, 0, 48); multi_array2D<float, 3> channelblur(bufferWidth, blurHeight, 0, 48);
array2D<float> temp(bufferWidth, blurHeight); // allocate temporary buffer array2D<float> temp(bufferWidth, blurHeight); // allocate temporary buffer
@@ -436,21 +438,21 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4);
if (plistener) { if (plistener) {
progress += 0.05; progress += 0.07;
plistener->setProgress(progress); plistener->setProgress(progress);
} }
boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4);
if (plistener) { if (plistener) {
progress += 0.05; progress += 0.07;
plistener->setProgress(progress); plistener->setProgress(progress);
} }
boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4);
if (plistener) { if (plistener) {
progress += 0.05; progress += 0.07;
plistener->setProgress(progress); plistener->setProgress(progress);
} }
@@ -476,7 +478,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
multi_array2D<float, 4> hilite_full(bufferWidth, blurHeight, ARRAY2D_CLEAR_DATA, 32); multi_array2D<float, 4> hilite_full(bufferWidth, blurHeight, ARRAY2D_CLEAR_DATA, 32);
if (plistener) { if (plistener) {
progress += 0.10; progress += 0.05;
plistener->setProgress(progress); plistener->setProgress(progress);
} }
@@ -506,7 +508,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
} }
}//end of filling highlight array }//end of filling highlight array
float hipass_ave = 2.f * hipass_sum / (hipass_norm + epsilon); const float hipass_ave = 2.f * hipass_sum / (hipass_norm + epsilon);
if (plistener) { if (plistener) {
progress += 0.05; progress += 0.05;
@@ -521,7 +523,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
temp.free(); // free temporary buffer temp.free(); // free temporary buffer
if (plistener) { if (plistener) {
progress += 0.05; progress += 0.07;
plistener->setProgress(progress); plistener->setProgress(progress);
} }
@@ -923,26 +925,26 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// now reconstruct clipped channels using color ratios // now reconstruct clipped channels using color ratios
StopWatch Stop1("last loop");
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16) #pragma omp parallel for schedule(dynamic,16)
#endif #endif
for (int i = 0; i < blurHeight; i++) { for (int i = 0; i < blurHeight; i++) {
int i1 = min((i - (i % pitch)) / pitch, hfh - 1); const int i1 = min((i - (i % pitch)) / pitch, hfh - 1);
for (int j = 0; j < blurWidth; j++) { for (int j = 0; j < blurWidth; j++) {
float pixel[3] = {red[i + miny][j + minx], green[i + miny][j + minx], blue[i + miny][j + minx]}; const float pixel[3] = {red[i + miny][j + minx], green[i + miny][j + minx], blue[i + miny][j + minx]};
if (pixel[0] < max_f[0] && pixel[1] < max_f[1] && pixel[2] < max_f[2]) { if (pixel[0] < max_f[0] && pixel[1] < max_f[1] && pixel[2] < max_f[2]) {
continue; //pixel not clipped continue; //pixel not clipped
} }
int j1 = min((j - (j % pitch)) / pitch, hfw - 1); const int j1 = min((j - (j % pitch)) / pitch, hfw - 1);
//estimate recovered values using modified HLRecovery_blend algorithm //estimate recovered values using modified HLRecovery_blend algorithm
float rgb[ColorCount], rgb_blend[ColorCount] = {}, cam[2][ColorCount], lab[2][ColorCount], sum[2], chratio; float rgb[ColorCount], rgb_blend[ColorCount] = {}, cam[2][ColorCount], lab[2][ColorCount], sum[2];
// Copy input pixel to rgb so it's easier to access in loops // Copy input pixel to rgb so it's easier to access in loops
rgb[0] = pixel[0]; rgb[0] = pixel[0];
@@ -972,12 +974,10 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
} }
} }
if(sum[0] == 0.f) { // avoid division by zero // avoid division by zero
sum[0] = epsilon; sum[0] = std::max(sum[0], epsilon);
}
chratio = sqrtf(sum[1] / sum[0]);
const float chratio = sqrtf(sum[1] / sum[0]);
// Apply ratio to lightness in lab space // Apply ratio to lightness in lab space
for (int c = 1; c < ColorCount; c++) { for (int c = 1; c < ColorCount; c++) {
@@ -998,19 +998,18 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
} }
// Copy converted pixel back // Copy converted pixel back
float rfrac = max(0.f, min(1.f, medFactor[0] * (pixel[0] - blendpt)));
float gfrac = max(0.f, min(1.f, medFactor[1] * (pixel[1] - blendpt)));
float bfrac = max(0.f, min(1.f, medFactor[2] * (pixel[2] - blendpt)));
if (pixel[0] > blendpt) { if (pixel[0] > blendpt) {
const float rfrac = max(0.f, min(1.f, medFactor[0] * (pixel[0] - blendpt)));
rgb_blend[0] = rfrac * rgb[0] + (1.f - rfrac) * pixel[0]; rgb_blend[0] = rfrac * rgb[0] + (1.f - rfrac) * pixel[0];
} }
if (pixel[1] > blendpt) { if (pixel[1] > blendpt) {
const float gfrac = max(0.f, min(1.f, medFactor[1] * (pixel[1] - blendpt)));
rgb_blend[1] = gfrac * rgb[1] + (1.f - gfrac) * pixel[1]; rgb_blend[1] = gfrac * rgb[1] + (1.f - gfrac) * pixel[1];
} }
if (pixel[2] > blendpt) { if (pixel[2] > blendpt) {
const float bfrac = max(0.f, min(1.f, medFactor[2] * (pixel[2] - blendpt)));
rgb_blend[2] = bfrac * rgb[2] + (1.f - bfrac) * pixel[2]; rgb_blend[2] = bfrac * rgb[2] + (1.f - bfrac) * pixel[2];
} }
@@ -1019,7 +1018,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
//there are clipped highlights //there are clipped highlights
//first, determine weighted average of unclipped extensions (weighting is by 'hue' proximity) //first, determine weighted average of unclipped extensions (weighting is by 'hue' proximity)
float totwt = 0.f; bool totwt = false;
float clipfix[3] = {0.f, 0.f, 0.f}; float clipfix[3] = {0.f, 0.f, 0.f};
float Y = epsilon + rgb_blend[0] + rgb_blend[1] + rgb_blend[2]; float Y = epsilon + rgb_blend[0] + rgb_blend[1] + rgb_blend[2];
@@ -1031,25 +1030,23 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
float Yhi = 1.f / (hilite_dir0[0][j1][i1] + hilite_dir0[1][j1][i1] + hilite_dir0[2][j1][i1]); float Yhi = 1.f / (hilite_dir0[0][j1][i1] + hilite_dir0[1][j1][i1] + hilite_dir0[2][j1][i1]);
if (Yhi < 2.f) { if (Yhi < 2.f) {
float dirwt = 1.f / (1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir0[0][j1][i1] * Yhi) + const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir0[0][j1][i1] * Yhi) +
SQR(rgb_blend[1] - hilite_dir0[1][j1][i1] * Yhi) + SQR(rgb_blend[1] - hilite_dir0[1][j1][i1] * Yhi) +
SQR(rgb_blend[2] - hilite_dir0[2][j1][i1] * Yhi))); SQR(rgb_blend[2] - hilite_dir0[2][j1][i1] * Yhi))) * (hilite_dir0[3][j1][i1] + epsilon));
totwt = dirwt; totwt = true;
dirwt /= (hilite_dir0[3][j1][i1] + epsilon);
clipfix[0] = dirwt * hilite_dir0[0][j1][i1]; clipfix[0] = dirwt * hilite_dir0[0][j1][i1];
clipfix[1] = dirwt * hilite_dir0[1][j1][i1]; clipfix[1] = dirwt * hilite_dir0[1][j1][i1];
clipfix[2] = dirwt * hilite_dir0[2][j1][i1]; clipfix[2] = dirwt * hilite_dir0[2][j1][i1];
} }
for (int dir = 0; dir < 2; dir++) { for (int dir = 0; dir < 2; dir++) {
float Yhi = 1.f / ( hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]); const float Yhi = 1.f / ( hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]);
if (Yhi < 2.f) { if (Yhi < 2.f) {
float dirwt = 1.f / (1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir[dir * 4 + 0][i1][j1] * Yhi) + const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir[dir * 4 + 0][i1][j1] * Yhi) +
SQR(rgb_blend[1] - hilite_dir[dir * 4 + 1][i1][j1] * Yhi) + SQR(rgb_blend[1] - hilite_dir[dir * 4 + 1][i1][j1] * Yhi) +
SQR(rgb_blend[2] - hilite_dir[dir * 4 + 2][i1][j1] * Yhi))); SQR(rgb_blend[2] - hilite_dir[dir * 4 + 2][i1][j1] * Yhi))) * (hilite_dir[dir * 4 + 3][i1][j1] + epsilon));
totwt += dirwt; totwt = true;
dirwt /= (hilite_dir[dir * 4 + 3][i1][j1] + epsilon);
clipfix[0] += dirwt * hilite_dir[dir * 4 + 0][i1][j1]; clipfix[0] += dirwt * hilite_dir[dir * 4 + 0][i1][j1];
clipfix[1] += dirwt * hilite_dir[dir * 4 + 1][i1][j1]; clipfix[1] += dirwt * hilite_dir[dir * 4 + 1][i1][j1];
clipfix[2] += dirwt * hilite_dir[dir * 4 + 2][i1][j1]; clipfix[2] += dirwt * hilite_dir[dir * 4 + 2][i1][j1];
@@ -1060,56 +1057,51 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
Yhi = 1.f / (hilite_dir4[0][j1][i1] + hilite_dir4[1][j1][i1] + hilite_dir4[2][j1][i1]); Yhi = 1.f / (hilite_dir4[0][j1][i1] + hilite_dir4[1][j1][i1] + hilite_dir4[2][j1][i1]);
if (Yhi < 2.f) { if (Yhi < 2.f) {
float dirwt = 1.f / (1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir4[0][j1][i1] * Yhi) + const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir4[0][j1][i1] * Yhi) +
SQR(rgb_blend[1] - hilite_dir4[1][j1][i1] * Yhi) + SQR(rgb_blend[1] - hilite_dir4[1][j1][i1] * Yhi) +
SQR(rgb_blend[2] - hilite_dir4[2][j1][i1] * Yhi))); SQR(rgb_blend[2] - hilite_dir4[2][j1][i1] * Yhi))) * (hilite_dir4[3][j1][i1] + epsilon));
totwt += dirwt; totwt = true;
dirwt /= (hilite_dir4[3][j1][i1] + epsilon);
clipfix[0] += dirwt * hilite_dir4[0][j1][i1]; clipfix[0] += dirwt * hilite_dir4[0][j1][i1];
clipfix[1] += dirwt * hilite_dir4[1][j1][i1]; clipfix[1] += dirwt * hilite_dir4[1][j1][i1];
clipfix[2] += dirwt * hilite_dir4[2][j1][i1]; clipfix[2] += dirwt * hilite_dir4[2][j1][i1];
} }
if(totwt == 0.f) { if (UNLIKELY(!totwt)) {
continue; continue;
} }
clipfix[0] /= totwt;
clipfix[1] /= totwt;
clipfix[2] /= totwt;
//now correct clipped channels //now correct clipped channels
if (pixel[0] > max_f[0] && pixel[1] > max_f[1] && pixel[2] > max_f[2]) { if (pixel[0] > max_f[0] && pixel[1] > max_f[1] && pixel[2] > max_f[2]) {
//all channels clipped //all channels clipped
float Y = (0.299 * clipfix[0] + 0.587 * clipfix[1] + 0.114 * clipfix[2]); const float Y = 0.299f * clipfix[0] + 0.587f * clipfix[1] + 0.114f * clipfix[2];
float factor = whitept / Y; const float factor = whitept / Y;
red[i + miny][j + minx] = clipfix[0] * factor; red[i + miny][j + minx] = clipfix[0] * factor;
green[i + miny][j + minx] = clipfix[1] * factor; green[i + miny][j + minx] = clipfix[1] * factor;
blue[i + miny][j + minx] = clipfix[2] * factor; blue[i + miny][j + minx] = clipfix[2] * factor;
} else {//some channels clipped } else {//some channels clipped
float notclipped[3] = {pixel[0] <= max_f[0] ? 1.f : 0.f, pixel[1] <= max_f[1] ? 1.f : 0.f, pixel[2] <= max_f[2] ? 1.f : 0.f}; const float notclipped[3] = {pixel[0] <= max_f[0] ? 1.f : 0.f, pixel[1] <= max_f[1] ? 1.f : 0.f, pixel[2] <= max_f[2] ? 1.f : 0.f};
if (notclipped[0] == 0.f) { //red clipped if (notclipped[0] == 0.f) { //red clipped
red[i + miny][j + minx] = max(red[i + miny][j + minx], (clipfix[0] * ((notclipped[1] * pixel[1] + notclipped[2] * pixel[2]) / red[i + miny][j + minx] = max(pixel[0], clipfix[0] * ((notclipped[1] * pixel[1] + notclipped[2] * pixel[2]) /
(notclipped[1] * clipfix[1] + notclipped[2] * clipfix[2] + epsilon)))); (notclipped[1] * clipfix[1] + notclipped[2] * clipfix[2] + epsilon)));
} }
if (notclipped[1] == 0.f) { //green clipped if (notclipped[1] == 0.f) { //green clipped
green[i + miny][j + minx] = max(green[i + miny][j + minx], (clipfix[1] * ((notclipped[2] * pixel[2] + notclipped[0] * pixel[0]) / green[i + miny][j + minx] = max(pixel[1], clipfix[1] * ((notclipped[2] * pixel[2] + notclipped[0] * pixel[0]) /
(notclipped[2] * clipfix[2] + notclipped[0] * clipfix[0] + epsilon)))); (notclipped[2] * clipfix[2] + notclipped[0] * clipfix[0] + epsilon)));
} }
if (notclipped[2] == 0.f) { //blue clipped if (notclipped[2] == 0.f) { //blue clipped
blue[i + miny][j + minx] = max(blue[i + miny][j + minx], (clipfix[2] * ((notclipped[0] * pixel[0] + notclipped[1] * pixel[1]) / blue[i + miny][j + minx] = max(pixel[2], clipfix[2] * ((notclipped[0] * pixel[0] + notclipped[1] * pixel[1]) /
(notclipped[0] * clipfix[0] + notclipped[1] * clipfix[1] + epsilon)))); (notclipped[0] * clipfix[0] + notclipped[1] * clipfix[1] + epsilon)));
} }
} }
Y = (0.299 * red[i + miny][j + minx] + 0.587 * green[i + miny][j + minx] + 0.114 * blue[i + miny][j + minx]); Y = 0.299f * red[i + miny][j + minx] + 0.587f * green[i + miny][j + minx] + 0.114f * blue[i + miny][j + minx];
if (Y > whitept) { if (Y > whitept) {
float factor = whitept / Y; const float factor = whitept / Y;
red[i + miny][j + minx] *= factor; red[i + miny][j + minx] *= factor;
green[i + miny][j + minx] *= factor; green[i + miny][j + minx] *= factor;
@@ -1117,6 +1109,7 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b
} }
} }
} }
std::cout << "progress : " << progress << std::endl;
if (plistener) { if (plistener) {
plistener->setProgress(1.00); plistener->setProgress(1.00);