int main() { void ddct8x8s(int isgn, double **a); void ddct16x16s(int isgn, double **a); void putdata2d(int n1, int n2, double **a); double errorcheck2d(int n1, int n2, double scale, double **a); double err; int i; double aarr[NMAX][NMAX], *a[NMAX], barr[NMAX][NMAX], *b[NMAX]; for (i = 0; i < NMAX; i++) a[i] = aarr[i]; for (i = 0; i < NMAX; i++) b[i] = barr[i]; /* check of 8x8 DCT */ putdata2d(8, 8, a); ddct8x8s(-1, a); ddct8x8s(1, a); err = errorcheck2d(8, 8, 1.0, a); printf("ddct8x8s err= %g\n", err); /* check of 16x16 DCT */ putdata2d(16, 16, a); ddct16x16s(-1, a); ddct16x16s(1, a); err = errorcheck2d(16, 16, 1.0, a); printf("ddct16x16s err= %g\n", err); return 0; }
void dctNxN(int n, double **data, int* ip, double* w) { switch(n) { case 2: case 4: ddct2d(n, n, -1, data, NULL, ip, w); break; case 8: ddct8x8s(-1,data); break; case 16: ddct16x16s(-1,data); break; default: error("N (blocksize) wasn't a power of 2 in dctNxN"); //exit(1); break; } }
void CLASS cfa_linedn(float noise) { // local variables //int height=m_OutHeight, width=m_OutWidth; int top, left, row, col; int rr, cc, indx, i, j; int ex, ey; int verbose=1; float eps=1e-10; //tolerance to avoid dividing by zero float gauss[5] = {0.20416368871516755, 0.18017382291138087, 0.1238315368057753, 0.0662822452863612, 0.02763055063889883}; float rolloff[8] = {0, 0.135335, 0.249352, 0.411112, 0.606531, 0.800737, 0.945959, 1}; //gaussian with sigma=3 float window[8] = {0, .25, .75, 1, 1, .75, .25, 0}; //sine squared float noisevar, linehvar, linevvar, coeffsq; float *cfain, *cfablur, *cfadiff,*cfadn; float aarr[8][8], *dctblock[8]; for (i = 0; i < 8; i++) dctblock[i] = aarr[i]; if (verbose) fprintf (stderr,_("Line denoise ...\n")); // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% noisevar=SQR(3*noise*65535); // _noise_ (as a fraction of saturation) is input to the algorithm cfain = (float (*)) calloc (TS*TS, sizeof(float)); cfablur = (float (*)) calloc (TS*TS, sizeof(float)); cfadiff = (float (*)) calloc (TS*TS, sizeof(float)); cfadn = (float (*)) calloc (TS*TS, sizeof(float)); // Main algorithm: Tile loop for (top=0; top < height-16; top += TS-32) for (left=0; left < width-16; left += TS-32) { int bottom = MIN( top+TS,height); int right = MIN(left+TS, width); int numrows = bottom - top; int numcols = right - left; // load CFA data; data should be in linear gamma space, before white balance multipliers are applied for (rr=top; rr < top+numrows; rr++) for (cc=left, indx=(rr-top)*TS; cc < left+numcols; cc++, indx++) { // cfain[indx] = ri->data[rr][cc]; cfain[indx] = image[rr*width+cc][FC(rr,cc)]; } //pad the block to a multiple of 16 on both sides if (numcols < TS) { indx=numcols % 16; for (i=0; i<(16-indx); i++) for (rr=0; rr<numrows; rr++) cfain[(rr)*TS+numcols+i+1]=cfain[(rr)*TS+numcols-i]; numcols += 16-indx; } if (numrows < TS) { indx=numrows % 16; for (i=0; i<(16-indx); i++) for (cc=0; cc<numcols; cc++) cfain[(numrows+i+1)*TS+cc]=cfain[(numrows-i)*TS+cc]; numrows += 16-indx; } //The cleaning algorithm starts here //gaussian blur of CFA data for (rr=8; rr < numrows-8; rr++) for (indx=rr*TS; indx < rr*TS+numcols; indx++) { cfablur[indx]=gauss[0]*cfain[indx]; for (i=1; i<5; i++) { cfablur[indx] += gauss[i]*(cfain[indx-(2*i)*TS]+cfain[indx+(2*i)*TS]); } } for (rr=8; rr < numrows-8; rr++) for (indx=rr*TS+8; indx < rr*TS+numcols-8; indx++) { cfadn[indx] = gauss[0]*cfablur[indx]; for (i=1; i<5; i++) { cfadn[indx] += gauss[i]*(cfablur[indx-2*i]+cfablur[indx+2*i]); } cfadiff[indx]=cfain[indx]-cfadn[indx]; // hipass cfa data } //begin block DCT for (ey=0; ey<2; ey++) // (ex,ey) specify RGGB subarray for (ex=0; ex<2; ex++) for (rr=8+ey; rr < numrows-22; rr+=8) // (rr,cc) shift by 8 to overlap blocks for (cc=8+ex; cc < numcols-22; cc+=8) { //grab an 8x8 block of a given RGGB channel for (i=0; i<8; i++) for (j=0; j<8; j++) { dctblock[i][j]=cfadiff[(rr+2*i)*TS+cc+2*j]; } ddct8x8s(-1, &dctblock); //forward DCT linehvar=linevvar=0; for (i=4; i<8; i++) { linehvar += SQR(dctblock[0][i]); linevvar += SQR(dctblock[i][0]); } //Wiener filter for line denoising; roll off low frequencies if (noisevar>linehvar) { for (i=1; i<8; i++) { coeffsq=SQR(dctblock[0][i]); dctblock[0][i] *= coeffsq/(coeffsq+rolloff[i]*noisevar+eps); } } if (noisevar>linevvar) { for (i=1; i<8; i++) { coeffsq=SQR(dctblock[i][0]); dctblock[i][0] *= coeffsq/(coeffsq+rolloff[i]*noisevar+eps); } } ddct8x8s(1, &dctblock); //inverse DCT //multiply by window fn and add to output (cfadn) for (i=0; i<8; i++) for (j=0; j<8; j++) { cfadn[(rr+2*i)*TS+cc+2*j] += window[i]*window[j]*dctblock[i][j]; } } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // copy smoothed results back to image matrix for (rr=16; rr < numrows-16; rr++) { row = rr + top; for (col=16+left, indx=rr*TS+16; indx < rr*TS+numcols-16; indx++, col++) { image[row*width+col][FC(row,col)] = CLIP((int)(cfadn[indx]+ 0.5)); } } //~ if(plistener) plistener->setProgress(fabs((float)top/height)); } // clean up free(cfain); free(cfablur); free(cfadiff); free(cfadn); }