1.将图像分为若干个8*8的块
2.对于每个块中的每个值(YCbCr?)转换为整型,并且减去平均值128,再进行DCT运算
temp = 0.0; for (u = 0; u < 8; u++) for (v = 0; v < 8; v++) { temp = 0.0; for (x = 0; x < 8; x++) for (y = 0; y < 8; y++) temp += (double)inblock[x][y] * cos((2 * x + 1)*u*pi / 16)*cos((2 * y + 1)*v*pi / 16); adct[u][v] = temp * c[u] * c[v] / 4; }
我的优化:
double temps[8][8]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { temps[i][j] = cos((2 * i + 1)*j*pi / 16); } } temp = 0.0; for (u = 0; u < 8; u++) for (v = 0; v < 8; v++) { temp = 0.0; for (x = 0; x < 8; x++) for (y = 0; y < 8; y++) temp += (double)inblock[x][y] * temps[x][u] * temps[y][v]; adct[u][v] = temp * c[u] * c[v] / 4; }
3.量化块,将块中每个值除以给定的量化值表中对应的值
//给定的量化值表,可以对其缩放/扩大进行压缩图像质量的控制
int qtbl[8][8] = { 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 };
for (u = 0; u < 8; u++){ for (v = 0; v < 8; v++) { temp1 = adct[u][v]; if (temp1 < 0) { temp1 = -temp1; temp1 += qtbl[u][v] / 2; temp2 = (int)temp1 / qtbl[u][v]; aqant[u][v] = -temp2; } else { temp1 += qtbl[u][v] / 2; temp2 = (int)temp1 / qtbl[u][v]; aqant[u][v] = temp2; } }
}
4.将块改为zigzag顺序
short int zigzag[8][8] = { 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 }; /* change the 8x8 block to zigzag sequence form ZIGZAG扫描*/ for (u = 0; u < 8; u++) for (v = 0; v < 8; v++) zz[zigzag[u][v]] = aqant[u][v];
5.DC值减去最后一个块的DC之差
/* replace DC value of each block as the difference between curent DC and the DC of last block */ tempdc = zz[0]; zz[0] = zz[0] - last_dc_value; last_dc_value = tempdc;
6.