All pastes #225289 Raw Edit

Anonymous

public text v1 · immutable
#225289 ·published 2006-10-27 21:17 UTC
rendered paste body
/**
 *
 */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include "dct.h"

#include "qcif.h"
#include "quantizer.h"

/****************************************************************************/

/* Pi */
#define PI 3.14159265

/****************************************************************************/

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

/****************************************************************************/

/* cosine coefficient values */
#define C1 (cos (PI       / 16))
#define C2 (cos ((2 * PI) / 16))
#define C3 (cos ((3 * PI) / 16))
#define C4 (cos ((4 * PI) / 16))
#define C5 (cos ((5 * PI) / 16))
#define C6 (cos ((6 * PI) / 16))
#define C7 (cos ((7 * PI) / 16))

/* DCT addition nodes, form of N<col><row> */
#define N11 (f[0] + f[7])
#define N12 (f[1] + f[6])
#define N13 (f[2] + f[5])
#define N14 (f[3] + f[4])
#define N15 (f[3] - f[4])
#define N16 (f[2] - f[5])
#define N17 (f[1] - f[6])
#define N18 (f[0] - f[7])

#define N21 (N11 + N14)
#define N22 (N12 + N13)
#define N23 (N12 - N13)
#define N24 (N11 - N14)
#define N25 (N15)
#define N26 ((N17 - N16) * C4)
#define N27 ((N17 + N16) * C4)
#define N28 (N18)

#define N31 ((N21 + N22) * C4)
#define N32 ((N21 - N22) * C4)
#define N33 (N23 * C6 + N24 * C2)
#define N34 (N24 * C6 - N23 * C2)
#define N35 (N25 + N26)
#define N36 (N25 - N26)
#define N37 (N28 - N27)
#define N38 (N28 + N27)

/* IDCT addition nodes, form of IN<col><row> */
#define IN31 (F[0])
#define IN32 (F[4])
#define IN33 (F[2])
#define IN34 (F[6])
#define IN35 (F[1] * C7 - F[7] * C1)
#define IN36 (F[5] * C3 - F[3] * C5)
#define IN37 (F[5] * C5 + F[3] * C3)
#define IN38 (F[1] * C1 + F[7] * C7)

#define IN21 ((IN31 + IN32) * C4)
#define IN22 ((IN31 - IN32) * C4)
#define IN23 (IN33 * C6 - IN34 * C2)
#define IN24 (IN34 * C6 + IN33 * C2)
#define IN25 (IN35 + IN36)
#define IN26 (IN35 - IN36)
#define IN27 (IN38 - IN37)
#define IN28 (IN38 + IN37)

#define IN11 (IN21 + IN24)
#define IN12 (IN22 + IN23)
#define IN13 (IN22 - IN23)
#define IN14 (IN21 - IN24)
#define IN15 (IN25)
#define IN16 ((IN27 - IN26) * C4)
#define IN17 ((IN27 + IN26) * C4)
#define IN18 (IN28)

/****************************************************************************/

/* 1-D DCT across a row or column, horizontal should be TRUE or FALSE */
void compute_1d_dct (DctBlock *block, int horizontal, int row_col)
{
	double f[8];
	double F2[8];
	int    i;
	
	for (i = 0; i < 8; i++)
	{
		if (horizontal)
			f[i] = block->f[row_col][i];
		else
			f[i] = block->f[i][row_col];
	}
	
	/* calculate transforms using common addition nodes */
	F2[0] = N31;
	F2[4] = N32;
	F2[2] = N33;
	F2[6] = N34;
	F2[1] = N35 * C7 + N38 * C1;
	F2[5] = N36 * C3 + N37 * C5;
	F2[3] = N37 * C3 - N36 * C5;
	F2[7] = N38 * C7 - N35 * C1;
	
	for (i = 0; i < 8; i++)
	{
		if (horizontal)
			block->f[row_col][i] = F2[i] / 2.0;
		else
			block->f[i][row_col] = F2[i] / 2.0;
	}
}

