看了一整天的资料,终于理清一些头绪,并且发现网上流传的一个关于JPEG编码中例子的错误,(只是查表的一个小错误,原理还是正确的)
先将所有用到的表格列出
DC差分系数size编码表
Size Amplitude
0 0
1 -1,1
2 -3,-2,2,3
3 -7~-4,4~7
4 -15~-8,8~15
5 -31~-16,16~31
6 -63~-32,32~63
7 -127~-64,64~127
8 -255~-128,128~255
9 -511~-256,256~511
10 -1023~512,512~1023
11 -2047~-1024,1024~2047
AC系数size编码表
Size Amplitude
1 -1,1
2 -3,-2,2,3
3 -7~-4,4~7
4 -15~-8,8~15
5 -31~-16,16~31
6 -63~-32,32~63
7 -127~-64,64~127
8 -255~-128,128~255
9 -511~-256,256~511
10 -1023~512,512~1023
亮度量化表
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
色度量化表
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
光亮度DC系数差huffman表
类别 | 代码长度 | 代码字 |
0 | 2 | 00 |
1 | 3 | 010 |
2 | 3 | 011 |
3 | 3 | 100 |
4 | 3 | 101 |
5 | 3 | 110 |
6 | 4 | 1110 |
7 | 5 | 11110 |
8 | 6 | 111110 |
9 | 7 | 1111110 |
10 | 8 | 11111110 |
11 | 9 | 111111110 |
色度DC系数差的huffman表
类别 | 代码长度 | 代码字 |
0 | 2 | 00 |
1 | 2 | 01 |
2 | 2 | 10 |
3 | 3 | 110 |
4 | 4 | 1110 |
5 | 5 | 11110 |
6 | 6 | 111110 |
7 | 7 | 1111110 |
8 | 8 | 11111110 |
9 | 9 | 111111110 |
10 | 10 | 1111111110 |
11 | 11 | 11111111110 |
亮度和色度的AC系数的huffman表过于庞大,请参阅其他资料,如需帮助,E2me:zww219@163.com
例如,一个8*8的模块的熵编码的中间格式为:
(DC)(2)(3), (AC) (1,2)(-2), (0,1)(-1), (0,1)(-1), (0,1),(-1) (2,1),(-1).(EOB)(0,0)
被编码为01111(此处很多文章写成11011,是不对的,查表错误),1101101,000,000,000,111000,1010时,先读到011,
每 读取一个bit进行一次huffman码表的扫描,第一个肯定是DC的编码,,,,便可根据 DC亮度Huffman 表,查到size为2,在根据这个size2读取后2位,11,进过VLI反编码,得到幅度为3,这样,就解码出(DC)(2)(3),然后,相继解码出 63个AC系数,这样,组成了一个8*8的模块后,进行逆量化后进行IDCT变换,最后得到第一个元素(Y)的8*8幅值表
以下是引用Ham的空间中的解码过程:http://user.qzone.qq.com/591170887/blog/1197016242
下 面讲解的都是真彩 JPG 的解码, 灰度 JPG 的解码很简单, 因为图形中只有亮度信息. 而彩色图形由 (Y, Cr, Cb) 构成, 前面提到过, Y 通常是每点采样一次, 而 Cr,Cb 一般是 2x2 点采样一次, 当然也有的 JPG 是逐点采样, 或者每两点采样 (横向两点, 纵向一点) 采样系数均被定义成对比最高采样系数的相对值. 一般情况 (即: Y 逐点采样, Cr Cb 每 2x2 点一次) 下: Y 有最高的采样率, 横向采样系数HY=2 纵向采样系数 VY=2; Cb 的横向采样系数 HCb=1, 纵向采样系数 VCb=1;同样 HCr=1, VCr=1
在 Jpeg 里, 8x8 个原始数据, 经过 RLE, Huffman 编码后的一串数据流称为一个
Data Unit (DU) JPG 里按 DU 为单位的编码次序如下:
1) for (counter_y=1;counter_y<=VY;counter_y++)
for (counter_x=1;counter_x<=HY;counter_x++)
{ 对 Y 的 Data Unit 编码 }
2) for (counter_y=1;counter_y<=VCb ;counter_y++)
for (counter_x=1;counter_x<=HCb;counter_x++)
{ 对 Cb 的 Data Unit 编码 }
3) for (counter_y=1;counter_y<=VCr;counter_y++)
for (counter_x=1;counter_x<=HCr;counter_x++)
{ 对 Cr 的 Data Unit 编码 }
按我上面的例子: (HY=2, VY=2 ; HCb=VCb =1, HCr,VCr=1) 就是这样一个次序
YDU,YDU,YDU,YDU,CbDU,CrDU
这些就描述了一块 16x16 的图形. 16x16 = (Hmax*8 x Vmax*8) 这里 Hmax=HY=2
Vmax=VY=2
一个 (Hmax*8,Vmax*8) 的块被称作 MCU (Minimun Coded Unix) 前面例子中一个
MCU = YDU,YDU,YDU,YDU,CbDU,CrDU
如果 HY =1, VY=1
HCb=1, VCb=1
HCr=1, VCr=1
这样 (Hmax=1,Vmax=1), MCU 只有 8x8 大, MCU = YDU,CbDU,CrDU
对于灰度 JPG, MCU 只有一个 DU (MCU = YDU)
JPG 文件里, 图象的每个组成部分的采样系数定义在 SOF0 (FFC0) 标记后
简单说一下 JPG 文件的解码
-------------------------
解码程序先从 JPG 文件中读出采样系数, 这样就知道了 MCU 的大小, 算出整个图象
有几个 MCU. 解码程序再循环逐个对 MCU 解码, 一直到检查到 EOI 标记. 对于每个
MCU, 按正规的次序解出每个 DU, 然后组合, 转换成 (R,G,B) 就 OK 了
没有评论:
发表评论