📄 dct.cpp
字号:
#include <stdio.h>
#include "DCT.h"
//亮度量化表,教材<<多媒体技术原理及应用>>p28表2.2
BYTE g_lumQuantTableDef[DCT_SIZE][DCT_SIZE] = {
{ 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 } };
//色度量化表,教材<<多媒体技术原理及应用>>p28表2.3
BYTE g_chrQuantTableDef[DCT_SIZE][DCT_SIZE] = {
{ 17,18,24,47,99,99,99,99 },
{ 18,21,26,66,99,99,99,99 },
{ 24,26,56,99,99,99,99,99 },
{ 47,66,99,99,99,99,99,99 },
{ 99,99,99,99,99,99,99,99 },
{ 99,99,99,99,99,99,99,99 },
{ 99,99,99,99,99,99,99,99 },
{ 99,99,99,99,99,99,99,99 } };
//亮度系数表
BYTE g_lumQuantTable[DCT_SIZE][DCT_SIZE];
//色度系数表
BYTE g_chrQuantTable[DCT_SIZE][DCT_SIZE];
//z型扫描表,教材<<多媒体技术原理及应用>>p29图2.12
BYTE g_rleZigZagTable[DCT_SIZE][DCT_SIZE] = {
{ 0, 1, 5, 6, 14,15,27,28 },
{ 2, 4, 7, 13,16,26,29,42 },
{ 3, 8, 12,17,25,30,41,43 },
{ 9, 11,18,24,31,40,44,53 },
{ 10,19,23,32,39,45,52,54 },
{ 20,22,33,38,46,51,55,60 },
{ 21,34,37,47,50,56,59,61 },
{ 35,36,48,49,57,58,62,63 } };
//离散余弦变换函数,公式教材<<多媒体技术原理及应用>>p27
void DCT_AAN(double dct[], double pic[])
{
static double x01, x11, x21, x31, x41, x51, x61, x71;
static double x0, x1, x2, x3;
x01 = pic[0]+pic[7];
x11 = pic[1]+pic[6];
x21 = pic[2]+pic[5];
x31 = pic[3]+pic[4];
x41 = pic[3]-pic[4];
x51 = pic[2]-pic[5];
x61 = pic[1]-pic[6];
x71 = pic[0]-pic[7];
x0 = x01+x31;
x1 = x11+x21;
x2 = x11-x21;
x3 = x01-x31;
dct[0] = 0.35355339*(x0+x1);
dct[4] = 0.35355339*(x0-x1);
x2 = 0.707106781*(x2+x3);
dct[2] = 0.27059805*(x2+x3);
dct[6] = 0.653281482*(x3-x2);
x0 = x41+x51;
x1 = x51+x61;
x2 = x61+x71;
x3 = 0.382683432*(x0-x2);
x41 = 0.541196100*x0+x3;
x51 = 0.707106781*x1;
x61 = 1.306562965*x2+x3;
x1 = x51+x71;
x3 = x71-x51;
dct[5] = 0.449988111*(x41+x3);
dct[1] = 0.254897789*(x1+x61);
dct[7] = 1.281457724*(x1-x61);
dct[3] = 0.300672443*(x3-x41);
}
//离散余弦变换调用函数
void DCT_8x8(double dct[][DCT_SIZE], double pic[][DCT_SIZE])
{
static int i, j;
static double res[DCT_SIZE][DCT_SIZE], out[DCT_SIZE], in[DCT_SIZE];
for (i=0; i<DCT_SIZE; i++)
{
for (j=0; j<DCT_SIZE; j++)
in[j] = pic[i][j]-128; //注意此处
DCT_AAN(res[i], in);
}
for (i=0; i<DCT_SIZE; i++)
{
for (j=0; j<DCT_SIZE; j++)
in[j] = res[j][i];
DCT_AAN(out, in);
for (j=0; j<DCT_SIZE; j++)
dct[j][i] = out[j];
}
}
//建立量化表
void InitQuantTable( BYTE compQuantTablePtr[][DCT_SIZE],const BYTE compQuantTableDef[][DCT_SIZE], int QValue )
{
int i, j, val;
if (QValue < 1)
QValue = 1;
if (QValue > 100)
QValue = 100;
if (QValue < 50) //nonlinear mapping 1->5000, 10->500, 25->200, 50->100, 75->50, 100->0
QValue = 5000/QValue;
else
QValue = 200-QValue*2;
for (i=0; i<DCT_SIZE; i++)
for (j=0; j<DCT_SIZE; j++)
{
val = (compQuantTableDef[i][j]*QValue+50)/100;
if (val < 1)
val = 1;
if (val > 255)
val = 255;
compQuantTablePtr[i][j] = val;
}
}
//量化处理函数
void QuantDCTValue(int quant[][DCT_SIZE], double dct[][DCT_SIZE], BYTE compQuantTable[][DCT_SIZE])
{
int i, j;
for (i=0; i<DCT_SIZE; i++)
for (j=0; j<DCT_SIZE; j++)
{
if(dct[i][j] >= 0)
quant[i][j] = (int)(dct[i][j]/compQuantTable[i][j]+0.5);
else
quant[i][j] = (int)(dct[i][j]/compQuantTable[i][j]-0.5);
}
}
//z型扫描函数
void ZigZagScan(int scan[], int quant[][DCT_SIZE])
{
int i, j;
for (i=0; i<DCT_SIZE; i++)
for (j=0; j<DCT_SIZE; j++)
scan[g_rleZigZagTable[i][j]] = quant[i][j];
}
//行程编码函数
void RunLengthEncode(int zlen[], int num[], int *cnt, int scan[])
{
int k = 0, z = 0;
(*cnt) = 0;
do {
k++;
if (scan[k] == 0)
{
if (k == 63)
{
zlen[*cnt] = 0;
num[*cnt] = 0;
(*cnt)++;
}
else
z++;
}
else
{
while (z > 15)
{
zlen[*cnt] = 15;
num[*cnt] = 0;
(*cnt)++;
z -= 16;
}
zlen[*cnt] = z;
num[*cnt] = scan[k];
(*cnt)++;
z = 0;
}
} while(k < 63);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -