/**************************************************************/
/* FILE NAME : F_DCT.C */
/* AUTHOR : HWEIHN CHUNG */
/* DATE : 94 / 02 / 15 */
/* Descript. : This program is to excute encoding process. */
/* ( DCT , quantization, Huffman encoding ) */
/* Input data : lenna.dat , couple.dat */
/**************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "huffman.h"
/*void File_Open();*/
void FDCT(short block[8][8]);
void QUANT(short Qblock[64]);
short Encode(short DctBuffer[64],short PreDc);
void PutCode(short Code, int Length);
void EncodeDc(short Dc, Huffman *h);
void EncodeAc(short Ac, short Run, Huffman *h);
FILE *in,*out;
/********************/
/* MAIN FUNCTION */
/********************/
main()
{
int cnt_sli, cnt_blk;
int i, j, k=0,l,m,n,cnt =0;
unsigned char buffer[256];
unsigned char slice[8][256];
short block[8][8];
short Pre_Dc=0;
short Huff[64];
File_Open();
for(cnt_sli = 0; cnt_sli < 32; cnt_sli++)
{
for(i = 0; i < 8; i++)
{
fread(buffer, SUC, 256, in);
for(j = 0; j < 256; j++) slice[i][j] = buffer[j];
}
for(cnt_blk = 0; cnt_blk < 32; cnt_blk++)
{
for(i = 0; i < 8; i++)
for(j = 0; j < 8; j++)
{
k = (cnt_blk*8)+j;
block[i][j] = slice[i][k];
}
FDCT(block); /* excute Discrete Cosine Transform */
for(l = 0; l < 8; l++)
for(m = 0; m < 8; m++) Huff[l*8+m] = block[l][m];
QUANT(Huff);*/
/* Huffman Encoding */
Pre_Dc = Encode(Huff,Pre_Dc);
printf("FDCT Process ===> %4d\n",cnt++);
}
}
printf("%ld",(unsigned long)CodeLength);
fwrite(CodeBuffer, SUC, (unsigned long) CodeLength, out);
printf("\nFDCT Process Is Terminated !!!!!\n");
fcloseall();
}
/*************************/
/* function to open file */
/*************************/
/*void File_Open()
{
// clrscr();
if((in=fopen("couple.dat","rb"))==NULL){
printf("\n\n\t file open error ! \a");
exit(1);
}
out=fopen("fdct.dat","wb");
}
*/
/**************************************************/
/* function for Foward Discrete Cosine Transform */
/**************************************************/
short Coeff[8][8]
= { { 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096 },
{ 5681, 4816, 3218, 1130, -1130, -3218, -4816, -5681},
{ 5352, 2217, -2217, -5352, -5352, -2217, 2217, 5352 },
{ 4816, -1130, -5681, -3218, 3218, 5681, 1130, -4816 },
{ 4096, -4096, -4096, 4096, 4096, -4096, -4096, 4096 },
{ 3218, -5681, 1130, 4816, -4816, -1130, 5681, -3218 },
{ 2217, -5352, 5352, -2217, -2217, 5352, -5352, 2217 },
{ 1130, -3218, 4816, -5681, 5681, -4816, 3218, -1130 } };
void FDCT(short block[8][8])
{
int i, j, k;
long dd;
short temp[8][8];
for(i = 0; i < 8; i++)
for(j = 0; j < 8; j++)
{
dd = 0;
for(k = 0; k < 8; k++)
dd += (long)block[i][k] * Coeff[j][k];
temp[i][j] = ((dd + 2048) >> 12);
}
for(i = 0; i < 8; i++)
for(j = 0; j < 8; j++)
{
dd = 0;
for(k = 0; k < 8; k++)
dd += (long)temp[k][i] * Coeff[j][k];
block[j][i] = ((dd + 16384) >> 15);
}
}
/*****************************/
/* function for Quantization */
/*****************************/
int Qtable[64]
= { 16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
void QUANT(short Qblock[64])
{
int i;
for(i = 0; i < 64; i++)
{
if(Qblock[i] >= 0)
Qblock[i] = (short)(((float)Qblock[i] + (float)Qtable[i] / 2.) / (float)Qtable[i]);
else
Qblock[i] = (short)(((float)Qblock[i] - (float)Qtable[i] / 2.) / (float)Qtable[i]);
}
}
/*************************/
/* function for Encoding */
/*************************/
short Encode(short DctBuffer[64], short PreDc)
{
short Dc, Ac, Run;
int k;
k = 0;
Dc = DctBuffer[Zigzag[k++]] - PreDc;
PreDc += Dc;
EncodeDc(Dc, DcHuffman);
Run = 0;
for(;;)
{
Ac = DctBuffer[Zigzag[k++]];
if(!Ac)
{
if(k >= 64)
{
EncodeAc(0, 0, AcHuffman);
break;
}
Run++;
}
else
{
while(Run > 15)
{
EncodeAc(0, 15, AcHuffman);
Run -= 16;
}
EncodeAc(Ac, Run, AcHuffman);
if(k >= 64) break;
Run = 0;
}
}
return(PreDc);
}
/**************************************/
/* function for Encoding DC component */
/**************************************/
void EncodeDc(short Dc, Huffman *h)
{
int s;
if(Dc == 0) s = 0;
else if( -1 <= Dc && Dc <= 1) s = 1;
else if( -3 <= Dc && Dc <= 3) s = 2;
else if( -7 <= Dc && Dc <= 7) s = 3;
else if( -15 <= Dc && Dc <= 15) s = 4;
else if( -31 <= Dc && Dc <= 31) s = 5;
else if( -63 <= Dc && Dc <= 63) s = 6;
else if( -127 <= Dc && Dc <= 127) s = 7;
else if( -255 <= Dc && Dc <= 255) s = 8;
else if( -511 <= Dc && Dc <= 511) s = 9;
else if( -1023 <= Dc && Dc <= 1023) s = 10;
else if( -2047 <= Dc && Dc <= 2047) s = 11;
PutCode(h[s].Code, h[s].Length);
if(s)
{
if(Dc < 0) Dc--;
PutCode(Dc, s);
}
}
/**************************************/
/* function for Encoding AC component */
/**************************************/
void EncodeAc(short Ac, short Run, Huffman *h)
{
int s;
if(Ac == 0) s = 0;
else if( -1 <= Ac && Ac <= 1) s = 1;
else if( -3 <= Ac && Ac <= 3) s = 2;
else if( -7 <= Ac && Ac <= 7) s = 3;
else if( -15 <= Ac && Ac <= 15) s = 4;
else if( -31 <= Ac && Ac <= 31) s = 5;
else if( -63 <= Ac && Ac <= 63) s = 6;
else if( -127 <= Ac && Ac <= 127) s = 7;
else if( -255 <= Ac && Ac <= 255) s = 8;
else if( -511 <= Ac && Ac <= 511) s = 9;
else if( -1023 <= Ac && Ac <= 1023) s = 10;
PutCode(h[s+(Run << 4)].Code, h[s+(Run << 4)].Length);
if(s)
{
if(Ac < 0) Ac--;
PutCode(Ac, s);
}
}
/***************************/
/* function to store code */
/***************************/
void PutCode(short Code, int Length)
{
int i;
int p1, p2;
for(i = 0; i < Length; i++)
{
p1 = (CodeLength >> 3);
p2 = (CodeLength & 7);
if( Code & (1 << (Length-1-i))) CodeBuffer[p1] |= (0x80 >> p2);
else CodeBuffer[p1] &= ~(0x80 >> p2);
CodeLength++;
}
}