From edeae689a6011a4fb5ca6c19dba89c7d9ec04b66 Mon Sep 17 00:00:00 2001 From: jdc Date: Sun, 10 Mar 2013 09:39:26 +0100 Subject: [PATCH] Igv and LMMSE demosaicing for noisy images see issue1741 --- rtdata/languages/Francais | 3 + rtdata/languages/default | 3 + rtdata/profiles/Default ISO High.pp3 | 4 +- rtdata/profiles/Default ISO Medium.pp3 | 2 +- rtengine/CMakeLists.txt | 7 +- rtengine/amaze_demosaic_RT.cc | 4 +- rtengine/color.h | 4 +- rtengine/demosaic_algos.cc | 910 +++++++++++++++++++++---- rtengine/expo_before_b.cc | 16 +- rtengine/fast_demo.cc | 36 +- rtengine/green_equil_RT.cc | 4 + rtengine/hilite_recon.cc | 5 +- rtengine/procparams.cc | 3 +- rtengine/procparams.h | 5 +- rtengine/rawimagesource.cc | 20 +- rtengine/rawimagesource.h | 9 +- rtgui/multilangmgr.h | 15 +- rtgui/rawprocess.cc | 4 +- 18 files changed, 894 insertions(+), 160 deletions(-) diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index a9d8d0599..a7960633d 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -1190,6 +1190,9 @@ TP_RAW_ALLENHANCE;Réduction de bruit/artefact post-dématriçage TP_RAW_DCBENHANCE;Appliquer la phase d'amélioration de DCB TP_RAW_DCBITERATIONS;Nombre d'itération de DCB TP_RAW_DMETHOD;Méthode +TP_RAW_DMETHOD_PROGRESSBAR;Dématriçage %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Affinage du dématriçage... +TP_RAW_DMETHOD_TOOLTIP;Note: IGV et LMMSE sont dédiés aux images à haut ISO TP_RAW_FALSECOLOR;Itérations pour la suppression\ndes fausses couleurs TP_RAW_LABEL;Dématriçage TP_RESIZE_APPLIESTO;S'applique à: diff --git a/rtdata/languages/default b/rtdata/languages/default index 1dd177f04..7adf44d50 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1175,6 +1175,9 @@ TP_RAW_ALLENHANCE;Post-Demosaic Artifact/Noise Reduction TP_RAW_DCBENHANCE;DCB Enhancement Step TP_RAW_DCBITERATIONS;Number of DCB Iterations TP_RAW_DMETHOD;Method +TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images TP_RAW_FALSECOLOR;False Color Suppression Steps TP_RAW_LABEL;Demosaicing TP_RESIZE_APPLIESTO;Applies to: diff --git a/rtdata/profiles/Default ISO High.pp3 b/rtdata/profiles/Default ISO High.pp3 index 268af5af5..74ba6d833 100644 --- a/rtdata/profiles/Default ISO High.pp3 +++ b/rtdata/profiles/Default ISO High.pp3 @@ -111,7 +111,7 @@ Curve2=0; Curve3=0; [Impulse Denoising] -Enabled=false +Enabled=true Threshold=80 [Defringing] @@ -251,7 +251,7 @@ HotDeadPixelThresh=40 LineDenoise=0 GreenEqThreshold=0 CcSteps=0 -Method=amaze +Method=igv DCBIterations=2 DCBEnhance=false ALLEnhance=false diff --git a/rtdata/profiles/Default ISO Medium.pp3 b/rtdata/profiles/Default ISO Medium.pp3 index e3c7d942a..3a84b1cbb 100644 --- a/rtdata/profiles/Default ISO Medium.pp3 +++ b/rtdata/profiles/Default ISO Medium.pp3 @@ -111,7 +111,7 @@ Curve2=0; Curve3=0; [Impulse Denoising] -Enabled=false +Enabled=true Threshold=50 [Defringing] diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 45b30dab4..dfac79d92 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -8,12 +8,13 @@ link_directories ("${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} ${GTHREAD_LIBRA set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc flatcurves.cc diagonalcurves.cc dcraw.cc iccstore.cc color.cc dfmanager.cc ffmanager.cc rawimage.cc image8.cc image16.cc imagefloat.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc + fast_demo.cc amaze_demosaic_RT.cc CA_correct_RT.cc cfa_linedn_RT.cc green_equil_RT.cc hilite_recon.cc expo_before_b.cc stdimagesource.cc myfile.cc iccjpeg.cc hlmultipliers.cc improccoordinator.cc processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc cieimage.cc iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc ipvibrance.cc - imagedimensions.cc jpeg_memsrc.cc jdatasrc.cc iimage.cc - EdgePreserveLab.cc EdgePreservingDecomposition.cc cplx_wavelet_dec.cc FTblockDN.cc - PF_correct_RT.cc + imagedimensions.cc jpeg_memsrc.cc jdatasrc.cc iimage.cc + EdgePreserveLab.cc EdgePreservingDecomposition.cc cplx_wavelet_dec.cc FTblockDN.cc + PF_correct_RT.cc dirpyr_equalizer.cc calc_distort.cc lcp.cc dcp.cc klt/convolve.cc klt/error.cc klt/klt.cc klt/klt_util.cc klt/pnmio.cc klt/pyramid.cc klt/selectGoodFeatures.cc diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index 8f022b4f7..3806e2164 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -27,6 +27,8 @@ #include "rtengine.h" #include "rawimagesource.h" #include "rt_math.h" +#include "../rtgui/multilangmgr.h" +#include "procparams.h" using namespace rtengine; @@ -74,7 +76,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) { // Issue 1676 // Moved from inside the parallel section if (plistener) { - plistener->setProgressStr ("AMaZE Demosaicing..."); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::amaze])); plistener->setProgress (0.0); } diff --git a/rtengine/color.h b/rtengine/color.h index 48d764ed0..6301ae09e 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -136,10 +136,10 @@ public: // standard srgb gamma and its inverse static inline double gamma2 (double x) { - return x <= 0.00304 ? x*12.92 : 1.055*exp(log(x)/sRGBGammaCurve)-0.055; + return x <= 0.003041 ? x*12.92 : 1.055011*exp(log(x)/sRGBGammaCurve)-0.055011; } static inline double igamma2 (double x) { - return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*sRGBGammaCurve); + return x <= 0.039293 ? x/12.92 : exp(log((x+0.055011)/1.055011)*sRGBGammaCurve); } /* static inline double gamma709 (double x) { return x <= 0.0176 ? x*4.5 : 1.0954*exp(log(x)/2.2)-0.0954; diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 1cdbeea5c..e2929abd1 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -31,6 +31,9 @@ #include "dfmanager.h" #include "slicer.h" #include "rt_math.h" +#include "color.h" +#include "../rtgui/multilangmgr.h" +#include "procparams.h" #ifdef _OPENMP #include @@ -52,7 +55,7 @@ extern const Settings* settings; void RawImageSource::eahd_demosaic () { if (plistener) { - plistener->setProgressStr ("Demosaicing..."); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::eahd])); plistener->setProgress (0.0); } @@ -70,7 +73,7 @@ void RawImageSource::eahd_demosaic () { lc21 = (0.019334 * imatrices.rgb_cam[1][0] + 0.119193 * imatrices.rgb_cam[1][1] + 0.950227 * imatrices.rgb_cam[1][2]) ;// / 1.088754; lc22 = (0.019334 * imatrices.rgb_cam[2][0] + 0.119193 * imatrices.rgb_cam[2][1] + 0.950227 * imatrices.rgb_cam[2][2]) ;// / 1.088754; - int maxindex = 2*65536; + int maxindex = 3*65536;//2*65536 3 = avoid crash 3/2013 J.Desmis cache = new double[maxindex]; threshold = (int)(0.008856*MAXVALD); for (int i=0; iISGREEN(i,j)) @@ -486,7 +491,7 @@ void RawImageSource::hphd_green (float** hpmap) { void RawImageSource::hphd_demosaic () { if (plistener) { - plistener->setProgressStr ("Demosaicing..."); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::hphd])); plistener->setProgress (0.0); } @@ -583,7 +588,7 @@ void RawImageSource::vng4_demosaic () { }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; if (plistener) { - plistener->setProgressStr ("Demosaicing..."); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::vng4])); plistener->setProgress (0.0); } @@ -762,7 +767,9 @@ void RawImageSource::ppg_demosaic() float (*image)[4]; if (plistener) { - plistener->setProgressStr ("Demosaicing..."); + // looks like ppg isn't supported anymore + //plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::ppg])); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "xxx")); plistener->setProgress (0.0); } @@ -838,31 +845,680 @@ void RawImageSource::ppg_demosaic() free (image); } -void RawImageSource::border_interpolate(int border, float (*image)[4], int start, int end) +void RawImageSource::border_interpolate(unsigned int border, float (*image)[4], unsigned int start, unsigned int end) { - unsigned row, col, y, x, f, c, sum[8]; - unsigned int width=W, height=H; - unsigned int colors = 3; + unsigned row, col, y, x, f, c, sum[8]; + unsigned int width=W, height=H; + unsigned int colors = 3; - if (end == 0 )end = H; - for (row=start; row < end; row++) - for (col=0; col < width; col++) { - if (col==border && row >= border && row < height-border) - col = width-border; - memset (sum, 0, sizeof sum); - for (y=row-1; y != row+2; y++) - for (x=col-1; x != col+2; x++) - if (y < height && x < width) { - f = fc(y,x); - sum[f] += image[y*width+x][f]; - sum[f+4]++; - } - f = fc(row,col); - FORCC if (c != f && sum[c+4]) - image[row*width+col][c] = sum[c] / sum[c+4]; - } + if (end == 0 )end = H; + for (row=start; row < end; row++) + for (col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fc(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fc(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } } +void RawImageSource::border_interpolate2(unsigned int border, float (*image)[3], unsigned int start, unsigned int end) +{ + unsigned row, col, y, x, f, c, sum[8]; + unsigned int width=W, height=H; + unsigned int colors=3; + + if (end == 0 ) end=H; + for (row=start; row < end; row++) + for (col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fc(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fc(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +// Joint Demosaicing and Denoising using High Order Interpolation Techniques +// Revision 0.9.1a - 09/02/2010 - Contact info: luis.sanz.rodriguez@gmail.com +// Copyright Luis Sanz Rodriguez 2010 +// Adapted to RT by Jacques Desmis 3/2013 + +void RawImageSource::jdl_interpolate_omp() // from "Lassus" +{ + int width=W, height=H; + int row,col,c,d,i,u=width,v=2*u,w=3*u,x=4*u,y=5*u,z=6*u,indx,(*dif)[2],(*chr)[2]; + float f[4],g[4]; + float (*image)[4]; + image = (float (*)[4]) calloc (width*height, sizeof *image); + dif = (int (*)[2]) calloc(width*height, sizeof *dif); + chr = (int (*)[2]) calloc(width*height, sizeof *chr); + if (plistener) { + // this function seems to be unused + //plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::jdl])); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "xxx")); + plistener->setProgress (0.0); + } + +#ifdef _OPENMP +#pragma omp parallel default(none) shared(image,width,height,u,w,v,y,x,z,dif,chr) private(row,col,f,g,indx,c,d,i) +#endif +{ +#ifdef _OPENMP +#pragma omp for +#endif + for (int ii=0; ii(0.725f*dif[indx][0]+0.1375f*dif[indx-v][0]+0.1375f*dif[indx+v][0],dif[indx-v][0],dif[indx+v][0]); + g[1]=ULIM(0.725f*dif[indx][1]+0.1375f*dif[indx-2][1]+0.1375f*dif[indx+2][1],dif[indx-2][1],dif[indx+2][1]); + chr[indx][c]=(f[1]*g[0]+f[0]*g[1])/(f[0]+f[1]); + } +#ifdef _OPENMP +#pragma omp for +#endif + for (row=6; row(b)) {temp=(a);(a)=(b);(b)=temp;} } +void RawImageSource::lmmse_interpolate_omp(int winw, int winh) +{ + int c, ii; + float h0, h1, h2, h3, h4, hs; + float (*rix)[6]; + float (*qix)[6]; + float (*glut); + + const bool applyGamma=true; + + char *buffer; + const int width=winw, height=winh; + const int ba = 10; + const int rr1 = height + 2*ba; + const int cc1 = width + 2*ba; + const int w1 = cc1; + const int w2 = 2*w1; + const int w3 = 3*w1; + const int w4 = 4*w1; + + h0 = 1.0f; + h1 = exp( -1.0f/8.0f); + h2 = exp( -4.0f/8.0f); + h3 = exp( -9.0f/8.0f); + h4 = exp(-16.0f/8.0f); + hs = h0 + 2.0f*(h1 + h2 + h3 + h4); + h0 /= hs; + h1 /= hs; + h2 /= hs; + h3 /= hs; + h4 /= hs; + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::lmmse])); + plistener->setProgress (0.0); + } + float (*image)[4]; + float maxdata=0.f; + // float epsil=0.00001f; unused + image = (float (*)[4]) calloc (width*height, sizeof *image); + + unsigned int a=0; + for (int ii=0; ii maxdata) maxdata=currData; + } + if(maxdata<65535.f) maxdata=65535.f; + if (applyGamma) + buffer = (char *)malloc(rr1*cc1*6*sizeof(float)+(int)(maxdata+1.f)*sizeof(float)); + else + buffer = (char *)malloc(rr1*cc1*6*sizeof(float)); + + qix = (float (*)[6])buffer; + if (applyGamma) { + glut = (float *)(buffer + rr1*cc1*6*sizeof(float)); + for (ii=0; ii < 65536; ii++) { + float v0 = (float)ii / 65535.0f; + if (v0 <= 0.003041f) + glut[ii] = v0*12.92f; + else + glut[ii] = 1.055011f*(float)powf(v0,1.f/2.4f) - 0.055011f; + } + }// gamma sRGB + + if (plistener) plistener->setProgress (0.1); + +/*#ifdef _OPENMP +#pragma omp parallel firstprivate (image,rix,qix,h0,h1,h2,h3,h4,hs) +#endif*/ +//{ + for (int rrr=0; rrr < rr1; rrr++) + for (int ccc=0, row=rrr-ba; ccc < cc1; ccc++) { + int col = ccc - ba; + rix = qix + rrr*cc1 + ccc; + if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { + if (applyGamma) + rix[0][4] = glut[(int)image[row*width+col][FC(row,col)]]; + else + rix[0][4] = (float)image[row*width+col][FC(row,col)]/65535.0f; + } + else + rix[0][4] = 0.f; + } + + if (plistener) plistener->setProgress (0.2); + + // G-R(B) + for (int rr=2; rr < rr1-2; rr++) { + // G-R(B) at R(B) location + for (int cc=2+(FC(rr,2)&1); cc < cc1-2; cc+=2) { + rix = qix + rr*cc1 + cc; + float v0 = 0.0625f*(rix[-w1-1][4]+rix[-w1+1][4]+rix[w1-1][4]+rix[w1+1][4]) +0.25f*rix[0][4]; + // horizontal + rix[0][0] = -0.25f*(rix[ -2][4] + rix[ 2][4])+ 0.5f*(rix[ -1][4] + rix[0][4] + rix[ 1][4]); + float Y = v0 + 0.5f*rix[0][0]; + if (rix[0][4] > 1.75f*Y) + rix[0][0] = ULIM(rix[0][0],rix[ -1][4],rix[ 1][4]); + else + rix[0][0] = LIM(rix[0][0],0.0f,1.0f); + rix[0][0] -= rix[0][4]; + // vertical + rix[0][1] = -0.25f*(rix[-w2][4] + rix[w2][4])+ 0.5f*(rix[-w1][4] + rix[0][4] + rix[w1][4]); + Y = v0 + 0.5f*rix[0][1]; + if (rix[0][4] > 1.75f*Y) + rix[0][1] = ULIM(rix[0][1],rix[-w1][4],rix[w1][4]); + else + rix[0][1] = LIM(rix[0][1],0.0f,1.0f); + rix[0][1] -= rix[0][4]; + } + // G-R(B) at G location + for (int ccc=2+(FC(rr,3)&1); ccc < cc1-2; ccc+=2) { + rix = qix + rr*cc1 + ccc; + rix[0][0] = 0.25f*(rix[ -2][4] + rix[ 2][4])- 0.5f*(rix[ -1][4] + rix[0][4] + rix[ 1][4]); + rix[0][1] = 0.25f*(rix[-w2][4] + rix[w2][4])- 0.5f*(rix[-w1][4] + rix[0][4] + rix[w1][4]); + rix[0][0] = LIM(rix[0][0],-1.0f,0.0f) + rix[0][4]; + rix[0][1] = LIM(rix[0][1],-1.0f,0.0f) + rix[0][4]; + } + } + + if (plistener) plistener->setProgress (0.25); + + // apply low pass filter on differential colors + for (int rr=4; rr < rr1-4; rr++) + for (int cc=4; cc < cc1-4; cc++) { + rix = qix + rr*cc1 + cc; + rix[0][2] = h0*rix[0][0] + h1*(rix[ -1][0] + rix[ 1][0]) + h2*(rix[ -2][0] + rix[ 2][0]) + h3*(rix[ -3][0] + rix[ 3][0]) + h4*(rix[ -4][0] + rix[ 4][0]); + rix[0][3] = h0*rix[0][1] + h1*(rix[-w1][1] + rix[w1][1]) + h2*(rix[-w2][1] + rix[w2][1]) + h3*(rix[-w3][1] + rix[w3][1]) + h4*(rix[-w4][1] + rix[w4][1]); + } + + if (plistener) plistener->setProgress (0.3); + + // interpolate G-R(B) at R(B) + for (int rr=4; rr < rr1-4; rr++) + for (int cc=4+(FC(rr,4)&1); cc < cc1-4; cc+=2) { + rix = qix + rr*cc1 + cc; + // horizontal + float mu = (rix[-4][2] + rix[-3][2] + rix[-2][2] + rix[-1][2] + rix[0][2]+ rix[ 1][2] + rix[ 2][2] + rix[ 3][2] + rix[ 4][2]) / 9.0f; + float p1 = rix[-4][2] - mu; + float p2 = rix[-3][2] - mu; + float p3 = rix[-2][2] - mu; + float p4 = rix[-1][2] - mu; + float p5 = rix[ 0][2] - mu; + float p6 = rix[ 1][2] - mu; + float p7 = rix[ 2][2] - mu; + float p8 = rix[ 3][2] - mu; + float p9 = rix[ 4][2] - mu; + float vx = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + p1 = rix[-4][0] - rix[-4][2]; + p2 = rix[-3][0] - rix[-3][2]; + p3 = rix[-2][0] - rix[-2][2]; + p4 = rix[-1][0] - rix[-1][2]; + p5 = rix[ 0][0] - rix[ 0][2]; + p6 = rix[ 1][0] - rix[ 1][2]; + p7 = rix[ 2][0] - rix[ 2][2]; + p8 = rix[ 3][0] - rix[ 3][2]; + p9 = rix[ 4][0] - rix[ 4][2]; + float vn = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + float xh = (rix[0][0]*vx + rix[0][2]*vn)/(vx + vn); + float vh = vx*vn/(vx + vn); + // vertical + mu = (rix[-w4][3] + rix[-w3][3] + rix[-w2][3] + rix[-w1][3] + rix[0][3]+rix[ w1][3] + rix[ w2][3] + rix[ w3][3] + rix[ w4][3]) / 9.0f; + p1 = rix[-w4][3] - mu; + p2 = rix[-w3][3] - mu; + p3 = rix[-w2][3] - mu; + p4 = rix[-w1][3] - mu; + p5 = rix[ 0][3] - mu; + p6 = rix[ w1][3] - mu; + p7 = rix[ w2][3] - mu; + p8 = rix[ w3][3] - mu; + p9 = rix[ w4][3] - mu; + vx = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + p1 = rix[-w4][1] - rix[-w4][3]; + p2 = rix[-w3][1] - rix[-w3][3]; + p3 = rix[-w2][1] - rix[-w2][3]; + p4 = rix[-w1][1] - rix[-w1][3]; + p5 = rix[ 0][1] - rix[ 0][3]; + p6 = rix[ w1][1] - rix[ w1][3]; + p7 = rix[ w2][1] - rix[ w2][3]; + p8 = rix[ w3][1] - rix[ w3][3]; + p9 = rix[ w4][1] - rix[ w4][3]; + vn = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; + float xv = (rix[0][1]*vx + rix[0][3]*vn)/(vx + vn); + float vv = vx*vn/(vx + vn); + // interpolated G-R(B) + rix[0][4] = (xh*vv + xv*vh)/(vh + vv); + } + + if (plistener) plistener->setProgress (0.4); + + // copy CFA values + for (int rr=0; rr < rr1; rr++) + for (int cc=0, row=rr-ba; cc < cc1; cc++) { + int col=cc-ba; + rix = qix + rr*cc1 + cc; + int c = FC(rr,cc); + if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { + if (applyGamma) + rix[0][c] = glut[(int)image[row*width+col][c]]; + else + rix[0][c] = (float)image[row*width+col][c]/65535.0f; + } + else + rix[0][c] = 0.f; + if (c != 1) rix[0][1] = rix[0][c] + rix[0][4]; + } + + if (plistener) plistener->setProgress (0.5); + + // bilinear interpolation for R/B + // interpolate R/B at G location + for (int rr=1; rr < rr1-1; rr++) + for (int cc=1+(FC(rr,2)&1), c=FC(rr,cc+1); cc < cc1-1; cc+=2) { + rix = qix + rr*cc1 + cc; + rix[0][c] = rix[0][1] + 0.5f*(rix[ -1][c] - rix[ -1][1] + rix[ 1][c] - rix[ 1][1]); + c = 2 - c; + rix[0][c] = rix[0][1]+ 0.5f*(rix[-w1][c] - rix[-w1][1] + rix[w1][c] - rix[w1][1]); + c = 2 - c; + } + + if (plistener) plistener->setProgress (0.6); + + // interpolate R/B at B/R location + for (int rr=1; rr < rr1-1; rr++) + for (int cc=1+(FC(rr,1)&1), c=2-FC(rr,cc); cc < cc1-1; cc+=2) { + rix = qix + rr*cc1 + cc; + rix[0][c] = rix[0][1]+ 0.25f*(rix[-w1][c] - rix[-w1][1] + rix[ -1][c] - rix[ -1][1]+ rix[ 1][c] - rix[ 1][1] + rix[ w1][c] - rix[ w1][1]); + } + + if (plistener) plistener->setProgress (0.7); + + // median filter/ + for (int pass=1; pass <= 3; pass++) { + for (int c=0; c < 3; c+=2) { + // Compute median(R-G) and median(B-G) + int d = c + 3; + for (int ii=0; ii < rr1*cc1; ii++) qix[ii][d] = qix[ii][c] - qix[ii][1]; + // Apply 3x3 median filter + for (int rr=1; rr < rr1-1; rr++) + for (int cc=1; cc < cc1-1; cc++) { + float temp; + rix = qix + rr*cc1 + cc; + // Assign 3x3 differential color values + float p1 = rix[-w1-1][d]; float p2 = rix[-w1][d]; float p3 = rix[-w1+1][d]; + float p4 = rix[ -1][d]; float p5 = rix[ 0][d]; float p6 = rix[ 1][d]; + float p7 = rix[ w1-1][d]; float p8 = rix[ w1][d]; float p9 = rix[ w1+1][d]; + // Sort for median of 9 values + PIX_SORT(p2,p3); PIX_SORT(p5,p6); PIX_SORT(p8,p9); + PIX_SORT(p1,p2); PIX_SORT(p4,p5); PIX_SORT(p7,p8); + PIX_SORT(p2,p3); PIX_SORT(p5,p6); PIX_SORT(p8,p9); + PIX_SORT(p1,p4); PIX_SORT(p6,p9); PIX_SORT(p5,p8); + PIX_SORT(p4,p7); PIX_SORT(p2,p5); PIX_SORT(p3,p6); + PIX_SORT(p5,p8); PIX_SORT(p5,p3); PIX_SORT(p7,p5); + PIX_SORT(p5,p3); + rix[0][4] = p5; + } + for (int ii=0; ii < rr1*cc1; ii++) qix[ii][d] = qix[ii][4]; + } + // red/blue at GREEN pixel locations + for (int rr=0; rr < rr1; rr++) + for (int cc=(FC(rr,1)&1) /*, c=FC(rr,cc+1)*/; cc < cc1; cc+=2) { + rix = qix + rr*cc1 + cc; + rix[0][0] = rix[0][1] + rix[0][3]; + rix[0][2] = rix[0][1] + rix[0][5]; + } + // red/blue and green at BLUE/RED pixel locations + for (int rr=0; rr < rr1; rr++) + for (int cc=(FC(rr,0)&1), c=2-FC(rr,cc),d=c+3; cc < cc1; cc+=2) { + rix = qix + rr*cc1 + cc; + rix[0][c] = rix[0][1] + rix[0][d]; + rix[0][1] = 0.5f*(rix[0][0] - rix[0][3] + rix[0][2] - rix[0][5]); + } + } + + if (plistener) plistener->setProgress (0.8); + + // copy result back to image matrix + for (int row=0; row < height; row++) + for (int col=0, rr=row+ba; col < width; col++) { + int cc = col+ba; + rix = qix + rr*cc1 + cc; + int c = FC(row,col); + float v0; + + if (applyGamma) { + for (int ii=0; ii < 3; ii++) + if (ii != c) { + v0 = 65535.f*rix[0][ii]; + image[row*width+col][ii]=Color::igammatab_srgb[v0]; + } + } + else + for (int ii=0; ii < 3; ii++) + if (ii != c) + image[row*width+col][ii] = ((65535.0f*rix[0][ii] + 0.5f)); + } + + if (plistener) plistener->setProgress (0.9); + + for (int ii=0; iisetProgress (1.0); + + +//} // End of parallelization + +// Done + free(buffer); + free(image); +} + +/*** +* +* Bayer CFA Demosaicing using Integrated Gaussian Vector on Color Differences +* Revision 1.0 - 2013/02/28 +* +* Copyright (c) 2007-2013 Luis Sanz Rodriguez +* Using High Order Interpolation technique by Jim S, Jimmy Li, and Sharmil Randhawa +* +* Contact info: luis.sanz.rodriguez@gmail.com +* +* This code is distributed under a GNU General Public License, version 3. +* Visit for more information. +* +***/ +// Adapted to RT by Jacques Desmis 3/2013 + +void RawImageSource::igv_interpolate() +{ + static const float eps=1e-5f, epssq=1e-10f; + static const int h1=1, h2=2, h3=3, h4=4, h5=5, h6=6; + const int width=W, height=H; + const int v1=1*width, v2=2*width, v3=3*width, v4=4*width, v5=5*width, v6=6*width; + float (*rgb)[3], *vdif, *hdif, (*chr)[2]; + rgb = (float (*)[3]) calloc(width*height, sizeof *rgb); + vdif = (float (*)) calloc(width*height, sizeof *vdif); + hdif = (float (*)) calloc(width*height, sizeof *hdif); + chr = (float (*)[2]) calloc(width*height, sizeof *chr); + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::igv])); + plistener->setProgress (0.0); + } + +#ifdef _OPENMP +#pragma omp parallel default(none) shared(rgb,vdif,hdif,chr) +#endif +{ + + float ng, eg, wg, sg, nv, ev, wv, sv, nwg, neg, swg, seg, nwv, nev, swv, sev; + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=0; rowsetProgress (0.1); +} + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=5; rowsetProgress (0.25); +} + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; rowsetProgress (0.45); +} + +// free(vdif); free(hdif); + + // The following block has to be executed by only one thread, because of memory access "collision" +#ifdef _OPENMP +#pragma omp single +#endif +{ + for (int row=7; rowsetProgress (0.6); + + for (int row=7; rowsetProgress (0.8); + + //Interpolate borders + border_interpolate2(7, rgb); +} + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=0; row < height; row++) //borders + for (int col=0; col < width; col++) { + if (col==7 && row >= 7 && row < height-7) + col = width-7; + int indxc=row*width+col; + red [row][col] = rgb[indxc][0]; + green[row][col] = rgb[indxc][1]; + blue [row][col] = rgb[indxc][2]; + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.9); +} + +#ifdef _OPENMP +#pragma omp for +#endif + for(int row=7; rowsetProgress (1.0); + + free(chr); free(rgb); + free(vdif); free(hdif); +} + + /* Adaptive Homogeneity-Directed interpolation is based on the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. @@ -878,18 +1534,18 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh) static const int dir[4] = { -1, 1, -TS, TS }; float ldiff[2][4], abdiff[2][4], leps, abeps; float xyz[3], xyz_cam[3][4]; - float (*cbrt); + float (*cbrt); float (*rgb)[TS][TS][3]; float (*lab)[TS][TS][3]; - float (*lix)[3]; + float (*lix)[3]; char (*homo)[TS][TS], *buffer; - double r; + double r; int width=W, height=H; float (*image)[4]; int colors = 3; - const double xyz_rgb[3][3] = { /* XYZ from RGB */ + const double xyz_rgb[3][3] = { /* XYZ from RGB */ { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, { 0.019334, 0.119193, 0.950227 } @@ -898,7 +1554,7 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh) const float d65_white[3] = { 0.950456, 1, 1.088754 }; if (plistener) { - plistener->setProgressStr ("AHD Demosaicing..."); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::ahd])); plistener->setProgress (0.0); } @@ -933,61 +1589,61 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh) for (left=2; left < width-5; left += TS-6) { /* Interpolate green horizontally and vertically: */ for (row = top; row < top+TS && row < height-2; row++) { - col = left + (FC(row,left) & 1); - for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { - pix = image + (row*width+col); - val = 0.25*((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 - - pix[-2][c] - pix[2][c]) ; - rgb[0][row-top][col-left][1] = ULIM(static_cast(val),pix[-1][1],pix[1][1]); - val = 0.25*((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 - - pix[-2*width][c] - pix[2*width][c]) ; - rgb[1][row-top][col-left][1] = ULIM(static_cast(val),pix[-width][1],pix[width][1]); - } + col = left + (FC(row,left) & 1); + for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { + pix = image + (row*width+col); + val = 0.25*((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 + - pix[-2][c] - pix[2][c]) ; + rgb[0][row-top][col-left][1] = ULIM(static_cast(val),pix[-1][1],pix[1][1]); + val = 0.25*((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 + - pix[-2*width][c] - pix[2*width][c]) ; + rgb[1][row-top][col-left][1] = ULIM(static_cast(val),pix[-width][1],pix[width][1]); + } } /* Interpolate red and blue, and convert to CIELab: */ for (d=0; d < 2; d++) - for (row=top+1; row < top+TS-1 && row < height-3; row++) - for (col=left+1; col < left+TS-1 && col < width-3; col++) { - pix = image + (row*width+col); - rix = &rgb[d][row-top][col-left]; - lix = &lab[d][row-top][col-left]; - if ((c = 2 - FC(row,col)) == 1) { - c = FC(row+1,col); - val = pix[0][1] + (0.5*( pix[-1][2-c] + pix[1][2-c] - - rix[-1][1] - rix[1][1] ) ); - rix[0][2-c] = CLIP(val); - val = pix[0][1] + (0.5*( pix[-width][c] + pix[width][c] - - rix[-TS][1] - rix[TS][1] ) ); - } else - val = rix[0][1] + (0.25*( pix[-width-1][c] + pix[-width+1][c] - + pix[+width-1][c] + pix[+width+1][c] - - rix[-TS-1][1] - rix[-TS+1][1] - - rix[+TS-1][1] - rix[+TS+1][1] + 1) ); - rix[0][c] = CLIP(val); - c = FC(row,col); - rix[0][c] = pix[0][c]; - xyz[0] = xyz[1] = xyz[2] = 0.0; - FORCC { - xyz[0] += xyz_cam[0][c] * rix[0][c]; - xyz[1] += xyz_cam[1][c] * rix[0][c]; - xyz[2] += xyz_cam[2][c] * rix[0][c]; - } + for (row=top+1; row < top+TS-1 && row < height-3; row++) + for (col=left+1; col < left+TS-1 && col < width-3; col++) { + pix = image + (row*width+col); + rix = &rgb[d][row-top][col-left]; + lix = &lab[d][row-top][col-left]; + if ((c = 2 - FC(row,col)) == 1) { + c = FC(row+1,col); + val = pix[0][1] + (0.5*( pix[-1][2-c] + pix[1][2-c] + - rix[-1][1] - rix[1][1] ) ); + rix[0][2-c] = CLIP(val); + val = pix[0][1] + (0.5*( pix[-width][c] + pix[width][c] + - rix[-TS][1] - rix[TS][1] ) ); + } else + val = rix[0][1] + (0.25*( pix[-width-1][c] + pix[-width+1][c] + + pix[+width-1][c] + pix[+width+1][c] + - rix[-TS-1][1] - rix[-TS+1][1] + - rix[+TS-1][1] - rix[+TS+1][1] + 1) ); + rix[0][c] = CLIP(val); + c = FC(row,col); + rix[0][c] = pix[0][c]; + xyz[0] = xyz[1] = xyz[2] = 0.0; + FORCC { + xyz[0] += xyz_cam[0][c] * rix[0][c]; + xyz[1] += xyz_cam[1][c] * rix[0][c]; + xyz[2] += xyz_cam[2][c] * rix[0][c]; + } - xyz[0] = CurveFactory::flinterp(cbrt,xyz[0]); - xyz[1] = CurveFactory::flinterp(cbrt,xyz[1]); - xyz[2] = CurveFactory::flinterp(cbrt,xyz[2]); + xyz[0] = CurveFactory::flinterp(cbrt,xyz[0]); + xyz[1] = CurveFactory::flinterp(cbrt,xyz[1]); + xyz[2] = CurveFactory::flinterp(cbrt,xyz[2]); - //xyz[0] = xyz[0] > 0.008856 ? pow(xyz[0]/65535,1/3.0) : 7.787*xyz[0] + 16/116.0; - //xyz[1] = xyz[1] > 0.008856 ? pow(xyz[1]/65535,1/3.0) : 7.787*xyz[1] + 16/116.0; - //xyz[2] = xyz[2] > 0.008856 ? pow(xyz[2]/65535,1/3.0) : 7.787*xyz[2] + 16/116.0; + //xyz[0] = xyz[0] > 0.008856 ? pow(xyz[0]/65535,1/3.0) : 7.787*xyz[0] + 16/116.0; + //xyz[1] = xyz[1] > 0.008856 ? pow(xyz[1]/65535,1/3.0) : 7.787*xyz[1] + 16/116.0; + //xyz[2] = xyz[2] > 0.008856 ? pow(xyz[2]/65535,1/3.0) : 7.787*xyz[2] + 16/116.0; - lix[0][0] = (116 * xyz[1] - 16); - lix[0][1] = 500 * (xyz[0] - xyz[1]); - lix[0][2] = 200 * (xyz[1] - xyz[2]); - } + lix[0][0] = (116 * xyz[1] - 16); + lix[0][1] = 500 * (xyz[0] - xyz[1]); + lix[0][2] = 200 * (xyz[1] - xyz[2]); + } - /* Build homogeneity maps from the CIELab images: */ + /* Build homogeneity maps from the CIELab images: */ memset (homo, 0, 2*TS*TS); for (row=top+2; row < top+TS-2 && row < height-4; row++) { tr = row-top; @@ -1046,7 +1702,7 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh) } free (image); - free (cbrt); + free (cbrt); } #undef TS @@ -1057,21 +1713,22 @@ void RawImageSource::nodemosaic() blue(W,H); for (int i=0; isetProgressStr ("Refinement..."); + plistener->setProgressStr (M("TP_RAW_DMETHOD_PROGRESSBAR_REFINE")); plistener->setProgress ((float)b/PassCount); } // Reinforce interpolated green pixels on RED/BLUE pixel locations +#ifdef _OPENMP #pragma omp for +#endif for (int row=6; rowverbose) printf("Refinement %d usec\n", t2e.etime(t1e)); } -*/ + /* * Redistribution and use in source and binary forms, with or without @@ -1583,7 +2251,7 @@ void RawImageSource::dcb_refinement(float (*image)[4], int x0, int y0) } } -// missing colors are interpolated using high quality algorithm by Luis Sanz Rodr‚àö‚â†guez +// missing colors are interpolated using high quality algorithm by Luis Sanz Rodriguez void RawImageSource::dcb_color_full(float (*image)[4], int x0, int y0, float (*chroma)[2]) { const int u=CACHESIZE, w=3*CACHESIZE; @@ -1643,7 +2311,7 @@ void RawImageSource::dcb_demosaic(int iterations, bool dcb_enhance) { double currentProgress=0.0; if(plistener) { - plistener->setProgressStr ("DCB Demosaicing..."); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::dcb])); plistener->setProgress (currentProgress); } @@ -1670,7 +2338,9 @@ void RawImageSource::dcb_demosaic(int iterations, bool dcb_enhance) float (*chroma)[2] = (float (*)[2]) calloc( CACHESIZE*CACHESIZE, sizeof *chroma); #endif +#ifdef _OPENMP #pragma omp parallel for +#endif for( int iTile=0; iTile < numTiles; iTile++){ int xTile = iTile % wTiles; int yTile = iTile / wTiles; @@ -1739,7 +2409,9 @@ void RawImageSource::dcb_demosaic(int iterations, bool dcb_enhance) plistener->setProgress (currentProgress); } } +#ifdef _OPENMP #pragma omp atomic +#endif tilesDone++; } diff --git a/rtengine/expo_before_b.cc b/rtengine/expo_before_b.cc index 70fe5e7cd..6dfe33665 100644 --- a/rtengine/expo_before_b.cc +++ b/rtengine/expo_before_b.cc @@ -30,6 +30,16 @@ // exposure (linear): 2^(-8..0..8): currently 0.5 +3 // preserve (log) : 0..8 : currently 0.1 1 +#include "rtengine.h" +#include "rawimagesource.h" +#include "mytime.h" +#include "rt_math.h" +#include "../rtgui/options.h" + +namespace rtengine { + +extern const Settings* settings; + void RawImageSource::processRawWhitepoint(float expos, float preser) { MyTime t1e,t2e; t1e.set(); @@ -146,7 +156,9 @@ void RawImageSource::processRawWhitepoint(float expos, float preser) { delete[] luminosity; } t2e.set(); - if( settings->verbose ) + if (settings->verbose) printf("Exposure before %d usec\n", t2e.etime(t1e)); -} \ No newline at end of file +} + +} //namespace diff --git a/rtengine/fast_demo.cc b/rtengine/fast_demo.cc index ee6031863..2b1abe526 100644 --- a/rtengine/fast_demo.cc +++ b/rtengine/fast_demo.cc @@ -24,6 +24,13 @@ #include #include "rawimagesource.h" +#include "../rtgui/multilangmgr.h" +#include "procparams.h" + +/*#ifdef _OPENMP +#include +#endif*/ + using namespace std; using namespace rtengine; @@ -48,7 +55,7 @@ void RawImageSource::fast_demosaic(int winx, int winy, int winw, int winh) { //int winw=W, winh=H; if (plistener) { - plistener->setProgressStr ("Fast demosaicing..."); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::fast])); plistener->setProgress (0.0); } float progress = 0.0; @@ -59,9 +66,13 @@ void RawImageSource::fast_demosaic(int winx, int winy, int winw, int winh) { int clip_pt = 4*65535*initialGain; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef _OPENMP #pragma omp parallel +#endif { +#ifdef _OPENMP #pragma omp for +#endif //first, interpolate borders using bilinear for (int i=0; isetProgress(0.4); - -#pragma omp for +#ifdef _OPENMP +#pragma omp for +#endif for (int i=bord; i< H-bord; i++) { for (int j=bord+(FC(i,2)&1); j < W-bord; j+=2) { @@ -241,9 +255,13 @@ void RawImageSource::fast_demosaic(int winx, int winy, int winw, int winh) { } if(plistener) plistener->setProgress(0.7); +#ifdef _OPENMP #pragma omp barrier - -#pragma omp for +#endif + +#ifdef _OPENMP +#pragma omp for +#endif // interpolate R/B using color differences for (int i=bord; i< H-bord; i++) { @@ -259,8 +277,8 @@ void RawImageSource::fast_demosaic(int winx, int winy, int winw, int winh) { //if(plistener) plistener->setProgress(progress); } if(plistener) plistener->setProgress(0.99); - } + } // End of parallelization #undef bord -}//namespace +} diff --git a/rtengine/green_equil_RT.cc b/rtengine/green_equil_RT.cc index da3255c23..55e88f73c 100644 --- a/rtengine/green_equil_RT.cc +++ b/rtengine/green_equil_RT.cc @@ -29,7 +29,9 @@ #include "rt_math.h" +#include "rawimagesource.h" +namespace rtengine { //void green_equilibrate()//for dcraw implementation void RawImageSource::green_equilibrate(float thresh) @@ -142,4 +144,6 @@ void RawImageSource::green_equilibrate(float thresh) } +} + #undef TS diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 9640675b4..396655d4c 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -37,6 +37,7 @@ #endif #include "rt_math.h" +#include "rawimagesource.h" @@ -45,7 +46,7 @@ //#include "RGBdefringe.cc" -//namespace rtengine { +namespace rtengine { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -698,5 +699,5 @@ void RawImageSource :: HLRecovery_inpaint (float** red, float** green, float** b } */ -//} +} diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e77ea923f..1a1396dbe 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -42,7 +42,8 @@ using namespace std; namespace rtengine { namespace procparams { -const char *RAWParams::methodstring[RAWParams::numMethods]={"eahd", "hphd", "vng4", "dcb", "amaze", "ahd", "fast" }; +const char *RAWParams::methodstring[RAWParams::numMethods]={"amaze","igv","lmmse","eahd", "hphd", "vng4", "dcb", "ahd", "fast" }; + const char *RAWParams::ff_BlurTypestring[RAWParams::numFlatFileBlurTypes]={/*"Parametric",*/ "Area Flatfield", "Vertical Flatfield", "Horizontal Flatfield", "V+H Flatfield"}; std::vector WBParams::wbEntries; diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 29dc503eb..25e250805 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -689,8 +689,11 @@ class HSVEqualizerParams { class RAWParams { public: - enum eMethod{eahd,hphd,vng4,dcb,amaze,ahd,fast, + // enum eMethod{eahd,hphd,vng4,dcb,amaze,ahd,IGV_noise,fast, + // numMethods }; // This MUST be the last enum + enum eMethod{amaze,igv,lmmse,eahd,hphd,vng4,dcb,ahd,fast, numMethods }; // This MUST be the last enum + static const char *methodstring[numMethods]; enum eFlatFileBlurType{/*parametric,*/area_ff,v_ff,h_ff,vh_ff, diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index a661432c1..b77910bfe 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -18,8 +18,8 @@ */ #include #include - -#include "rtengine.h" + +#include "rtengine.h" #include "rawimagesource.h" #include "rawimagesource_i.h" #include "median.h" @@ -35,7 +35,7 @@ #include "../rtgui/options.h" #include "dcp.h" #include "rt_math.h" -#include "improcfun.h" +#include "improcfun.h" #ifdef _OPENMP #include @@ -1102,6 +1102,10 @@ void RawImageSource::demosaic(const RAWParams &raw) dcb_demosaic(raw.dcb_iterations, raw.dcb_enhance); else if (raw.dmethod == RAWParams::methodstring[RAWParams::eahd]) eahd_demosaic (); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::igv]) + igv_interpolate(); + else if (raw.dmethod == RAWParams::methodstring[RAWParams::lmmse]) + lmmse_interpolate_omp(W,H); else if (raw.dmethod == RAWParams::methodstring[RAWParams::fast] ) fast_demosaic (0,0,W,H); //nodemosaic();//for testing @@ -1368,7 +1372,7 @@ void RawImageSource::scaleColors(int winx,int winy,int winw,int winh, const RAWP black_lev[2]=raw.blacktwo;//B black_lev[3]=raw.blackthree;//G2 (only used with a Bayer filter) - for(int i=0; i<4 ;i++) cblacksom[i] = max( c_black[i]+black_lev[i], 0.0f ); // adjust black level + for(int i=0; i<4 ;i++) cblacksom[i] = max( c_black[i]+black_lev[i], 0.0f ); // adjust black level // this seems strange, but it works // scale image colors @@ -2368,7 +2372,7 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) { if (!ri->isBayer()) { int xmin, xmax, ymin, ymax; int xr, xg, xb, yr, yg, yb; - for (size_t i=0; ipack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") +": ")),Gtk::PACK_SHRINK, 4); dmethod = Gtk::manage (new MyComboBoxText ()); - for( size_t i=0; i< procparams::RAWParams::numMethods;i++) + for( size_t i=0; iappend_text(procparams::RAWParams::methodstring[i]); dmethod->set_active(0); + hb1->set_tooltip_markup (M("TP_RAW_DMETHOD_TOOLTIP")); + hb1->pack_end (*dmethod, Gtk::PACK_EXPAND_WIDGET, 4); pack_start( *hb1, Gtk::PACK_SHRINK, 4);