JPEG文件格式简单分析

来源:互联网 发布:廊坊友秦网络怎么样 编辑:程序博客网 时间:2024/04/29 02:38

一,JPEG文件格式概述:
      图像和动画的存储方式是一个很重要的问题。幸好我们有了数据压缩,有了JPEG等多种压缩存储图像的文件格式。如果没有图像压缩算法,也许我们的多媒体时代就会晚到来许多年。JPEG图像存储格式是一个比较成熟的图像有损压缩格式,虽然一个图片经过转化为JPEG图像后,一些数据会丢失,但是,人眼是很不容易分辨出来这种差别的。
二,JPEG文件的存储方式:
      JPEG文件的格式是分为一个一个的段来存储的(但并不是全部都是段),段的多少和长度并不是一定的。JPEG文件的每个段都一定包含两部分:一个是段的标识,它由两个字节构成:第一个字节是十六进制0xFF,第二个字节对于不同的段,这个值是不同的。紧接着的两个字节存放的是这个段的长度(除了前面的两个字节0xFF和0xXX,X表示不确定。他们是不算到段的长度中的)。注意:这个长度的表示方法是按照高位在前,低位在后的,与Intel的表示方法不同。比方说一个段的长度是0x12AB,那么它会按照0x12,0xAB的顺序存储。但是如果按照Intel的方式:高位在后,低位在前的方式会存储成0xAB,0x12,而这样的存储方法对于JPEG是不对的。
    介绍一个读取JPEG文件信息的程序,该程序能够读取JPEG文件中包含的段的信息并显示出来。下面是一个JPEG图片的信息片断:
SOI
        APP0    Length: 0x10
        DQT
                DQT [0]:
        8       6       5       8       12      20      26      31
        6       6       7       10      13      29      30      28
        7       7       8       12      20      29      35      60
        7       9       11      15      26      44      50      31
        9       11      19      28      34      56      52      0
        12      18      28      32      61      52      0       46
        25      32      39      57      52      0       60      0
        36      46      39      49      253     50      0       50
        Length: 0x43
        DQT
                DQT [1]:
        9       9       12      24      50      50      50      50
        9       11      13      33      50      50      50      50
        12      13      28      50      50      50      50      50
        24      33      50      50      50      50      50      50
        50      50      50      50      50      50      50      0
        50      50      50      50      50      50      0       50
        50      50      50      50      50      0       50      0
        50      50      50      50      253     50      0       50
        Length: 0x43
        SOF0
                Image Height: 173
                Image Width: 401
                Number of Frame(s): 3
                ****************
                Content ID: 1
                H Factor: 2
                V Factor: 2
                QT ID: 0
                ****************
                Content ID: 2
                H Factor: 1
                V Factor: 1
                QT ID: 1
                ****************
                Content ID: 3
                H Factor: 1
                V Factor: 1
                QT ID: 1
        Length: 0x11
        DHT
                Type: DC TABLE
                ID: 0
        Length: 0x1f
        DHT
                Type: AC TABLE
                ID: 0
        Length: 0xb5
        DHT
                Type: DC TABLE
                ID: 1
        Length: 0x1f
        DHT
                Type: AC TABLE
                ID: 1
        Length: 0xb5
        SOS     Length: 0xc     <-Will Not Process This Seg.
FATAL ERROR: File Structure Does NOT Support.
      在SOS(Start Of Scan)段的后面,就是编码后的一行一行的图像信息。最开始的SOI(Start Of Image)不是一个段,它是文件的开始,它的值也是类似于0xFF,0xXX的结构,但是后面没有段的长度。在文件的最后,有一个EOI(End Of Image)的标识,它的结构和SOI是类似的。它标志着文件的结束。在SOI跟EOI之间,包含了APP0段,DQT段,SOF0段,DHT段,SOS段。有的段的个数是不唯一的,比方说DQT段。

三,JPEG文件中段的介绍:
      APP0段中主要存储的是图片的识别信息(字符串”JFIF/0”)、一些分辨率的信息以及缩略图的信息。在我的实际测试中,发现并不是所有的JPEG文件都有APP0段的,有的仅是有APP2之类的其他段,但是每个文件中肯定是包含APPX的段。
      DQT段的内容是量化表的信息。众所周知,一个颜色可以分为RGB(红、绿、兰)三个分量,这三色光组成了我们可以见到的所有色彩。但是,在JPEG文件中,RGB色彩格式需要先转化为YUV的格式。Y分量代表了亮度信息,UV分量代表了色差信息。相比之下,人眼对于Y分量更为敏感。量化表的作用就是对于一些不需要的量进行去除,这也是JPEG有损压缩损失数据的关键。上面的输出可以看到两个量化表,一个给Y分量,另一个给UV分量。其实,他们也可以共用一个量化表。一个量化的结果如下所示(摘自《JPEG压缩编码标准》):
15    0     -1    0     0     0     0     0
-2    -1    0     0     0     0     0     0
-1    -1    0     0     0     0     0     0
0     0     0     0     0     0     0     0
0     0     0     0     0     0     0     0
0     0     0     0     0     0     0     0
0     0     0     0     0     0     0     0
0     0     0     0     0     0     0     0
我们可以看到,量化后出现了大量的0,这种结果很有利于我们进行下一步的数据压缩的。这里需要强调一点的是,包括量化表在内8x8的块的值是以左上角开始按照Z形来保存量化表8x8的数据的。而不是按照一行一行的保存的。这样做的好处是,能够让实际上相邻的像素点保存后也排列得比较近,便于压缩和编码。
      SOF0段的内容是图像的大小信息,每个像素的位数信息,以及YUV每个分量分别得的采样信息。JPEG文件图像的编码是一个方块一个方块进行的,每块的大小为8x8大小(如果图像不是整数个方块的大小那么就对图像补齐为整数个大小)。简略地说采样信息,就是如何按组记录YUV的信息,即若干个Y方块,若干个U方块,若干个V方块经过量化的数据再次经过编码后组成一组记录,保存在SOS段结束后。
      DHT段的内容是一个重头戏,如果没有它,JPEG压缩效率就不会那么高了。它内部定义的是一个Huffman表,不同的DHT段定义不同的Huffman表,有的是直流量的表,有的是交流量的表。最多的Huffman表有几个呢?YUV各一个,直流交流各一个,因为YUV每个分量都有直流和交流,所以最多时,Huffman表有3x2个,也就是可以有6个DHT段。该文件中有4个DHT表,Y的直流和交流各一个Huffman表,UV合起来直流和交流各一个Huffman表。 
      SOS段的内容是关于YUV每个分量的直流和交流各使用那个Huffman表来编码的。在这个段的后面就是所有压缩后的数据。

 

 

原文地址:http://www.blogjava.net/wilsonny/archive/2005/07/01/7000.aspx