/* 1-D IDCT across a row or column, horizontal should be TRUE or FALSE */
void compute_1d_idct (DctBlock *block, int horizontal, int row_col)
{
	double f[8];
	double F[8];
	int    i;
	
	for (i = 0; i < 8; i++)
	{
		if (horizontal)
			F[i] = block->f[row_col][i] * 2.0;
		else
			F[i] = block->f[i][row_col] * 2.0;
	}
	
	/* calculate transforms using common addition nodes */
	f[0] = IN11 + IN18;
	f[1] = IN12 + IN17;
	f[2] = IN13 + IN16;
	f[3] = IN14 + IN15;
	f[4] = IN14 - IN15;
	f[5] = IN13 - IN16;
	f[6] = IN12 - IN17;
	f[7] = IN11 - IN18;
	
	/* note that when converting back, we scale by a factor of 2/N = 2/8 */
	for (i = 0; i < 8; i++)
	{
		if (horizontal)
			block->f[row_col][i] = f[i] / 4.0;
		else
			block->f[i][row_col] = f[i] / 4.0;
	}
}

/****************************************************************************/

void dct_block_free (DctBlock *block)
{
	free (block);
}

DctBlock *dct_block_init ()
{
	DctBlock *block   = (DctBlock *)malloc (sizeof (DctBlock));
	int       i, j;
	
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
			block->f[i][j] = 0.0;
	}
	
	return block;
}

DctBlock *dct_block_new_char (char *row0, char *row1, char *row2, char *row3, 
                              char *row4, char *row5, char *row6, char *row7, 
                              int offset)
{
	char   *crow[8];
	double  drow[8][8];
	int     i, j;
	
	/* for looping convenience */
	crow[0] = row0;
	crow[1] = row1;
	crow[2] = row2;
	crow[3] = row3;
	crow[4] = row4;
	crow[5] = row5;
	crow[6] = row6;
	crow[7] = row7;
	
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
			drow[i][j] = (double)crow[i][j];
	}
	
	return dct_block_new_double (drow[0], drow[1], drow[2], drow[3], 
	                             drow[4], drow[5], drow[6], drow[7], 
	                             offset);
}

DctBlock *dct_block_new_double (double *row0, double *row1, double *row2, 
                                double *row3, double *row4, double *row5, 
                                double *row6, double *row7, int offset)
{
	DctBlock *block   = dct_block_init ();
	double   *drow[8];
	int       i, j;
	
	/* for looping convenience */
	drow[0] = row0;
	drow[1] = row1;
	drow[2] = row2;
	drow[3] = row3;
	drow[4] = row4;
	drow[5] = row5;
	drow[6] = row6;
	drow[7] = row7;
	
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
			block->f[i][j] = drow[i][j + offset];
	}
	
	return block;
}

void dct_block_print (DctBlock *block)
{
	int i;
	
	printf ("DCT Block:\n");
	
	for (i = 0; i < 8; i++)
		printf ("[ %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f ]\n", 
		        block->f[i][0], block->f[i][1], block->f[i][2], 
		        block->f[i][3], block->f[i][4], block->f[i][5], 
				block->f[i][6], block->f[i][7]);
}

void dct_block_quantize (DctBlock *block)
{
	int i, j;
	
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
			block->f[i][j] = quantize (block->f[i][j]);
	}
}

/****************************************************************************/

DctFrame *dct_frame_init ()
{
	return (DctFrame *)malloc (sizeof (DctFrame));
}

DctFrame *dct_frame_new (double **components)
{
	
}

/****************************************************************************/

void compute_dct (DctBlock *block)
{
	int i;
	
	/* computer 1-D horizontal DCTs */
	for (i = 0; i < 8; i++)
		compute_1d_dct (block, TRUE, i);
	
	/* computer 1-D vertical DCTs */
	for (i = 0; i < 8; i++)
		compute_1d_dct (block, FALSE, i);
}

void compute_idct (DctBlock *block)
{
	int i;

	/* compute 1-D vertical IDCTs */
	for (i = 0; i < 8; i++)
		compute_1d_idct (block, FALSE, i);

	/* compute 1-D horizontal IDCTs */
	for (i = 0; i < 8; i++)
		compute_1d_idct (block, TRUE, i);
}

/****************************************************************************/