Jpeg文件格式简介
57 是第 6 组的, 实际保存值为 111001 , 所以被编码为 (6,111001)
45 , 同样的操作, 编码为 (6,101101)
23 -> (5,10111)
-30 -> (5,00001)
-8 -> (4,0111)
1 -> (1,1)
前面的那串数字就变成了:
(0,6), 111001 ; (0,6), 101101 ; (4,5), 10111; (1,5), 00001; (0,4) , 0111
;
(2,1), 1 ; (0,0)
括号里的数值正好合成一个字节. 后面被编码的数字表示范围是 -32767..32767. 合成的字节里, 高 4 位是前续 0 的个数, 低 4 位描述了后面数字的位数.
继续刚才的例子, 如果 06 的 huffman 编码为 111000
69 = (4,5) --- 1111111110011001
21 = (1,5) --- 11111110110
4 = (0,4) --- 1011
33 = (2,1) --- 11011
0 = EOB = (0,0) --- 1010
那么最后对于前面的例子表示的 63 个系数 (记得我们将第一个跳过了吗?) 按位流 写入 JPG 文件中就是这样的:
111000 111001 111000 101101 1111111110011001 10111 11111110110 00001 1011 0111 11011 1 1010
DC 的编码
---------
记得刚才我们跳过了每组 64 个数据的第一个吧, DC 就是指的这个数字 (后面 63 个简称 AC) 代入前面的 FDCT 公式可以得到
c(0,0) 7 7
DC = F(0,0) = --------- * sum sum f(x,y) * cos 0 * cos 0 其中 c(0,0) = 1/2
4 x=0 y=0
1 7 7
= --- * sum sum f(x,y)
8 x=0 y=0
即一块图象样本的平均值. 就是说, 它包含了原始 8x8 图象块里的很多能量. (通常 会得到一个很大的数值)
JPEG 的作者指出连续块的 DC 率之间有很紧密的联系, 因此他们决定对 8x8 块的 DC 值的差别进行编码. (Y, Cb, Cr 分别有自己的 DC)
Diff = DC(i) - DC(i-1)
所以这一块的 DC(i) 就是: DC(i) = DC(i-1) + Diff
JPG 从 0 开始对 DC 编码, 所以 DC(0)=0. 然后再将当前 Diff 值加在上一个值上得 到当前值.
下面再来看看上面那个例子: (记住我们保存的 DC 是和上一块 DC 的差值 Diff) 例如上面例子中, Diff 是 -511, 就编码成
(9, 000000000)
如果 9 的 Huffman 编码是 1111110 (在 JPG 文件中, 一般有两个 Huffman 表, 一