| |
1.读入文件的相关信息
按照上述的JPEG文件数据存储方式,把要解码的文件的相关信息一一读出,为接下来的解码工作做好准备。
参考方法是,设计一系列的结构体对应各个标记,并存储标记内表示的信息。其中图像长宽、多个量化
表和哈夫曼表、水平/垂直采样因子等多项信息比较重要。以下给出读取过程中的两个问题。
1)整个文件的大体结构
JFIF格式的JPEG文件(*.jpg)的一般顺序为:
SOI(0xFFD8)
APP0(0xFFE0)
[APPn(0xFFEn)]可选
DQT(0xFFDB)
SOF0(0xFFC0)
DHT(0xFFC4)
SOS(0xFFDA)
压缩数据
EOI(0xFFD9)
2)字的高低位问题
JPEG文件格式中,一个字(16位)的存储使用的是 Motorola 格式, 而不是 Intel 格式。也就是说, 一个字的
高字节(高8位)在数据流的前面, 低字节(低8位)在数据流的后面,与平时习惯的Intel格式不一样。.
3)读出哈夫曼表数据
a)理论说明
在标记段DHT内,包含了一个或者多个的哈夫曼表。对于单一个哈夫曼表,应该包括了三部分:
l 哈夫曼表ID和表类型
这个字节的值为一般只有四个0x00、0x01、0x10、0x11。
0x00表示DC直流0号表;
0x01表示DC直流1号表;
0x10表示AC交流0号表;
0x11表示AC交流1号表。
l 不同位数的码字数量
JPEG文件的哈夫曼编码只能是1~16位。这个字段的16个字节分别表示1~16位的编码码字在哈夫曼树中的个数。
l 编码内容
这个字段记录了哈夫曼树中各个叶子结点的权。所以,上一字段(不同位数的码字数量)的16个数
值之和就应该是本字段的长度,也就是哈夫曼树中叶子结点个数。
b)举例说明
以下面一段哈夫曼表数据举例说明(数据全部以16进制表示):
11 00 02 02 00 05 01 06 01 00 00 00 00 00 00 00 00
00 01 11 02 21 03 31 41 12 51 61 71 81 91 22 13 32
红色部分(第1字节)为哈夫曼表ID和表类型,其值0x11表示此部分数据描述的是AC交流1号表。
蓝色部分(2~17字节)为不同位数的码字的数量。这16个数值实际意义为:没有1位和4
位的哈夫曼码字;2位和3位的码字各有2个;5位码字有5个;6位和8位码字各有1个;7位码字各有6个;没有9位或以上的码字。
绿色部分(18~34字节)为编码内容。由蓝色部分数据知道,此哈夫曼树有0+2+2+0+5+1+6+1=17个叶子结点,
即本字段应该有17个字节。这段数据表示17个叶子结点按从小到大排列,其权值依次为0、1、11、2、21、3、31、41……
4)建立哈夫曼树
a)理论说明
在读出哈夫曼表的数据后,就要建立哈夫曼树。具体方法为:
1)第一个码字必定为0。
如果第一个码字位数为1,则码字为0;
如果第一个码字位数为2,则码字为00;
如此类推。
2)从第二个码字开始,
如果它和它前面的码字位数相同,则当前码字为它前面的码字加1;
如果它的位数比它前面的码字位数大,则当前码字是前面的码字加1后再在后边添若干个0,直至满足位数长度为止。
b)举例说明
继续以上边的例子说明问题。
n 由于没有1位的码字,所以第一个码字的位数为2,即码字为00;
n 由于2位的码字有两个,所以第二个码字位数仍为2,即码字为00+1=01;
n 第三个码字为3位,比第二个码字长1位,所以第三个码字为:01+1=10,然后再添1个“0”,得100;
n ……
如此类推,最后得到这个哈夫曼树如下:
序号 | 码字长度 | 码字 | 权值 |
1 | 2 | 00 | 0x00 |
2 | 2 | 01 | 0x01 |
3 | 3 | 100 | 0x11 |
4 | 3 | 101 | 0x02 |
5 | 5 | 11000 | 0x21 |
6 | 5 | 11001 | 0x03 |
7 | 5 | 11010 | 0x31 |
8 | 5 | 11011 | 0x41 |
9 | 5 | 11100 | 0x12 |
10 | 6 | 111010 | 0x51 |
11 | 7 | 1110110 | 0x61 |
12 | 7 | 1110111 | 0x71 |
13 | 7 | 1111000 | 0x81 |
14 | 7 | 1111001 | 0x91 |
15 | 7 | 1111010 | 0x22 |
16 | 7 | 1111011 | 0x13 |
17 | 8 | 11111000 | 0x32 |
特别注意的是,如果中间有某个位数的码字缺失,例如没有4位码字,则应该在3位码字加1后,添加“00”补足5位,形成下一个5位码字。
在准备好所有的图片信息后,就可以对图片数据进行解码了。
1)理论说明
分析图像数据流的结构,笔者准备以一个从宏观到微观的顺序为读者详细剖析,即:
数据流à最小编码单元à数据单元与颜色分量。
a) 在图片像素数据流中,信息可以被分为一段接一段的最小编码单元(Minimum Coded Unit,MCU)数据流。
所谓MCU,是图像中一个正方矩阵像素的数据。
矩阵的大小是这样确定的:
查阅标记SOF0,可以得到图像不同颜色分量的采样因子,即Y、Cr、Cb三个分量各自的水平采样因子和垂直采
样因子。大多图片的采样因子为4:1:1或1:1:1。其中,4:1:1即(2*2):(