JPEG 编解码中的 dct 变换
总结了一下,大家可以作为参考。
/* 包含头文件 */
#include "dct.h"
#if 1 /* 快速的整数运算版本 */
/* 内部常量定义 */
#define DCTSIZE 8
/* 内部全局变量定义 */
static long enfactor[64] =
{
65536, 47248, 50159, 55733, 65536, 83411, 121094, 237535,
47248, 34064, 36162, 40181, 47248, 60136, 87304, 171253,
50159, 36162, 38390, 42656, 50159, 63840, 92681, 181802,
55733, 40181, 42656, 47397, 55733, 70935, 102982, 202007,
65536, 47248, 50159, 55733, 65536, 83411, 121094, 237535,
83411, 60136, 63840, 70935, 83411, 106162, 154124, 302325,
121094, 87304, 92681, 102982, 121094, 154124, 223753, 438909,
237535, 171253, 181802, 202007, 237535, 302325, 438909, 860951,
};
static long defactor[64] =
{
65536, 90901, 85626, 77062, 65536, 51491, 35467, 18081,
90901, 126083, 118767, 106888, 90901, 71420, 49195, 25079,
85626, 118767, 111876, 100686, 85626, 67276, 46340, 23624,
77062, 106888, 100686, 90615, 77062, 60547, 41705, 21261,
65536, 90901, 85626, 77062, 65536, 51491, 35467, 18081,
51491, 71420, 67276, 60547, 51491, 40456, 27866, 14206,
35467, 49195, 46340, 41705, 35467, 27866, 19195, 9785,
18081, 25079, 23624, 21261, 18081, 14206, 9785, 4988,
};
/*
46341 / 65536 = 0.707106781f
25080 / 65536 = 0.382683433f
35468 / 65536 = 0.541196100f
85627 / 65536 = 1.306562965f
92682 / 65536 = 1.414213562f
121095 / 65536 = 1.847759065f
70936 / 65536 = 1.082392200f
171254 / 65536 = 2.613125930f
*/
/* 函数实现 */
void fdct2d8x8(long *data)
{
long tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
long tmp10, tmp11, tmp12, tmp13;
long z1, z2, z3, z4, z5, z11, z13;
long *dataptr;
int ctr, i;
for (i=0; i<64; i++) data[i] <<= 1;
/* Pass 1: process rows. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
tmp0 = dataptr[0] + dataptr[7];
tmp7 = dataptr[0] - dataptr[7];
tmp1 = dataptr[1] + dataptr[6];
tmp6 = dataptr[1] - dataptr[6];
tmp2 = dataptr[2] + dataptr[5];
tmp5 = dataptr[2] - dataptr[5];
tmp3 = dataptr[3] + dataptr[4];
tmp4 = dataptr[3] - dataptr[4];
/* Even part */
tmp10 = tmp0 + tmp3; /* phase 2 */
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; /* phase 3 */
dataptr[4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * 46341 >> 16; /* c4 */
dataptr[2] = tmp13 + z1; /* phase 5 */
dataptr[6] = tmp13 - z1;
/* Odd part */
tmp10 = tmp4 + tmp5; /* phase 2 */
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
/* The rotator is modified from fig 4-8 to avoid extra negations. */
z5 = (tmp10 - tmp12) * 25080 >> 16; /* c6 */
z2 = (tmp10 * 35468 >> 16) + z5; /* c2-c6 */
z4 = (tmp12 * 85627 >> 16) + z5; /* c2+c6 */
z3 = tmp11 * 46341 >> 16; /* c4 */
z11 = tmp7 + z3; /* phase 5 */
z13 = tmp7 - z3;
dataptr[5] = z13 + z2; /* phase 6 */
dataptr[3] = z13 - z2;
dataptr[1] = z11 + z4;
dataptr[7] = z11 - z4;
dataptr += DCTSIZE; /* advance pointer to next row */
}
/* Pass 2: process columns. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
tmp0 = dataptr[DCTSIZE * 0] + dataptr[DCTSIZE * 7];
tmp7 = dataptr[DCTSIZE * 0] - dataptr[DCTSIZE * 7];
tmp1 = dataptr[DCTSIZE * 1] + dataptr[DCTSIZE * 6];
tmp6 = dataptr[DCTSIZE * 1] - dataptr[DCTSIZE * 6];
tmp2 = dataptr[DCTSIZE * 2] + dataptr[DCTSIZE * 5];
tmp5 = dataptr[DCTSIZE * 2] - dataptr[DCTSIZE * 5];
tmp3 = dataptr[DCTSIZE * 3] + dataptr[DCTSIZE * 4];
tmp4 = dataptr[DCTSIZE * 3] - dataptr[DCTSIZE * 4];
/* Even part */
tmp10 = tmp0 + tmp3; /* phase 2 */
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[DCTSIZE * 0] = tmp10 + tmp11; /* phase 3 */
dataptr[DCTSIZE * 4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * 46341 >> 16; /* c4 */
dataptr[DCTSIZE * 2] = tmp13 + z1; /* phase 5 */
dataptr[DCTSIZE * 6] = tmp13 - z1;
/* Odd part */
tmp10 = tmp4 + tmp5; /* phase 2 */
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
/* The rotator is modified from fig 4-8 to avoid extra negations. */
z5 = (tmp10 - tmp12) * 25080 >> 16; /* c6 */
z2 = (tmp10 * 35468 >> 16) + z5; /* c2-c6 */
z4 = (tmp12 * 85627 >> 16) + z5; /* c2+c6 */
z3 = tmp11 * 46341 >> 16; /* c4 */
z11 = tmp7 + z3; /* phase 5 */
z13 = tmp7 - z3;
dataptr[DCTSIZE * 5] = z13 + z2; /* phase 6 */
dataptr[DCTSIZE * 3] = z13 - z2;
dataptr[DCTSIZE * 1] = z11 + z4;
dataptr[DCTSIZE * 7] = z11 - z4;
dataptr++; /* advance pointer to next column */
}
for (i=0; i<64; i++)
{
data[i] *= enfactor[i];
data[i] >>= 20;
}
}
void idct2d8x8(long *data)
{
long tmp0, tmp1, tmp2, tmp3;
long tmp4, tmp5, tmp6, tmp7;
long tmp10, tmp11, tmp12, tmp13;
long z5, z10, z11, z12, z13;
long *dataptr;
int ctr, i;
for (i=0; i<64; i++)
{
data[i] *= defactor[i];
data[i] >>= 13;
}
/* Pass 1: process rows. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
if ( dataptr[1] + dataptr[2] + dataptr[3] + dataptr[4] +
dataptr[5] + dataptr[6] + dataptr[7] == 0 )
{
dataptr[1] = dataptr[0];
dataptr[2] = dataptr[0];
dataptr[3] = dataptr[0];
dataptr[4] = dataptr[0];
dataptr[5] = dataptr[0];
dataptr[6] = dataptr[0];
dataptr[7] = dataptr[0];
dataptr += DCTSIZE;
continue;
}
/* Even part */
tmp0 = dataptr[0];
tmp1 = dataptr[2];
tmp2 = dataptr[4];
tmp3 = dataptr[6];
tmp10 = tmp0 + tmp2; /* phase 3 */
tmp11 = tmp0 - tmp2;
tmp13 = tmp1 + tmp3; /* phases 5-3 */
tmp12 = tmp1 - tmp3; /* 2 * c4 */
tmp12 *= 92682;
tmp12 >>= 16;
tmp12 -= tmp13;
tmp0 = tmp10 + tmp13; /* phase 2 */
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
/* Odd part */
tmp4 = dataptr[1];
tmp5 = dataptr[3];
tmp6 = dataptr[5];
tmp7 = dataptr[7];
z13 = tmp6 + tmp5; /* phase 6 */
z10 = tmp6 - tmp5;
z11 = tmp4 + tmp7;
z12 = tmp4 - tmp7;
tmp7 = z11 + z13; /* phase 5 */
tmp11 = z11 - z13; /* 2 * c4 */
tmp11 *= 92682;
tmp11 >>= 16;
z5 = (z10 + z12) * 121095 >> 16; /* 2 * c2 */
tmp10 = (z12 * 70936 >> 16) - z5; /* 2 * (c2 - c6) */
tmp12 = -(z10 * 171254 >> 16) + z5; /* -2 * (c2 + c6) */
tmp6 = tmp12 - tmp7; /* phase 2 */
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
dataptr[0] = tmp0 + tmp7;
dataptr[7] = tmp0 - tmp7;
dataptr[1] = tmp1 + tmp6;
dataptr[6] = tmp1 - tmp6;
dataptr[2] = tmp2 + tmp5;
dataptr[5] = tmp2 - tmp5;
dataptr[4] = tmp3 + tmp4;
dataptr[3] = tmp3 - tmp4;
dataptr += DCTSIZE;
}
/* Pass 2: process columns. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
/* Even part */
tmp0 = dataptr[DCTSIZE * 0];
tmp1 = dataptr[DCTSIZE * 2];
tmp2 = dataptr[DCTSIZE * 4];
tmp3 = dataptr[DCTSIZE * 6];
tmp10 = tmp0 + tmp2; /* phase 3 */
tmp11 = tmp0 - tmp2;
tmp13 = tmp1 + tmp3; /* phases 5-3 */
tmp12 = tmp1 - tmp3; /* 2 * c4 */
tmp12 *= 92682;
tmp12 >>= 16;
tmp12 -= tmp13;
tmp0 = tmp10 + tmp13; /* phase 2 */
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
/* Odd part */
tmp4 = dataptr[DCTSIZE * 1];
tmp5 = dataptr[DCTSIZE * 3];
tmp6 = dataptr[DCTSIZE * 5];
tmp7 = dataptr[DCTSIZE * 7];
z13 = tmp6 + tmp5; /* phase 6 */
z10 = tmp6 - tmp5;
z11 = tmp4 + tmp7;
z12 = tmp4 - tmp7;
tmp7 = z11 + z13; /* phase 5 */
tmp11 = z11 - z13; /* 2 * c4 */
tmp11 *= 92682;
tmp11 >>= 16;
z5 = (z10 + z12) * 121095 >> 16; /* 2 * c2 */
tmp10 = (z12 * 70936 >> 16) - z5; /* 2 * (c2 - c6) */
tmp12 = -(z10 * 171254 >> 16) + z5; /* -2 * (c2 + c6) */
tmp6 = tmp12 - tmp7; /* phase 2 */
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
dataptr[DCTSIZE * 0] = tmp0 + tmp7;
dataptr[DCTSIZE * 7] = tmp0 - tmp7;
dataptr[DCTSIZE * 1] = tmp1 + tmp6;
dataptr[DCTSIZE * 6] = tmp1 - tmp6;
dataptr[DCTSIZE * 2] = tmp2 + tmp5;
dataptr[DCTSIZE * 5] = tmp2 - tmp5;
dataptr[DCTSIZE * 4] = tmp3 + tmp4;
dataptr[DCTSIZE * 3] = tmp3 - tmp4;
dataptr++; /* advance pointers to next column */
}
for (i=0; i<64; i++) data[i] >>= 6;
}
#endif
#if 0 /* 快速的浮点数运算版本 */
/* 内部常量定义 */
#define DCTSIZE 8
/* 内部全局变量定义 */
static float aandctfactor[DCTSIZE] = {
1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
1.0f, 0.785694958f, 0.541196100f, 0.275899379f,
};
static float dctfactor[64] = {0};
/* 内部函数实现 */
static initdctfactor()
{
int i, j;
for (i=0; i<DCTSIZE; i++)
for (j=0; j<DCTSIZE; j++)
dctfactor[i * 8 + j] = aandctfactor[i] * aandctfactor[j];
}
/* 函数实现 */
void fdct2d8x8(float *data)
{
float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
float tmp10, tmp11, tmp12, tmp13;
float z1, z2, z3, z4, z5, z11, z13;
float *dataptr;
int ctr;
/* Pass 1: process rows. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
tmp0 = dataptr[0] + dataptr[7];
tmp7 = dataptr[0] - dataptr[7];
tmp1 = dataptr[1] + dataptr[6];
tmp6 = dataptr[1] - dataptr[6];
tmp2 = dataptr[2] + dataptr[5];
tmp5 = dataptr[2] - dataptr[5];
tmp3 = dataptr[3] + dataptr[4];
tmp4 = dataptr[3] - dataptr[4];
/* Even part */
tmp10 = tmp0 + tmp3; /* phase 2 */
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; /* phase 3 */
dataptr[4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * 0.707106781f; /* c4 */
dataptr[2] = tmp13 + z1; /* phase 5 */
dataptr[6] = tmp13 - z1;
/* Odd part */
tmp10 = tmp4 + tmp5; /* phase 2 */
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
/* The rotator is modified from fig 4-8 to avoid extra negations. */
z5 = (tmp10 - tmp12) * 0.382683433f; /* c6 */
z2 = 0.541196100f * tmp10 + z5; /* c2-c6 */
z4 = 1.306562965f * tmp12 + z5; /* c2+c6 */
z3 = tmp11 * 0.707106781f; /* c4 */
z11 = tmp7 + z3; /* phase 5 */
z13 = tmp7 - z3;
dataptr[5] = z13 + z2; /* phase 6 */
dataptr[3] = z13 - z2;
dataptr[1] = z11 + z4;
dataptr[7] = z11 - z4;
dataptr += DCTSIZE; /* advance pointer to next row */
}
/* Pass 2: process columns. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
tmp0 = dataptr[DCTSIZE * 0] + dataptr[DCTSIZE * 7];
tmp7 = dataptr[DCTSIZE * 0] - dataptr[DCTSIZE * 7];
tmp1 = dataptr[DCTSIZE * 1] + dataptr[DCTSIZE * 6];
tmp6 = dataptr[DCTSIZE * 1] - dataptr[DCTSIZE * 6];
tmp2 = dataptr[DCTSIZE * 2] + dataptr[DCTSIZE * 5];
tmp5 = dataptr[DCTSIZE * 2] - dataptr[DCTSIZE * 5];
tmp3 = dataptr[DCTSIZE * 3] + dataptr[DCTSIZE * 4];
tmp4 = dataptr[DCTSIZE * 3] - dataptr[DCTSIZE * 4];
/* Even part */
tmp10 = tmp0 + tmp3; /* phase 2 */
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[DCTSIZE * 0] = tmp10 + tmp11; /* phase 3 */
dataptr[DCTSIZE * 4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * 0.707106781f; /* c4 */
dataptr[DCTSIZE * 2] = tmp13 + z1; /* phase 5 */
dataptr[DCTSIZE * 6] = tmp13 - z1;
/* Odd part */
tmp10 = tmp4 + tmp5; /* phase 2 */
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
/* The rotator is modified from fig 4-8 to avoid extra negations. */
z5 = (tmp10 - tmp12) * 0.382683433f; /* c6 */
z2 = 0.541196100f * tmp10 + z5; /* c2-c6 */
z4 = 1.306562965f * tmp12 + z5; /* c2+c6 */
z3 = tmp11 * 0.707106781f; /* c4 */
z11 = tmp7 + z3; /* phase 5 */
z13 = tmp7 - z3;
dataptr[DCTSIZE * 5] = z13 + z2; /* phase 6 */
dataptr[DCTSIZE * 3] = z13 - z2;
dataptr[DCTSIZE * 1] = z11 + z4;
dataptr[DCTSIZE * 7] = z11 - z4;
dataptr++; /* advance pointer to next column */
}
}
void idct2d8x8(float *data)
{
float tmp0, tmp1, tmp2, tmp3;
float tmp4, tmp5, tmp6, tmp7;
float tmp10, tmp11, tmp12, tmp13;
float z5, z10, z11, z12, z13;
float *dataptr;
int ctr;
/* Pass 1: process rows. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
/* Even part */
tmp0 = dataptr[0];
tmp1 = dataptr[2];
tmp2 = dataptr[4];
tmp3 = dataptr[6];
tmp10 = tmp0 + tmp2; /* phase 3 */
tmp11 = tmp0 - tmp2;
tmp13 = tmp1 + tmp3; /* phases 5-3 */
tmp12 = tmp1 - tmp3; /* 2 * c4 */
tmp12 *= 1.414213562f;
tmp12 -= tmp13;
tmp0 = tmp10 + tmp13; /* phase 2 */
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
/* Odd part */
tmp4 = dataptr[1];
tmp5 = dataptr[3];
tmp6 = dataptr[5];
tmp7 = dataptr[7];
z13 = tmp6 + tmp5; /* phase 6 */
z10 = tmp6 - tmp5;
z11 = tmp4 + tmp7;
z12 = tmp4 - tmp7;
tmp7 = z11 + z13; /* phase 5 */
tmp11 = z11 - z13; /* 2 * c4 */
tmp11 *= 1.414213562f;
z5 = (z10 + z12) * 1.847759065f; /* 2 * c2 */
tmp10 = 1.082392200f * z12 - z5; /* 2 * (c2 - c6) */
tmp12 = -2.613125930f * z10 + z5; /* -2 * (c2 + c6) */
tmp6 = tmp12 - tmp7; /* phase 2 */
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
dataptr[0] = tmp0 + tmp7;
dataptr[7] = tmp0 - tmp7;
dataptr[1] = tmp1 + tmp6;
dataptr[6] = tmp1 - tmp6;
dataptr[2] = tmp2 + tmp5;
dataptr[5] = tmp2 - tmp5;
dataptr[4] = tmp3 + tmp4;
dataptr[3] = tmp3 - tmp4;
dataptr += DCTSIZE;
}
/* Pass 2: process columns. */
dataptr = data;
for (ctr=0; ctr<DCTSIZE; ctr++)
{
/* Even part */
tmp0 = dataptr[DCTSIZE * 0];
tmp1 = dataptr[DCTSIZE * 2];
tmp2 = dataptr[DCTSIZE * 4];
tmp3 = dataptr[DCTSIZE * 6];
tmp10 = tmp0 + tmp2; /* phase 3 */
tmp11 = tmp0 - tmp2;
tmp13 = tmp1 + tmp3; /* phases 5-3 */
tmp12 = tmp1 - tmp3; /* 2 * c4 */
tmp12 *= 1.414213562f;
tmp12 -= tmp13;
tmp0 = tmp10 + tmp13; /* phase 2 */
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
/* Odd part */
tmp4 = dataptr[DCTSIZE * 1];
tmp5 = dataptr[DCTSIZE * 3];
tmp6 = dataptr[DCTSIZE * 5];
tmp7 = dataptr[DCTSIZE * 7];
z13 = tmp6 + tmp5; /* phase 6 */
z10 = tmp6 - tmp5;
z11 = tmp4 + tmp7;
z12 = tmp4 - tmp7;
tmp7 = z11 + z13; /* phase 5 */
tmp11 = z11 - z13; /* 2 * c4 */
tmp11 *= 1.414213562f;
z5 = (z10 + z12) * 1.847759065f; /* 2 * c2 */
tmp10 = 1.082392200f * z12 - z5; /* 2 * (c2 - c6) */
tmp12 = -2.613125930f * z10 + z5; /* -2 * (c2 + c6) */
tmp6 = tmp12 - tmp7; /* phase 2 */
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
dataptr[DCTSIZE * 0] = tmp0 + tmp7;
dataptr[DCTSIZE * 7] = tmp0 - tmp7;
dataptr[DCTSIZE * 1] = tmp1 + tmp6;
dataptr[DCTSIZE * 6] = tmp1 - tmp6;
dataptr[DCTSIZE * 2] = tmp2 + tmp5;
dataptr[DCTSIZE * 5] = tmp2 - tmp5;
dataptr[DCTSIZE * 4] = tmp3 + tmp4;
dataptr[DCTSIZE * 3] = tmp3 - tmp4;
dataptr++; /* advance pointers to next column */
}
}
/* how to use */
static void dcttest(void)
{
float data[64];
int i;
/* FDCT */
fdct2d8x8(data);
for (i=0; i<64; i++) data[i] /= dctfactor[i];
for (i=0; i<64; i++) data[i] /= 8.0f;
/* IDCT */
for (i=0; i<64; i++) data[i] *= dctfactor[i];
idct2d8x8(data);
for (i=0; i<64; i++) data[i] /= 8.0f;
}
#endif
#if 0 /* 矩阵变换版本 */
/* 内部常量定义 */
#define M_PI 3.14159265358979323846f
/* 内部全局变量定义 */
static float fdctmatrix[8][8] = {0}; /* fdct 变换矩阵 */
static float idctmatrix[8][8] = {0}; /* idct 变换矩阵 */
/* 内部函数定义 */
static float c(int u)
{
if (u == 0) return (float)sqrt(1.0f / 8.0f);
else return (float)sqrt(2.0f / 8.0f);
}
/* 初始化 dct 变换矩阵 */
void initdctmatrix(void)
{
static int inited = 0;
int u, x;
/* 避免重复初始化 */
if (inited) return;
/* init fdct matrix */
for (u=0; u<8; u++)
{
for (x=0; x<8; x++)
{
fdctmatrix[u][x] = (float)(c(u) * cos((2.0f * x + 1.0f) * u * M_PI / 16.0f));
}
}
/* init idct matrix */
for (u=0; u<8; u++)
{
for (x=0; x<8; x++)
{
idctmatrix[x][u] = (float)(c(u) * cos((2.0f * x + 1.0f) * u * M_PI / 16.0f));
}
}
inited = 1;
}
/* 1d 8-points forward dct */
void fdct1d8(float *u, float *x)
{
int i;
int j;
for (i=0; i<8; i++)
{
u[i] = 0.0f;
for (j=0; j<8; j++)
{
u[i] += fdctmatrix[i][j] * x[j];
}
}
}
/* 1d 8-points invert dct */
void idct1d8(float *x, float *u)
{
int i;
int j;
for (i=0; i<8; i++)
{
x[i] = 0.0f;
for (j=0; j<8; j++)
{
x[i] += idctmatrix[i][j] * u[j];
}
}
}
/* 2d 8x8 forward dct */
void fdct2d8x8(float *data)
{
float temp[64];
int i, j;
/* 初始化变换矩阵 */
initdctmatrix();
/* 逐行进行 1d fdct */
for (i=0; i<8; i++)
{
fdct1d8(temp + 8 * i, data + 8 * i);
}
/* 转置矩阵 */
for (i=0; i<8; i++)
for (j=0; j<8; j++)
*(data + 8 * i + j) = *(temp + 8 * j + i);
/* 逐行进行 1d fdct */
for (i=0; i<8; i++)
{
fdct1d8(temp + 8 * i, data + 8 * i);
}
/* 转置矩阵 */
for (i=0; i<8; i++)
for (j=0; j<8; j++)
*(data + 8 * i + j) = *(temp + 8 * j + i);
}
/* 2d 8x8 invert dct */
void idct2d8x8(float *data)
{
float temp[64];
int i, j;
/* 初始化变换矩阵 */
initdctmatrix();
/* 逐行进行 1d idct */
for (i=0; i<8; i++)
{
idct1d8(temp + 8 * i, data + 8 * i);
}
/* 转置矩阵 */
for (i=0; i<8; i++)
for (j=0; j<8; j++)
*(data + 8 * i + j) = *(temp + 8 * j + i);
/* 逐行进行 1d idct */
for (i=0; i<8; i++)
{
idct1d8(temp + 8 * i, data + 8 * i);
}
/* 转置矩阵 */
for (i=0; i<8; i++)
for (j=0; j<8; j++)
*(data + 8 * i + j) = *(temp + 8 * j + i);
}
#endif
#if 0 /* 数学表达式版本 */
/* 内部常量定义 */
#define M_PI 3.14159265358979323846f
/* 函数实现 */
static float alpha(int n)
{
if (n == 0) return 1.0f / (float)sqrt(8);
else return 1.0f / 2.0f;
}
void fdct2d8x8(float *data)
{
int u, v;
int x, y, i;
float buf[64];
float temp;
for (u=0; u<8; u++)
{
for (v=0; v<8; v++)
{
temp = 0;
for (x=0; x<8; x++)
{
for (y=0; y<8; y++)
{
temp += data[y * 8 + x]
* (float)cos((2.0f * x + 1.0f) / 16.0f * u * M_PI)
* (float)cos((2.0f * y + 1.0f) / 16.0f * v * M_PI);
}
}
buf[v * 8 + u] = alpha(u) * alpha(v) * temp;
}
}
for (i=0; i<64; i++) data[i] = buf[i];
}
void idct2d8x8(float *data)
{
int u, v;
int x, y, i;
float buf[64];
float temp;
for (x=0; x<8; x++)
{
for (y=0; y<8; y++)
{
temp = 0;
for (u=0; u<8; u++)
{
for (v=0; v<8; v++)
{
temp += alpha(u) * alpha(v) * (data[v * 8 + u]
* (float)cos((2.0f * x + 1.0f) / 16.0f * u * M_PI)
* (float)cos((2.0f * y + 1.0f) / 16.0f * v * M_PI));
}
}
buf[y * 8 + x] = (char)(temp + 0.5);
}
}
for (i=0; i<64; i++) data[i] = buf[i];
}
#endif