From 64562bd83f72c688d5c27b5113cc984e52a8ff73 Mon Sep 17 00:00:00 2001 From: Ingo Date: Thu, 6 Mar 2014 22:31:13 +0100 Subject: [PATCH] Reformated code of vng4_demosaic() to prepare patches for Issue 2278 --- rtengine/demosaic_algos.cc | 485 +++++++++++++++++++------------------ 1 file changed, 248 insertions(+), 237 deletions(-) diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 341f2905d..85a09f435 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -570,189 +570,200 @@ void RawImageSource::hphd_demosaic () { (ri->prefilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) typedef unsigned short ushort; void RawImageSource::vng4_demosaic () { - static const signed short int *cp, terms[] = { - -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, - -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, - -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, - -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, - -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, - -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, - -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, - -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, - -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, - -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, - -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, - -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, - -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, - +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, - +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, - +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, - +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, - +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, - +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, - +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, - +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, - +1,+0,+2,+1,0,0x10 - }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; - if (plistener) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::vng4])); - plistener->setProgress (0.0); - } + static const signed short int *cp, terms[] = { + -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, + -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, + -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, + -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, + -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, + -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, + -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, + -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, + -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, + -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, + -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, + -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, + -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, + +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, + +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, + +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, + +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, + +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, + +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, + +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, + +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, + +1,+0,+2,+1,0,0x10 + }, + chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; - float (*brow[5])[4], *pix; - int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; - int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; - int g, diff, thold, num, c, width=W, height=H, colors=4; - float (*image)[4]; - int lcode[16][16][32], shift, i; + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::vng4])); + plistener->setProgress (0.0); + } - image = (float (*)[4]) calloc (H*W, sizeof *image); - for (int ii=0; ii gval[g]) gmin = gval[g]; - if (gmax < gval[g]) gmax = gval[g]; - } - if (gmax == 0) { - memcpy (brow[2][col], pix, sizeof *image); - continue; - } - thold = gmin + (gmax /2); - memset (sum, 0, sizeof sum); - for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ - if (gval[g] <= thold) { - FORCC - if (c == color && ip[1]) - sum[c] += (pix[c] + pix[ip[1]]) /2; - else - sum[c] += pix[ip[0] + c]; - num++; - } - } - FORCC { /* Save to buffer */ - t = pix[color]; - if (c != color) - t += (sum[c] - sum[color]) / num; - brow[2][col][c] = t; - } - } - if (row > 3) /* Write buffer to image */ - memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); - for (g=0; g < 4; g++) - brow[(g-1) & 3] = brow[g]; - if (!(row%20) && plistener) - plistener->setProgress ((double)row / (H-2)); - } - memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); - memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); - free (brow[4]); - free (code[0][0]); + ip = (int *) calloc ((prow+1)*(pcol+1), 1280); + for (row=0; row <= prow; row++) /* Precalculate for VNG */ + for (col=0; col <= pcol; col++) { + code[row][col] = ip; + for (cp=terms, t=0; t < 64; t++) { + y1 = *cp++; x1 = *cp++; + y2 = *cp++; x2 = *cp++; + weight = *cp++; + grads = *cp++; + color = fc(row+y1,col+x1); + if (fc(row+y2,col+x2) != color) + continue; + diag = (fc(row,col+1) == color && fc(row+1,col) == color) ? 2:1; + if (abs(y1-y2) == diag && abs(x1-x2) == diag) + continue; + *ip++ = (y1*width + x1)*4 + color; + *ip++ = (y2*width + x2)*4 + color; + *ip++ = weight; + for (g=0; g < 8; g++) + if (grads & (1< gval[g]) + gmin = gval[g]; + if (gmax < gval[g]) + gmax = gval[g]; + } + if (gmax == 0) { + memcpy (brow[2][col], pix, sizeof *image); + continue; + } + thold = gmin + (gmax /2); + memset (sum, 0, sizeof sum); + for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + FORCC + if (c == color && ip[1]) + sum[c] += (pix[c] + pix[ip[1]]) /2; + else + sum[c] += pix[ip[0] + c]; + num++; + } + } + FORCC { /* Save to buffer */ + t = pix[color]; + if (c != color) + t += (sum[c] - sum[color]) / num; + brow[2][col][c] = t; + } + } + if (row > 3) /* Write buffer to image */ + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + for (g=0; g < 4; g++) + brow[(g-1) & 3] = brow[g]; + if (!(row%20) && plistener) + plistener->setProgress ((double)row / (H-2)); + } + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); + free (brow[4]); + free (code[0][0]); + + for (int i=0; isetProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::lmmse])); plistener->setProgress (0.0); @@ -1168,12 +1179,12 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) float maxdata=0.f; image = (float (*)[3]) calloc (width*height, sizeof *image); unsigned int a=0; -#ifdef _OPENMP -#pragma omp parallel for +#ifdef _OPENMP +#pragma omp parallel for #endif for (int ii=0; ii= 0) & (row < height) & (col >= 0) & (col < width)) { if (applyGamma) - rix[0][4] = Color::gammatab_24_17a[image[row*width+col][FC(row,col)]]; + rix[0][4] = Color::gammatab_24_17a[image[row*width+col][FC(row,col)]]; else rix[0][4] = (float)image[row*width+col][FC(row,col)]/65535.0f; } @@ -1215,8 +1226,8 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) // G-R(B) -#ifdef _OPENMP -#pragma omp for +#ifdef _OPENMP +#pragma omp for #endif for (int rr=2; rr < rr1-2; rr++) { // G-R(B) at R(B) location @@ -1258,8 +1269,8 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) // apply low pass filter on differential colors -#ifdef _OPENMP -#pragma omp for +#ifdef _OPENMP +#pragma omp for #endif for (int rr=4; rr < rr1-4; rr++) for (int cc=4; cc < cc1-4; cc++) { @@ -1276,9 +1287,9 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) // interpolate G-R(B) at R(B) -#ifdef _OPENMP -#pragma omp for -#endif +#ifdef _OPENMP +#pragma omp for +#endif 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; @@ -1342,9 +1353,9 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) // copy CFA values -#ifdef _OPENMP -#pragma omp for -#endif +#ifdef _OPENMP +#pragma omp for +#endif for (int rr=0; rr < rr1; rr++) for (int cc=0, row=rr-ba; cc < cc1; cc++) { int col=cc-ba; @@ -1352,7 +1363,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) int c = FC(rr,cc); if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { if (applyGamma) - rix[0][c] = Color::gammatab_24_17a[image[row*width+col][c]]; + rix[0][c] = Color::gammatab_24_17a[image[row*width+col][c]]; else rix[0][c] = (float)image[row*width+col][c]/65535.0f; } @@ -1370,9 +1381,9 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) // bilinear interpolation for R/B // interpolate R/B at G location -#ifdef _OPENMP -#pragma omp for -#endif +#ifdef _OPENMP +#pragma omp for +#endif 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; @@ -1390,9 +1401,9 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) // interpolate R/B at B/R location -#ifdef _OPENMP +#ifdef _OPENMP #pragma omp for -#endif +#endif 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; @@ -1454,13 +1465,13 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) } if (plistener) plistener->setProgress (0.8); -#ifdef _OPENMP +#ifdef _OPENMP #pragma omp parallel firstprivate (image,rix,qix) #endif { // copy result back to image matrix -#ifdef _OPENMP -#pragma omp for +#ifdef _OPENMP +#pragma omp for #endif for (int row=0; row < height; row++) for (int col=0, rr=row+ba; col < width; col++) { @@ -1500,7 +1511,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) //if(iterations > 4) refinement_lassus(passref); if(iterations > 4 && iterations <=6) refinement(passref); else if(iterations > 6) refinement_lassus(passref); - + } /*** @@ -1524,7 +1535,7 @@ void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int iterations) SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) { static const float eps=1e-5f, epssq=1e-5f;//mod epssq -10f =>-5f Jacques 3/2013 to prevent artifact (divide by zero) - + static const int h1=1, h2=2, h3=3, h5=5; const int width=winw, height=winh; const int v1=1*width, v2=2*width, v3=3*width, v5=5*width; @@ -1541,7 +1552,7 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) chrarray = (float (*)) calloc( width*height, sizeof( float ) ); chr[0] = chrarray; chr[1] = chrarray + (width*height)/2; - + // mapped chr[2] and chr[3] to hdif and hdif, because these are out of use, when chr[2] and chr[3] are used chr[2] = hdif; chr[3] = vdif; @@ -1620,7 +1631,7 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) egv=(epsv+(vabsf(LVFU(rgb[1][(indx+h1)>>1])-LVFU(rgb[1][(indx+h3)>>1]))+vabsf(LVFU(rgb[0][indx1])-LVFU(rgb[0][(indx1+h1)])))/c65535v); wgv=(epsv+(vabsf(LVFU(rgb[1][(indx-h1)>>1])-LVFU(rgb[1][(indx-h3)>>1]))+vabsf(LVFU(rgb[0][indx1])-LVFU(rgb[0][(indx1-h1)])))/c65535v); sgv=(epsv+(vabsf(LVFU(rgb[1][(indx+v1)>>1])-LVFU(rgb[1][(indx+v3)>>1]))+vabsf(LVFU(rgb[0][indx1])-LVFU(rgb[0][(indx1+v1)])))/c65535v); - //N,E,W,S High Order Interpolation (Li & Randhawa) + //N,E,W,S High Order Interpolation (Li & Randhawa) //N,E,W,S Hamilton Adams Interpolation // (48.f * 65535.f) = 3145680.f tempv = c40v*LVFU(rgb[0][indx1]); @@ -1640,7 +1651,7 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) eg=(eps+(fabsf(rgb[1][(indx+h1)>>1]-rgb[1][(indx+h3)>>1])+fabsf(rgb[0][indx1]-rgb[0][(indx1+h1)]))/65535.f); wg=(eps+(fabsf(rgb[1][(indx-h1)>>1]-rgb[1][(indx-h3)>>1])+fabsf(rgb[0][indx1]-rgb[0][(indx1-h1)]))/65535.f); sg=(eps+(fabsf(rgb[1][(indx+v1)>>1]-rgb[1][(indx+v3)>>1])+fabsf(rgb[0][indx1]-rgb[0][(indx1+v1)]))/65535.f); - //N,E,W,S High Order Interpolation (Li & Randhawa) + //N,E,W,S High Order Interpolation (Li & Randhawa) //N,E,W,S Hamilton Adams Interpolation // (48.f * 65535.f) = 3145680.f nv=LIM(((23.0f*rgb[1][(indx-v1)>>1]+23.0f*rgb[1][(indx-v3)>>1]+rgb[1][(indx-v5)>>1]+rgb[1][(indx+v1)>>1]+40.0f*rgb[0][indx1]-32.0f*rgb[0][(indx1-v1)]-8.0f*rgb[0][(indx1-v2)]))/3145680.f, 0.0f, 1.0f); @@ -1808,7 +1819,7 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) float *src1, *src2, *redsrc0, *redsrc1, *bluesrc0, *bluesrc1; #ifdef _OPENMP #pragma omp for -#endif +#endif for(int row=7; rowsetProgress (1.0); + if (plistener) plistener->setProgress (1.0); free(chrarray); free(rgbarray); free(vdif); free(hdif); @@ -1887,12 +1898,12 @@ void RawImageSource::igv_interpolate(int winw, int winh) chrarray = (float (*)) calloc(width*height*2, sizeof( float)); chr[0] = chrarray; chr[1] = chrarray + (width*height); - + vdif = (float (*)) calloc(width*height/2, sizeof *vdif); hdif = (float (*)) calloc(width*height/2, sizeof *hdif); border_interpolate2(winw,winh,7); - + if (plistener) { plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::methodstring[RAWParams::igv])); plistener->setProgress (0.0); @@ -1931,7 +1942,7 @@ void RawImageSource::igv_interpolate(int winw, int winh) eg=(eps+(fabsf(rgb[1][indx+h1]-rgb[1][indx+h3])+fabsf(rgb[c][indx]-rgb[c][indx+h2]))/65535.f); wg=(eps+(fabsf(rgb[1][indx-h1]-rgb[1][indx-h3])+fabsf(rgb[c][indx]-rgb[c][indx-h2]))/65535.f); sg=(eps+(fabsf(rgb[1][indx+v1]-rgb[1][indx+v3])+fabsf(rgb[c][indx]-rgb[c][indx+v2]))/65535.f); - //N,E,W,S High Order Interpolation (Li & Randhawa) + //N,E,W,S High Order Interpolation (Li & Randhawa) //N,E,W,S Hamilton Adams Interpolation // (48.f * 65535.f) = 3145680.f nv=LIM(((23.0f*rgb[1][indx-v1]+23.0f*rgb[1][indx-v3]+rgb[1][indx-v5]+rgb[1][indx+v1]+40.0f*rgb[c][indx]-32.0f*rgb[c][indx-v2]-8.0f*rgb[c][indx-v4]))/3145680.f, 0.0f, 1.0f); @@ -2071,7 +2082,7 @@ void RawImageSource::igv_interpolate(int winw, int winh) /* #ifdef _OPENMP #pragma omp for -#endif +#endif for (int row=0; row < height; row++) //borders for (int col=0; col < width; col++) { if (col==7 && row >= 7 && row < height-7) @@ -2085,7 +2096,7 @@ void RawImageSource::igv_interpolate(int winw, int winh) #ifdef _OPENMP #pragma omp for -#endif +#endif for(int row=7; rowverbose) printf("Refinement Lee %d usec\n", t2e.etime(t1e)); @@ -2423,8 +2434,8 @@ void RawImageSource::refinement(int PassCount) // // Should be DISABLED if it decreases image quality by increases some image noise and generates blocky edges void RawImageSource::refinement_lassus(int PassCount) -{ - // const int PassCount=1; +{ + // const int PassCount=1; // if (settings->verbose) printf("Refinement\n"); @@ -2445,7 +2456,7 @@ void RawImageSource::refinement_lassus(int PassCount) for (int j=0;j