/*******
* dct_transform.c
*
* Looking at the discrete cosine transform
*
*******/
#include <stdio.h>
#include <math.h>
// Number of points. JPEG's typically used 8x8 2-dim DCT's.
#define N 8
// ------------------------------------------------------
// Define the 64 terms in the DCT and DCT_inverse matrix.
void defineDCT(double dct[N][N]){
double pi = 4.0*atan(1.0); // typical way to get pi, using tan(pi/4)=1
double piOver2N = pi/(2*N);
double invSqrt2 = 1.0/sqrt(2.0);
double sqrt2overN = sqrt(2.0/N);
double C;
int u,x;
for (u=0; u<N; u++){
C = u==0 ? invSqrt2 : 1;
for (x=0; x<N; x++) {
dct[u][x] = sqrt2overN*C*cos( (2*x+1)*u*piOver2N );
}
}
}
// ------------------------------------------------------
// The DCT matrix is orthogonal, so its transpose is also its inverse.
void transposeMatrix(double a[N][N], double aTrans[N][N]){
int row,col;
for (row=0; row<N; row++){
for (col=0; col<N; col++){
aTrans[col][row] = a[row][col];
}
}
}
// ------------------------------------------------------
void matrixTimesVector(double m[N][N], double v[N], double answer[N]){
int row,col;
double tmp;
for (row=0; row<N; row++){
tmp=0;
for (col=0; col<N; col++){
tmp += m[row][col]*v[col];
}
answer[row]=tmp;
}
}
// ------------------------------------------------------
int main(){
double dct[N][N]; // All these are [row][column]
double dctInv[N][N];
double f[N] = { -.2, -.1, 0.0, 0.1, 0.2, 0.2, 0.2, 0.2 };
double S[N];
double ff[N];
int i;
defineDCT(dct);
transposeMatrix(dct, dctInv);
matrixTimesVector(dct, f, S); // transform f -> S
matrixTimesVector(dctInv, S, ff); // inverse transform S -> ff
printf("# Here's an array and its discrete cosine transform. \n");
printf("# Using N=%d.\n",N);
printf("#\n");
printf("# f[x] original, S[u] transform, ff[x] restored original \n");
for (i=0; i<N; i++){
printf(" % 7.5f % 7.5f % 7.5f \n", f[i], S[i], ff[i]);
}
}
syntax highlighted by Code2HTML, v. 0.9.1