表1:
0 ,0 ,1 ,4 ,3 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,6 ,0 ,4 ,5 ,7 ,1 ,2 ,3 ,8 ,
----------------
16 ,0 ,2 ,1 ,2 ,5 ,2 ,4 ,3 ,5 ,6 ,4 ,4 ,5 ,5 ,0 ,0 ,1 ,2 ,3 ,4 ,17 ,0 ,5 ,18 ,33 ,49 ,6 ,65 ,19 ,34 ,81 ,97 ,7 ,113 ,-127 ,20 ,50 ,-111 ,-95 ,-16 ,35 ,66 ,82 ,114 ,-79 ,-63 ,21 ,-126 ,-47 ,-15 ,22 ,51 ,67 ,98 ,8 ,36 ,-110 ,-94 ,-62 ,23 ,52 ,53 ,-93 ,-78 ,
----------------
1 ,0 ,2 ,3 ,1 ,1 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,3 ,4 ,0 ,2 ,5 ,1 ,6 ,7 ,
----------------
17 ,0 ,2 ,2 ,1 ,3 ,2 ,4 ,4 ,4 ,5 ,5 ,1 ,0 ,0 ,0 ,0 ,1 ,2 ,0 ,3 ,17 ,4 ,18 ,33 ,5 ,49 ,19 ,34 ,65 ,81 ,50 ,97 ,-111 ,-95 ,6 ,113 ,-47 ,-16 ,20 ,35 ,51 ,-127 ,-79 ,21 ,66 ,114 ,-63 ,-31 ,-15 ,
----------------
这是成品jpg图片的霍夫曼表
0:是亮度dc表,16:为亮度ac表
1:为色度dc表,17:为色度ac表
---------------
Z型排序后的64个元素,第一个为DC ,后63为AC必须经过RLE变成(a,b)格式。
DC和b必须先经过ALI(可变长度整数变换)变换。就是利用表1把DC和b变成二进制位数加二进制代码的形式。可以表示正负数,负数用补码表示。这个环节还没有霍夫曼变换,不用jpeg文件头的霍夫曼表。只用表1的ALI表,用程序实现转换。这个环节可叫为DC,AC中间格式转换。
下一步才是利用jpeg文件头的霍夫曼表把DC,AC中间转换格式转换为霍夫曼可变比特流。
表二为霍夫曼DC 二进制位数转换表,这个表是书面例子,实际使用时可根据统计变化。如DC变换为中间格式后,统计6位的二进制数最多,就可以把6放在最前面,比如下面的实际例子。我想不统计用书面理论表也可以,只是比特流长些。
表三为霍夫曼AC (0个数+二进制位数)转换表。
比如:
0 ,0 ,1 ,4 ,3 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,6 ,0 ,4 ,5 ,7 ,1 ,2 ,3 ,8 ,
第一位是id 0,表示 亮度DC表
,0 ,1 ,4 ,3 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 这16个数表示 DC ALI转换后的二进制位数:
1位:0, 二位 1个 ,三位4个 。。。
6 ,0 ,4 ,5 ,7 ,1 ,2 ,3 ,8 这是二进制位数
6位的二进制是: 00
0位二进制是:(00+1)X2=010
4位:011
5位:100
。。。。
AC表也是这种原理,只是它转换的数不只是位数,还要加上0的个数。对应实际的表中,也要根据jpeg文件头定义的AC表用程序推算出二进制代码,而不是查理论表。
所以,jpeg压缩是经过两步转换的: 第一步:把DC 和 (a ,b)对中的b VLI 转化为 二进制位数加 二进制代码的中间格式
第二步: DC: 把位数转换为 可变的霍夫曼比特流
AC: 把a 和 b的位数作为一字节c,再把c转化为可变比特流,所以c一定是正数。负号的表示在VLI的二进制代码部分表示,最高位是1表示正数,0表示负数。
规定:所有霍夫曼编码必须从2比特开始,绝对不可能只有一个比特。所以霍夫曼必须从00开始。ALI表从0位开始。而且十进制数0只有位数是0,二进制代码部分没有。AC系数中0是单独用别的方法表示的。
如果要jpeg的理论表感觉也可以,就不用先统计了。表二就是DC的二进制位数霍夫曼,表三是理论上的AC 0个数加二进制位数 霍夫曼表。如果要用此表,特别是AC表,那就很长了,估计有16*16 个。而不是自己统计生成的适用本图片的表格,理论表会多出很多图片中没有的AC系数值。
比如用表2这个理论表的话,jpeg文件中DC直流表就是:
1,2,3,4,5,6,7,8,9,,,,16位数
0,1,5,1,1,1,1,1,1......16个数
0,1,2,3,4,5,6.......15 ALI二进制位数
意思就是:
1位二进制没有,因为必须2位开始
2位1个:00
3位5个:010,011,100,101,110
4位一一11位都是1个。11位后面就没有了。