diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 0d9af1bbe..ddcb11622 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -396,6 +396,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef const float qhighFactor = (nrQuality == QUALITY_HIGH) ? 1.f/(float) settings->nrhigh : 1.0f; const bool useNoiseCCurve = (noiseCCurve && noiseCCurve.getSum() > 5.f ); const bool useNoiseLCurve = (noiseLCurve && noiseLCurve.getSum() >= 7.f ); + const bool autoch = (settings->leveldnautsimpl==1 && (dnparams.Cmethod=="AUT" || dnparams.Cmethod=="PRE")) || (settings->leveldnautsimpl==0 && (dnparams.C2method=="AUTO" || dnparams.C2method=="PREV")); float** lumcalc; float* lumcalcBuffer; @@ -418,6 +419,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // init luma noisevarL const float noiseluma=(float) dnparams.luma; const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? (float) (SQR(((noiseluma+1.0)/125.0)*(10.+ (noiseluma+1.0)/25.0))) : (float) (SQR((noiseluma/125.0)*(1.0+ noiseluma/25.0))); + const bool denoiseLuminance = (noisevarL > 0.00001f); if(useNoiseLCurve || useNoiseCCurve) { int hei=calclum->height; @@ -522,7 +524,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef const float gain = pow (2.0f, float(expcomp)); float noisevar_Ldetail = SQR((float)(SQR(100.-dnparams.Ldetail) + 50.*(100.-dnparams.Ldetail)) * TS * 0.5f); - if(settings->verbose) printf("Denoise Lab=%i\n",settings->denoiselabgamma); @@ -548,20 +549,20 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef array2D tilemask_in(TS,TS); array2D tilemask_out(TS,TS); + if(denoiseLuminance) { + const int border = MAX(2,TS/16); + for (int i=0; iTS/2 ? i-TS+1 : i)); + float vmask = (i1TS/2 ? j-TS+1 : j)); + tilemask_in[i][j] = (vmask * (j1TS/2 ? i-TS+1 : i)); - float vmask = (i1TS/2 ? j-TS+1 : j)); - tilemask_in[i][j] = (vmask * (j1leveldnti ==0) { @@ -609,27 +610,27 @@ do { int min_numblox_W = ceil(((float)((MIN(imwidth,((numtiles_W - 1) * tileWskip) + tilewidth) ) - ((numtiles_W - 1) * tileWskip)))/(offset))+2*blkrad; // these are needed only for creation of the plans and will be freed before entering the parallel loop - float * Lbloxtmp; - float * fLbloxtmp; - Lbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); - fLbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); - - int nfwd[2]={TS,TS}; - - //for DCT: - const fftw_r2r_kind fwdkind[2] = {FFTW_REDFT10, FFTW_REDFT10}; - const fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01}; - fftwf_plan plan_forward_blox[2]; fftwf_plan plan_backward_blox[2]; + + if(denoiseLuminance) { + float *Lbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); + float *fLbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); - // Creating the plans with FFTW_MEASURE instead of FFTW_ESTIMATE speeds up the execute a bit - plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - fftwf_free ( Lbloxtmp ); - fftwf_free ( fLbloxtmp ); + int nfwd[2]={TS,TS}; + + //for DCT: + fftw_r2r_kind fwdkind[2] = {FFTW_REDFT10, FFTW_REDFT10}; + fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01}; + + // Creating the plans with FFTW_MEASURE instead of FFTW_ESTIMATE speeds up the execute a bit + plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + fftwf_free ( Lbloxtmp ); + fftwf_free ( fLbloxtmp ); + } #ifndef _OPENMP int numthreads = 1; @@ -653,7 +654,7 @@ do { float *LbloxArray[denoiseNestedLevels*numthreads]; float *fLbloxArray[denoiseNestedLevels*numthreads]; - if(numtiles > 1) + if(numtiles > 1 && denoiseLuminance) for(int i=0;iW * labdn->H; - //now perform basic wavelet denoise - //last two arguments of wavelet decomposition are max number of wavelet decomposition levels; + //arguments 4 and 5 of wavelet decomposition are max number of wavelet decomposition levels; //and whether to subsample the image after wavelet filtering. Subsampling is coded as - //binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample + //binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample //the first level only, 7 means subsample the first three levels, etc. - float interm_medT = (float) dnparams.chroma/10.0; + //actual implementation only works with subsampling set to 1 + float interm_medT = (float) dnparams.chroma/10.0; bool execwavelet = true; - bool autoch = false; - if(noisevarL < 0.000007f && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed=="Lab" || dnparams.methodmed=="Lonly")) + if(!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed=="Lab" || dnparams.methodmed=="Lonly")) execwavelet=false;//do not exec wavelet if sliders luminance and chroma are very small and median need - //we considered user don't want wavelet + //we considered user don't want wavelet if(settings->leveldnautsimpl==1 && dnparams.Cmethod!="MAN") execwavelet=true; if(settings->leveldnautsimpl==0 && dnparams.C2method!="MANU") - execwavelet=true; - if(settings->leveldnautsimpl==1 && (dnparams.Cmethod=="AUT" || dnparams.Cmethod=="PRE")) - autoch=true; - if(settings->leveldnautsimpl==0 && (dnparams.C2method=="AUTO" || dnparams.C2method=="PREV")) - autoch=true; - - + execwavelet=true; if(execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 wavelet_decomposition* Ldecomp; wavelet_decomposition* adecomp; @@ -914,12 +907,13 @@ do { if(levwav>8) levwav=8; // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b ); - Ldecomp = new wavelet_decomposition (labdn->data, labdn->W, labdn->H, levwav/*maxlevels*/, 1/*subsampling*/, 1, max(1,denoiseNestedLevels)); + Ldecomp = new wavelet_decomposition (labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels)); if(Ldecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } float madL[8][3]; - if(!memoryAllocationFailed) { + if(!memoryAllocationFailed) { + // precalculate madL, because it's used in adecomp and bdecomp int maxlvl = Ldecomp->maxlevel(); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) @@ -946,19 +940,19 @@ do { float chmaxresid = 0.f; float chmaxresidtemp = 0.f; - adecomp = new wavelet_decomposition (labdn->data+datalen, labdn->W, labdn->H,levwav, 1, 1, max(1,denoiseNestedLevels)); + adecomp = new wavelet_decomposition (labdn->a[0], labdn->W, labdn->H,levwav, 1, 1, max(1,denoiseNestedLevels)); if(adecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } if(!memoryAllocationFailed) { if(nrQuality==QUALITY_STANDARD) { - if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, width, height, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode memoryAllocationFailed = true; } else /*if(nrQuality==QUALITY_HIGH)*/ { - if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, width, height, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode memoryAllocationFailed = true; if(!memoryAllocationFailed) - if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, width, height, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) + if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) memoryAllocationFailed = true; } } @@ -968,23 +962,23 @@ do { chresidtemp=chresid; chmaxresidtemp= chmaxresid; } - adecomp->reconstruct(labdn->data+datalen); + adecomp->reconstruct(labdn->a[0]); } delete adecomp; if(!memoryAllocationFailed) { - wavelet_decomposition* bdecomp = new wavelet_decomposition (labdn->data+2*datalen, labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels)); + wavelet_decomposition* bdecomp = new wavelet_decomposition (labdn->b[0], labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels)); if(bdecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } if(!memoryAllocationFailed) { if(nrQuality==QUALITY_STANDARD) { - if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, width, height, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode memoryAllocationFailed = true; } else /*if(nrQuality==QUALITY_HIGH)*/ { - if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, width, height, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode memoryAllocationFailed = true; if(!memoryAllocationFailed) - if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, width, height, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) + if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) memoryAllocationFailed = true; } } @@ -997,30 +991,33 @@ do { highresi = chresid + 0.66f*(sqrt(chmaxresid) - chresid);//evaluate sigma nresi = chresid; } - bdecomp->reconstruct(labdn->data+2*datalen); + bdecomp->reconstruct(labdn->b[0]); } delete bdecomp; if(!memoryAllocationFailed) { - if(nrQuality==QUALITY_STANDARD) { - if(!WaveletDenoiseAllL(*Ldecomp, noisevarL, noisevarlum, madL, width, height, useNoiseLCurve, denoiseMethodRgb ))//enhance mode - memoryAllocationFailed = true; - } else /*if(nrQuality==QUALITY_HIGH)*/ { - if(!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarL, noisevarlum, madL, width, height, useNoiseLCurve, denoiseMethodRgb ))//enhance mode - memoryAllocationFailed = true; - if(!memoryAllocationFailed) - if(!WaveletDenoiseAllL(*Ldecomp, noisevarL, noisevarlum, madL, width, height, useNoiseLCurve, denoiseMethodRgb )) + if(denoiseLuminance) { + if(nrQuality==QUALITY_STANDARD) { + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL))//enhance mode memoryAllocationFailed = true; - } - if(!memoryAllocationFailed) { - // copy labdn->L to Lin before it gets modified by reconstruction - Lin = new array2D(width,height); + } else /*if(nrQuality==QUALITY_HIGH)*/ { + if(!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL))//enhance mode + memoryAllocationFailed = true; + if(!memoryAllocationFailed) + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL)) + memoryAllocationFailed = true; + } + if(!memoryAllocationFailed) { + // copy labdn->L to Lin before it gets modified by reconstruction + Lin = new array2D(width,height); #ifdef _OPENMP #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) #endif - for(int i=0;iL[i][j]; - Ldecomp->reconstruct(labdn->data); + for(int i=0;iL[i][j]; + + Ldecomp->reconstruct(labdn->L[0]); + } } } } @@ -1028,9 +1025,7 @@ do { } if(!memoryAllocationFailed) { - //median on Luminance Lab only if( (metchoice==1 || metchoice==2 || metchoice==3 || metchoice==4) && dnparams.median) { - //printf("Lab et Lonly \n"); float** tmL; int wid=labdn->W; int hei=labdn->H; @@ -1105,11 +1100,7 @@ do { const int numblox_W = ceil(((float)(width))/(offset))+2*blkrad; const int numblox_H = ceil(((float)(height))/(offset))+2*blkrad; - //residual between input and denoised L channel - array2D Ldetail(width,height,ARRAY2D_CLEAR_DATA); - //pixel weight - array2D totwt(width,height,ARRAY2D_CLEAR_DATA);//weight for combining DCT blocks // end of tiling calc @@ -1118,128 +1109,132 @@ do { // Main detail recovery algorithm: Block loop //DCT block data storage - if(numtiles == 1) - for(int i=0;i Ldetail(width,height,ARRAY2D_CLEAR_DATA); + //pixel weight + array2D totwt(width,height,ARRAY2D_CLEAR_DATA);//weight for combining DCT blocks + if(numtiles == 1) + for(int i=0;i1) #endif { #ifdef _OPENMP - int subThread = masterThread * denoiseNestedLevels + omp_get_thread_num(); + int subThread = masterThread * denoiseNestedLevels + omp_get_thread_num(); #else - int subThread = 0; + int subThread = 0; #endif - float blurbuffer[TS*TS] ALIGNED64; - float *Lblox = LbloxArray[subThread]; - float *fLblox = fLbloxArray[subThread]; - float pBuf[width + TS + 2*blkrad*offset] ALIGNED16; - float nbrwt[TS*TS] ALIGNED64; + float blurbuffer[TS*TS] ALIGNED64; + float *Lblox = LbloxArray[subThread]; + float *fLblox = fLbloxArray[subThread]; + float pBuf[width + TS + 2*blkrad*offset] ALIGNED16; + float nbrwt[TS*TS] ALIGNED64; #ifdef _OPENMP #pragma omp for #endif - for (int vblk=0; vblk=height) { - rr = MAX(0,2*height-2-row); - } - - for (int j=0; jW; j++) { - datarow[j] = ((*Lin)[rr][j]-labdn->L[rr][j]); - } - - for (int j=-blkrad*offset; j<0; j++) { - datarow[j] = datarow[MIN(-j,width-1)]; - } - for (int j=width; j=0 && top+i=height) { + rr = MAX(0,2*height-2-row); } - } + for (int j=0; jW; j++) { + datarow[j] = ((*Lin)[rr][j]-labdn->L[rr][j]); + } - }//end of filling block row + for (int j=-blkrad*offset; j<0; j++) { + datarow[j] = datarow[MIN(-j,width-1)]; + } + for (int j=width; j=0 && top+i1) #endif - for (int i=0; iL[i][j] += Ldetail[i][j]/totwt[i][j]; //note that labdn initially stores the denoised hipass data - } - } - + for (int i=0; iL[i][j] += Ldetail[i][j]/totwt[i][j]; //note that labdn initially stores the denoised hipass data + } + } + } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // transform denoised "Lab" to output RGB @@ -1270,7 +1265,7 @@ do { } //convert back to RGB and write to destination array if (isRAW) { - if(!denoiseMethodRgb) {//Lab mode + if(!denoiseMethodRgb) {//Lab mode realred /= 100.f; realblue /= 100.f; @@ -1400,7 +1395,8 @@ do { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% } delete labdn; - delete Lin; + if(denoiseLuminance) + delete Lin; }//end of tile row }//end of tile loop @@ -1410,12 +1406,13 @@ do { } } - - for(int i=0;idata[i] = Color::gammatab_srgb[ dst->data[i] ]; } } - -// destroy the plans -fftwf_destroy_plan( plan_forward_blox[0] ); -fftwf_destroy_plan( plan_backward_blox[0] ); -fftwf_destroy_plan( plan_forward_blox[1] ); -fftwf_destroy_plan( plan_backward_blox[1] ); -fftwf_cleanup(); + + if(denoiseLuminance) { + // destroy the plans + fftwf_destroy_plan( plan_forward_blox[0] ); + fftwf_destroy_plan( plan_backward_blox[0] ); + fftwf_destroy_plan( plan_forward_blox[1] ); + fftwf_destroy_plan( plan_backward_blox[1] ); + fftwf_cleanup(); + } } while(memoryAllocationFailed && numTries < 2 && (options.rgbDenoiseThreadLimit == 0) && !ponder); if(memoryAllocationFailed) printf("tiled denoise failed due to isufficient memory. Output is not denoised!\n"); @@ -1826,33 +1825,32 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, chmaxresid = maxresid; } -SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float noisevar_L, float *noisevarlum, float madL[8][3], int width, int height, const bool useNoiseLCurve, bool denoiseMethodRgb) - { - int maxlvl = WaveletCoeffs_L.maxlevel(); - const float eps = 0.01f; +SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]) { + int maxlvl = WaveletCoeffs_L.maxlevel(); + const float eps = 0.01f; - int maxWL = 0, maxHL = 0; - for (int lvl=0; lvl maxWL) - maxWL = WaveletCoeffs_L.level_W(lvl); - if(WaveletCoeffs_L.level_H(lvl) > maxHL) - maxHL = WaveletCoeffs_L.level_H(lvl); - } - bool memoryAllocationFailed = false; + int maxWL = 0, maxHL = 0; + for (int lvl=0; lvl maxWL) + maxWL = WaveletCoeffs_L.level_W(lvl); + if(WaveletCoeffs_L.level_H(lvl) > maxHL) + maxHL = WaveletCoeffs_L.level_H(lvl); + } + bool memoryAllocationFailed = false; #ifdef _OPENMP #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) #endif { - float *buffer[3]; - buffer[0] = new (std::nothrow) float[maxWL*maxHL+32]; - buffer[1] = new (std::nothrow) float[maxWL*maxHL+64]; - buffer[2] = new (std::nothrow) float[maxWL*maxHL+96]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { - memoryAllocationFailed = true; - } - - if(!memoryAllocationFailed) { - + float *buffer[3]; + buffer[0] = new (std::nothrow) float[maxWL*maxHL+32]; + buffer[1] = new (std::nothrow) float[maxWL*maxHL+64]; + buffer[2] = new (std::nothrow) float[maxWL*maxHL+96]; + if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + memoryAllocationFailed = true; + } + + if(!memoryAllocationFailed) { + #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif @@ -1863,7 +1861,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); if (lvl==maxlvl-1) { - ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevar_L, noisevarlum, width, height, useNoiseLCurve, denoiseMethodRgb, madL[lvl] ); + ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl] ); } else { //simple wavelet shrinkage float * sfave = buffer[0]+32; @@ -1872,73 +1870,71 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit float mad_Lr = madL[lvl][dir-1]; - if (noisevar_L>0.00001f) { - float levelFactor = mad_Lr*5.f/(lvl+1); + float levelFactor = mad_Lr*5.f/(lvl+1); #ifdef __SSE2__ - __m128 mad_Lv; - __m128 ninev = _mm_set1_ps( 9.0f ); - __m128 epsv = _mm_set1_ps(eps); - __m128 mag_Lv; - __m128 levelFactorv = _mm_set1_ps(levelFactor); - int coeffloc_L; - for (coeffloc_L=0; coeffloc_L=0;i--) - if(buffer[i] != NULL) - delete [] buffer[i]; + } + for(int i=2;i>=0;i--) + if(buffer[i] != NULL) + delete [] buffer[i]; } return (!memoryAllocationFailed); - } +} SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, - float *noisevarchrom, float madL[8][3], int width, int height, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb) + float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb) { int maxlvl = WaveletCoeffs_L.maxlevel(); if(autoch && noisevar_ab <=0.001f) noisevar_ab=0.02f; @@ -1997,7 +1993,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); if (lvl==maxlvl-1) { - ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, width, height, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], madab[lvl], true); + ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], madab[lvl], true); } else { //simple wavelet shrinkage @@ -2057,7 +2053,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi } - bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float noisevar_L, float *noisevarlum, float madL[8][3], int width, int height, const bool useNoiseLCurve, bool denoiseMethodRgb)//mod JD + bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3])//mod JD { @@ -2088,7 +2084,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi #endif for (int lvl=0; lvl0.00001f) { - float levelFactor = mad_L * 5.f / (float)(level+1); + float levelFactor = mad_L * 5.f / (float)(level+1); #ifdef __SSE2__ - __m128 magv; - __m128 levelFactorv = _mm_set1_ps(levelFactor); - __m128 mad_Lv; - __m128 ninev = _mm_set1_ps( 9.0f ); - __m128 epsv = _mm_set1_ps( eps ); - int i; - for (i=0; inrhigh : 1.f; for (int dir=1; dir<4; dir++) { float mada, madb; - if(!perf) + if(!denoiseMethodRgb) mada = SQR(Mad(WavCoeffs_a[dir], W_ab*H_ab)); else mada = SQR(MadRgb(WavCoeffs_a[dir], W_ab*H_ab)); @@ -2393,7 +2386,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** maxredaut = sqrt(reduc*maxchred); minredaut = sqrt(reduc*minchred); - if(!perf) + if(!denoiseMethodRgb) madb = SQR(Mad(WavCoeffs_b[dir], W_ab*H_ab)); else madb = SQR(MadRgb(WavCoeffs_b[dir], W_ab*H_ab)); @@ -2419,7 +2412,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut,int schoice, bool autoch, - float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool perf, bool multiThread ){ + float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread ){ int maxlvl = levwav; for (int lvl=0; lvlheight, imwidth=src->width; - bool perf = (dnparams.dmethod == "RGB"); + bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); const float gain = pow (2.0f, float(expcomp)); @@ -2742,7 +2735,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat noisevarlum[i1>>1][j1>>1]= Llum; } } - if (!perf){//lab mode, modification Jacques feb 2013 and july 2014 + if (!denoiseMethodRgb){//lab mode, modification Jacques feb 2013 and july 2014 #ifdef _OPENMP #pragma omp parallel for if(multiThread) @@ -2883,7 +2876,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat } } bool autoch = dnparams.autochroma; - if(comptlevel==0) WaveletDenoiseAll_info(levwav, *adecomp, *bdecomp, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevarab_r, noisevarab_b, labdn, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, schoice, autoch, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc,maxchred, maxchblue, minchred, minchblue, nb,chau ,chred, chblue, perf, multiThread);//enhance mode + if(comptlevel==0) WaveletDenoiseAll_info(levwav, *adecomp, *bdecomp, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevarab_r, noisevarab_b, labdn, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, schoice, autoch, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc,maxchred, maxchblue, minchred, minchblue, nb,chau ,chred, chblue, denoiseMethodRgb, multiThread);//enhance mode comptlevel+=1; float chresid,chmaxredresid,chmaxblueresid; nresi=chresid; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 58454202e..8143ed255 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -311,22 +311,21 @@ class ImProcFunctions { void RGB_denoise_info(Imagefloat * src, Imagefloat * calclum, bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut,float &nresi, float &highresi, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel,float &skinc, float &nsknc, bool multiThread = false); void RGBtile_denoise (float * fLblox, int hblproc, float noisevar_L, float * nbrwt, float * blurbuffer ); //for DCT void RGBoutput_tile_row (float *Lbloxrow, float ** Ldetail, float ** tilemask_out, int height, int width, int top ); - bool WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float noisevar_L, float *noisevarlum, float madL[8][3], int width, int height, const bool useNoiseLCurve, bool denoiseMethodRgb); - bool WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], int width, int height, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool perf); + bool WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); + bool WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); void WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut,float &minredaut, float & minblueaut, int schoice, bool autoch, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel,float &skinc, float &nsknc, float &maxchred, float &maxchblue,float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread); - bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float noisevar_L, float *noisevarlum, float madL[8][3], int width, int height, const bool useNoiseLCurve, bool denoiseMethodRgb); - bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], int width, int height, float noisevar_ab, + bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); + bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); - void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, - float noisevar_L, float *noisevarlum, int width, int height, const bool useNoiseLCurve, bool denoiseMethodRgb, float * madaL); + void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madaL); void ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, - float *noisevarchrom, int width, int height, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = NULL, bool madCalculated = false); + float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = NULL, bool madCalculated = false); void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int level, int W_ab, int H_ab, int skip_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb,LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, bool autoch, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel,float &skinc, float &nsknc, - float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool perf, bool multiThread); + float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread); void Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); void calcautodn_info (float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc); float MadMax(float * HH_Coeffs, int &max, int datalen);