diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 8f3ebae9f..e20bc04e7 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -20,38 +20,27 @@ #include #include -#include "curves.h" -#include "labimage.h" -#include "color.h" -#include "mytime.h" #include "improcfun.h" -#include "rawimagesource.h" #include "array2D.h" #include "rt_math.h" #include "opthelper.h" -#ifdef _OPENMP -#include -#endif -#define CLIPI(a) ((a)>0 ?((a)<32768 ?(a):32768):0) #define RANGEFN(i) ((1000.0f / (i + 1000.0f))) -#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) #define DIRWT(i1,j1,i,j) ( domker[(i1-i)/scale+halfwin][(j1-j)/scale+halfwin] * RANGEFN(fabsf((data_fine[i1][j1]-data_fine[i][j]))) ) namespace rtengine { -static const int maxlevel = 6; -static const float noise = 2000; +constexpr int maxlevel = 6; +constexpr float noise = 2000; //sequence of scales -static const int scales[6] = {1, 2, 4, 8, 16, 32}; +constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; extern const Settings* settings; //sequence of scales - -SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, float ** dest_a, float ** dest_b, const double * mult, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scaleprev) +SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) { int lastlevel = maxlevel; @@ -94,10 +83,10 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, } int level; - float multi[6] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[6]; + float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; + float scalefl[maxlevel]; - for(int lv = 0; lv < 6; lv++) { + for(int lv = 0; lv < maxlevel; lv++) { scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; if(lv >= 1) { @@ -226,12 +215,12 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, float ** buffer = dirpyrlo[lastlevel - 1]; for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice ); + idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); } scale = scales[0]; - idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice ); + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); if(skinprot != 0.f) { for (int i = 0; i < srcheight; i++) { @@ -247,7 +236,6 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, delete [] tmpHue; } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #pragma omp parallel for for (int i = 0; i < srcheight; i++) @@ -259,7 +247,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, -void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scaleprev) +void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scaleprev) { int lastlevel = maxlevel; @@ -303,10 +291,10 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float int level; - float multi[6] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[6]; + float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; + float scalefl[maxlevel]; - for(int lv = 0; lv < 6; lv++) { + for(int lv = 0; lv < maxlevel; lv++) { scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; // if(scalefl[lv] < 1.f) multi[lv] = 1.f; else multi[lv]=(float) mult[lv]; @@ -371,7 +359,6 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float idirpyr_eq_channelcam(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if(execdir) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -385,20 +372,17 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float dst[i][j] = src[i][j]; } } - } else + } else { for (int i = 0; i < srcheight; i++) for (int j = 0; j < srcwidth; j++) { dst[i][j] = CLIP( buffer[i][j] ); // TODO: Really a clip necessary? } - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + } } - SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, int width, int height, int level, int scale) { - //scale is spacing of directional averaging weights - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // scale is spacing of directional averaging weights // calculate weights, compute directionally weighted average if(level > 1) { @@ -620,9 +604,7 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da } } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[6], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r , int choice) +void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); @@ -635,7 +617,7 @@ void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fin offs = -1.f; } - float multbis[6]; + float multbis[maxlevel]; multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult @@ -714,7 +696,7 @@ void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fin } -void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r) +void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; @@ -728,7 +710,7 @@ void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_ offs = -1.f; } - float multbis[6]; + float multbis[maxlevel]; multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 3b5bd3275..efdef778a 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -1310,10 +1310,8 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int pW, int pwb, L if (rtt == 1) { float b_l = static_cast (params->dirpyrequalizer.hueskin.value[0]) / 100.0f; float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; - float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; - int choice = 0; //not disabled in case of ! always 0 - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); //contrast by detail adapted to CIECAM + dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM } } @@ -2757,11 +2755,9 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw if (rtt == 1) { float b_l = static_cast (params->dirpyrequalizer.hueskin.value[0]) / 100.0f; float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; - float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; - int choice = 0; // I have not suppress this statement in case of !! always to 0 lab->deleteLab(); - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); //contrast by detail adapted to CIECAM + dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM lab->reallocLab(); } @@ -6506,7 +6502,6 @@ void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; - int choice = 0; //I have not disabled this statement in case of ! always 0 // if (params->dirpyrequalizer.algo=="FI") choice=0; // else if(params->dirpyrequalizer.algo=="LA") choice=1; float artifact = (float) settings->artifact_cbdl; @@ -6526,7 +6521,7 @@ void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) } //dirpyrLab_equalizer(lab, lab, params->dirpyrequalizer.mult); - dirpyr_equalizer (lab->L, lab->L, lab->W, lab->H, lab->a, lab->b, lab->a, lab->b, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); + dirpyr_equalizer (lab->L, lab->L, lab->W, lab->H, lab->a, lab->b, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, b_l, t_l, t_r, scale); } } void ImProcFunctions::EPDToneMapCIE (CieImage *ncie, float a_w, float c_, int Wid, int Hei, float minQ, float maxQ, unsigned int Iterates, int skip) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 1065c5833..d6bbdff32 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -332,10 +332,10 @@ public: float MadRgb (float * DataList, const int datalen); // pyramid wavelet - void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, float ** dest_a, float ** dest_b, const double * mult, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid wavelet - void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid wavelet + void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale);//Emil's directional pyramid wavelet + void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scale);//Emil's directional pyramid wavelet void dirpyr_channel (float ** data_fine, float ** data_coarse, int width, int height, int level, int scale); - void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice); + void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); void idirpyr_eq_channelcam (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); void defringe (LabImage* lab); void defringecam (CieImage* ncie);