上一篇:jpeg压缩算法学习(1)——离散余弦变换-CSDN博客
ZigZag算法
上一篇学习了离散余弦变换(DCT),像素值在进行离散余弦变换后,大的数值都集中在左上角,例如下面这样:
338 | 145 | -8 | 18 | -7 | 4 | 14 | -14 |
162 | -41 | 3 | 2 | 3 | -1 | -13 | 9 |
-17 | 57 | -2 | -2 | -20 | 16 | 2 | 10 |
41 | 19 | -24 | 31 | -19 | -8 | 4 | -1 |
-59 | 7 | -2 | -32 | 21 | -1 | 6 | -15 |
-19 | 12 | 32 | 0 | -16 | -9 | -15 | 12 |
7 | -12 | -9 | 17 | 5 | 15 | -4 | 0 |
15 | -11 | 10 | 11 | -10 | -13 | 10 | 0 |
称为能力集中(Energy Compaction),这为有损压缩提供可能性,就是将右下角数值小的部分舍弃掉。
ZigZag算法目的是将离散变换后的二维数组转成一维数组,且将大数值(高能力)放在一维数组前面,小数值(低能力)放在一维数组末尾,方便后面进行霍夫曼编码。
为了达到这个目的,可以按下面的顺序来存放数值:
代码
const char ZigZag[64] =
{
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
};
int zigZagIndex = ZigZag[v * 8 + u]; // u指像素矩阵的列,v指行
fdc_data[zigZagIndex] = (short) ((short)(temp + 16384.5) - 16384);
以上代码来自github上的开源项目: https://github.com/thejinchao/jpeg_encoder.git