dct.c 1.81 KB
#include <math.h>

#ifndef M_PI

#define M_PI            3.14159265358979323846

#endif


#include "dct.h"


/* prototypes */

void dct_init(void);
void ref_fdct(DCTELEM block[8][8]);
void ref_idct(DCTELEM block[8][8]);

/* Reference double-precision FDCT and IDCT */


/* The cosine lookup table */
/* coslu[a][b] = C(b)/2 * cos[(2a+1)b*pi/16] */
double coslu[8][8];


/* Routine to initialise the cosine lookup table */
void dct_init(void)
{
  int a,b;
  double tmp;

  for(a=0;a<8;a++)
    for(b=0;b<8;b++) {
      tmp = cos((double)((a+a+1)*b) * (M_PI / 16.0));
      if(b==0)
	tmp /= sqrt(2.0);
      coslu[a][b] = tmp * 0.5;
    }
}


void ref_fdct (DCTELEM block[8][8])
{
  int x,y,u,v;
  double tmp, tmp2;
  double res[8][8];

  if( coslu[0][0] == 0.0 )
    dct_init();

  for (v=0; v<8; v++) {
    for (u=0; u<8; u++) {
      tmp = 0.0;
      for (y=0; y<8; y++) {
	tmp2 = 0.0;
	for (x=0; x<8; x++) {
	  tmp2 += (double) block[y][x] * coslu[x][u];
	}
	tmp += coslu[y][v] * tmp2;
      }
      res[v][u] = tmp;
    }
  }

  for (v=0; v<8; v++) {
    for (u=0; u<8; u++) {
      tmp = res[v][u];
      if (tmp < 0.0) {
	x = - ((int) (0.5 - tmp));
      } else {
	x = (int) (tmp + 0.5);
      }
      block[v][u] = (DCTELEM) x;
    }
  }
}


void ref_idct (DCTELEM block[8][8])
{
  int x,y,u,v;
  double tmp, tmp2;
  double res[8][8];

  if( coslu[0][0] == 0.0 )
    dct_init();

  for (y=0; y<8; y++) {
    for (x=0; x<8; x++) {
      tmp = 0.0;
      for (v=0; v<8; v++) {
	tmp2 = 0.0;
	for (u=0; u<8; u++) {
	  tmp2 += (double) block[v][u] * coslu[x][u];
	}
	tmp += coslu[y][v] * tmp2;
      }
      res[y][x] = tmp;
    }
  }

  for (v=0; v<8; v++) {
    for (u=0; u<8; u++) {
      tmp = res[v][u];
      if (tmp < 0.0) {
	x = - ((int) (0.5 - tmp));
      } else {
	x = (int) (tmp + 0.5);
      }
      block[v][u] = (DCTELEM) x;
    }
  }
}