📄 common.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <float.h>#include "pgm.h"#include "common.h"#define IA 16807#define IM 2147483647#define AM (1.0/IM)#define IQ 127773#define IR 2836#define MASK 123459876static int NN = 0;static int m = 0;static double two_over_N = 0;static double root2_over_rootN = 0;static double *C = NULL;static gray maxval;static int format;void open_image(FILE *in, int *width, int *height){ pgm_readpgminit(in, width, height, &maxval, &format);}void load_image(int **im, FILE *in, int width, int height){ int col, row; gray *rowbuf; rowbuf = malloc(sizeof(gray) * width); for (row = 0; row < height; row++) { pgm_readpgmrow(in, rowbuf, width, maxval, format); for (col = 0; col < width; col++) im[row][col] = rowbuf[col]; } free(rowbuf);}void save_image(int **im, FILE *out, int width, int height){ int col, row; gray *rowbuf; pgm_writepgminit(out, width, height, 255, 0); rowbuf = malloc(sizeof(gray) * width); for (row = 0; row < height; row++) { for (col = 0; col < width; col++) rowbuf[col] = im[row][col]; pgm_writepgmrow(out, rowbuf, width, 255, 0); } free(rowbuf);}int ** imatrix(int nrows, int ncols){ int **m; int i, j; m = (int **) malloc (nrows * sizeof(int *)); for (i = 0; i < nrows; i++) { m[i] = (int *) malloc (ncols * sizeof(int)); if (!m[i]) fprintf(stderr, "\nIt's not working"); } for (i = 0; i < nrows; i++) for (j = 0; j < ncols; j++) m[i][j] = 0; return m;}void freematrix(int **I, int rows){ int k; for (k = 0; k < rows; k++) free (I[k]);}float ran0(long int *idum){ long int k; float ans; *idum ^= MASK; k = (*idum) / IQ; *idum = IA * (*idum - k * IQ) - IR * k; if (*idum < 0) *idum += IM; ans = AM * (*idum); *idum ^= MASK; return ans;}float gasdev(long int *idum){ float v1; v1 = (float) sqrt( -2.0 * log(ran0(idum))) * cos(2 * PI * ran0(idum)); return v1;}void put_image_from_int_2_double(int **i, double *f, int N){ int l, j, k; k = 0; for (l = 0; l < N; l++) for (j = 0; j < N; j++) f[k++] = (double) i[l][j];}void put_image_from_double_2_int(double *f, int **i, int N){ int l, j, k; k = 0; for (l = 0; l < N; l++) for (j = 0; j < N; j++) i[l][j] = (int) f[k++];}void bitrev(double *f, int len){ int i, j, m, halflen; double temp; if (len <= 2) return ; /* No action necessary if n=1 or n=2 */ halflen = len >> 1; j = 1; for (i = 1; i <= len; i++) { if (i < j) { temp = f[j - 1]; f[j - 1] = f[i - 1]; f[i - 1] = temp; } m = halflen; while (j > m) { j = j - m; m = (m + 1) >> 1; } j = j + m; }}void inv_sums(double *f){ int ii, stepsize, stage, curptr, nthreads, thread, step, nsteps; for (stage = 1; stage <= m - 1; stage++) { nthreads = 1 << (stage - 1); stepsize = nthreads << 1; nsteps = (1 << (m - stage)) - 1; for (thread = 1; thread <= nthreads; thread++) { curptr = NN - thread; for (step = 1; step <= nsteps; step++) { f[curptr] += f[curptr - stepsize]; curptr -= stepsize; } } }}//--------------------------------------------------------//Foreign code - FCT from Bath Univerity//--------------------------------------------------------void rarrwrt(double f[], int n){ int i; for (i = 0; i <= n - 1; i++) { fprintf(stderr, "%4d : %f\n", i, f[i]); }}/* fast DCT based on IEEE signal proc, 1992 #8, yugoslavian authors. */void fwd_sums(double *f){ int ii, stepsize, stage, curptr, nthreads, thread, step, nsteps; for (stage = m - 1; stage >= 1; stage--) { nthreads = 1 << (stage - 1); stepsize = nthreads << 1; nsteps = (1 << (m - stage)) - 1; for (thread = 1; thread <= nthreads; thread++) { curptr = nthreads + thread - 1; for (step = 1; step <= nsteps; step++) { f[curptr] += f[curptr + stepsize]; curptr += stepsize; } } }}void scramble(double *f, int len){ double temp; int i, ii1, ii2, halflen, qtrlen; halflen = len >> 1; qtrlen = halflen >> 1; bitrev(f, len); bitrev(&f[0], halflen); bitrev(&f[halflen], halflen); ii1 = len - 1; ii2 = halflen; for (i = 0; i <= qtrlen - 1; i++) { temp = f[ii1]; f[ii1] = f[ii2]; f[ii2] = temp; ii1--; ii2++; }}void unscramble(double *f, int len){ double temp; int i, ii1, ii2, halflen, qtrlen; halflen = len >> 1; qtrlen = halflen >> 1; ii1 = len - 1; ii2 = halflen; for (i = 0; i <= qtrlen - 1; i++) { temp = f[ii1]; f[ii1] = f[ii2]; f[ii2] = temp; ii1--; ii2++; } bitrev(&f[0], halflen); bitrev(&f[halflen], halflen); bitrev(f, len);}void initcosarray(int length){ int i, group, base, item, nitems, halfN; double factor; m = -1; do { m++; NN = 1 << m; if (NN > length) { fprintf(stderr, "ERROR in FCT-- length %d not a power of 2\n", length); exit(1); } } while (NN < length); if (C != NULL) free(C); C = (double *)calloc(NN, sizeof(double)); if (C == NULL) { fprintf(stderr, "Unable to allocate C array\n"); exit(1); } halfN = NN / 2; two_over_N = 2.0 / (double)NN; root2_over_rootN = sqrt(2.0 / (double)NN); for (i = 0; i <= halfN - 1; i++) C[halfN + i] = 4 * i + 1; for (group = 1; group <= m - 1; group++) { base = 1 << (group - 1); nitems = base; factor = 1.0 * (1 << (m - group)); for (item = 1; item <= nitems; item++) C[base + item - 1] = factor * C[halfN + item - 1]; } //printf("before taking cos, C array =\n"); rarrwrt(C,N); for (i = 1; i <= NN - 1; i++) C[i] = 1.0 / (2.0 * cos(C[i] * PI / (2.0 * NN))); //printf("After taking cos, Carray = \n"); rarrwrt(C,N);}void inv_butterflies(double *f){ int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr; double Cfac, T; for (stage = 1; stage <= m; stage++) { ngroups = 1 << (m - stage); wingspan = 1 << (stage - 1); increment = wingspan << 1; for (butterfly = 1; butterfly <= wingspan; butterfly++) { Cfac = C[wingspan + butterfly - 1]; baseptr = 0; for (group = 1; group <= ngroups; group++) { ii1 = baseptr + butterfly - 1; ii2 = ii1 + wingspan; T = Cfac * f[ii2]; f[ii2] = f[ii1]-T; f[ii1] = f[ii1] + T; baseptr += increment; } } }}void fwd_butterflies(double *f){ int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr; double Cfac, T; for (stage = m; stage >= 1; stage--) { ngroups = 1 << (m - stage); wingspan = 1 << (stage - 1); increment = wingspan << 1; for (butterfly = 1; butterfly <= wingspan; butterfly++) { Cfac = C[wingspan + butterfly - 1]; baseptr = 0; for (group = 1; group <= ngroups; group++) { ii1 = baseptr + butterfly - 1; ii2 = ii1 + wingspan; T = f[ii2]; f[ii2] = Cfac * (f[ii1]-T); f[ii1] = f[ii1] + T; baseptr += increment; } } }}void ifct_noscale(double *f, int length){ if (length != NN) initcosarray(length); f[0] *= INVROOT2; inv_sums(f); bitrev(f, NN); inv_butterflies(f); unscramble(f, NN);}void fct_noscale(double *f, int length){ if (length != NN) initcosarray(length); scramble(f, NN); fwd_butterflies(f); bitrev(f, NN); fwd_sums(f); f[0] *= INVROOT2;}void ifct_defn_scaling(double *f, int length){ ifct_noscale(f, length);}void fct_defn_scaling(double *f, int length){ int i; fct_noscale(f, length); for (i = 0; i <= NN - 1; i++) f[i] *= two_over_N;}void ifct(double *f, int length){ /* CALL THIS FOR INVERSE 1D DCT DON-MONRO PREFERRED SCALING */ int i; if (length != NN) initcosarray(length); /* BGS patch June 1997 */ for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN; ifct_noscale(f, length);}void fct(double *f, int length){ /* CALL THIS FOR FORWARD 1D DCT DON-MONRO PREFERRED SCALING */ int i; fct_noscale(f, length); for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN;}/**************************************************************** 2D FAST DCT SECTION****************************************************************/static double *g = NULL;static double two_over_sqrtncolsnrows = 0.0;static int ncolsvalue = 0;static int nrowsvalue = 0;void initfct2d(int nrows, int ncols){ if ((nrows <= 0) || (ncols < 0)) { fprintf(stderr, "FCT2D -- ncols=%d or nrows=%d is <=0\n", nrows, ncols); exit(1); } if (g != NULL) free(g); g = (double *)calloc(nrows, sizeof(double)); if (g == NULL) { fprintf(stderr, "FCT2D -- Unable to allocate g array\n"); exit(1); } ncolsvalue = ncols; nrowsvalue = nrows; two_over_sqrtncolsnrows = 2.0 / sqrt(ncols * 1.0 * nrows);}void fct2d(double f[], int nrows, int ncols)/* CALL THIS FOR FORWARD 2d DCT DON-MONRO PREFERRED SCALING */{ int u, v; if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){ initfct2d(nrows, ncols); } for (u = 0; u <= nrows - 1; u++){ fct_noscale(&f[u*ncols], ncols); } for (v = 0; v <= ncols - 1; v++){ for (u = 0; u <= nrows - 1; u++) { g[u] = f[u * ncols + v]; } fct_noscale(g, nrows); for (u = 0; u <= nrows - 1; u++) { f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows; } }}void ifct2d(double f[], int nrows, int ncols)/* CALL THIS FOR INVERSE 2d DCT DON-MONRO PREFERRED SCALING */{ int u, v; if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){ initfct2d(nrows, ncols); } for (u = 0; u <= nrows - 1; u++){ ifct_noscale(&f[u*ncols], ncols); } for (v = 0; v <= ncols - 1; v++){ for (u = 0; u <= nrows - 1; u++) { g[u] = f[u * ncols + v]; } ifct_noscale(g, nrows); for (u = 0; u <= nrows - 1; u++) { f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows; } }}void matmul(double **a, double **b, double **r, int N){ int i, j, k; for (i = 0; i < N; i++) for (j = 0; j < N; j++) { r[i][j] = 0.0; for (k = 0; k < N; k++) r[i][j] += a[i][k] * b[k][j]; }}void hartley(double **in, double **out, int N){ int k, n; double **h; h = dmatrix(N, N); //Building up the transformation matrix for (k = 0; k < N; k++) for (n = 0; n < N; n++) h[k][n] = (cos(2 * PI * k * n / N) + sin(2 * PI * k * n / N)) / sqrt(N); // Now we have to multiply the input with the transformation matrix matmul(h, in, out, N); freematrix_d(h, N); return ;}double ** dmatrix(int nrows, int ncols){ double **m; int i, j; m = (double **) malloc (nrows * sizeof(double *)); for (i = 0; i < nrows; i++) { m[i] = (double *) malloc (ncols * sizeof(double)); if (!m[i]) printf("\nIt's not working"); } for (i = 0; i < nrows; i++) for (j = 0; j < ncols; j++) m[i][j] = 0.0; return m;}void freematrix_d(double **I, int rows){ int k; for (k = 0; k < rows; k++) free (I[k]);}void matrix_i2d(int **i, double **d, int N){ int x, y; for (x = 0; x < N; x++) for (y = 0; y < N; y++) d[y][x] = i[y][x];}void matrix_d2i(double **d, int **i, int N){ int x, y; for (x = 0; x < N; x++) for (y = 0; y < N; y++) i[y][x] = d[y][x];}double * dvector(long int N){ double *m; m = (double *) malloc (N * sizeof(double)); if (!m) printf("\nIt's not working"); return m;}void put_matrix_2_vector(double **i, double *f, int N){ int l, j, k; k = 0; for (l = 0; l < N; l++) for (j = 0; j < N; j++) f[k++] = i[l][j];}void put_vector_2_matrix(double *f, double **i, int N){ int l, j, k; k = 0; for (l = 0; l < N; l++) for (j = 0; j < N; j++) i[l][j] = f[k++];}void set_in_binary() {#if defined(EMX) _fsetmode(in, "b");#elif defined(MINGW) setmode(STDIN_FILENO, O_BINARY);#endif}void set_out_binary() {#if defined(EMX) _fsetmode(out, "b");#elif defined(MINGW) setmode(STDOUT_FILENO, O_BINARY);#endif} void wm_init2() { set_out_binary();}void wm_init1() { set_in_binary();}void wm_init() { set_in_binary(); set_out_binary();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -