文件结构
JFIF 文件格式直接使用JPEG标准为应用程序定义的许多标记,因此JFIF格式成了事实上JPEG文件交换格式标准。JPEG的每个标记都是由2个字节组成,其前一个字节是固定值0xFF。每个标记之前还可以添加数目不限的0xFF填充字节(fill byte)。下面是其中的8个标记:
1. SOI 0xD8 图像开始
2. APP0 0xE0 JFIF应用数据块
3. APPn 0xE1 - 0xEF 其他的应用数据块(n, 1~15)
4. DQT 0xDB 量化表
5. SOF0 0xC0 帧开始
6. DHT 0xC4 霍夫曼(Huffman)表
7. SOS 0xDA 扫描线开始
8. EOI 0xD9 图像结束
JPEG定义的标记
Symbol (符号) |
Code Assignment (标记代码) |
Description (说明) |
Start Of Frame markers, non-hierarchical Huffman coding | ||
SOF0 |
0xFFC0 |
Baseline DCT |
SOF1 |
0xFFC1 |
Extended sequential DCT |
SOF2 |
0xFFC2 |
Progressive DCT |
SOF3 |
0xFFC3 |
Spatial (sequential) lossless |
Start Of Frame markers, hierarchical Huffman coding | ||
SOF5 |
0xFFC5 |
Differential sequential DCT |
SOF6 |
0xFFC6 |
Differential progressive DCT |
SOF7 |
0xFFC7 |
Differential spatial lossless |
Start Of Frame markers, non-hierarchical arithmetic coding | ||
JPG |
0xFFC8 |
Reserved for JPEG extensions |
SOF9 |
0xFFC9 |
Extended sequential DCT |
SOF10 |
0xFFCA |
Progressive DCT |
SOF11 |
0xFFCB |
Spatial (sequential) Lossless |
Start Of Frame markers, hierarchical arithmetic coding | ||
SOF13 |
0xFFCD |
Differential sequential DCT |
SOF14 |
0xFFCE |
Differential progressive DCT |
SOF15 |
0xFFCF |
Differential spatial Lossless |
Huffman table specification | ||
DHT |
0xFFC4 |
Define Huffman table(s) |
arithmetic coding conditioning specification | ||
DAC |
0xFFCC |
Define arithmetic conditioning table |
Restart interval termination | ||
RSTm |
0xFFD0~0xFFD7 |
Restart with modulo 8 counter m |
Other marker | ||
SOI |
0xFFD8 |
Start of image |
EOI |
0xFFD9 |
End of image |
SOS |
0xFFDA |
Start of scan |
DQT |
0xFFDB |
Define quantization table(s) |
DNL |
0xFFDC |
Define number of lines |
DRI |
0xFFDD |
Define restart interval |
DHP |
0xFFDE |
Define hierarchical progression |
EXP |
0xFFDF |
Expand reference image(s) |
APPn |
0xFFE0~0xFFEF |
Reserved for application use |
JPGn |
0xFFF0~0xFFFD |
Reserved for JPEG extension |
COM |
0xFFFE |
Comment |
Reserved markers | ||
TEM |
0xFF01 |
For temporary use in arithmetic coding |
RES |
0xFF02~0xFFBF |
Reserved |
JPEG文件由下面的8个部分组成:
(1) 图像开始SOI(Start of Image)标记
(2) APP0标记(Marker)
① APP0长度(length)
②标识符(identifier)
③版本号(version)
④ X和Y的密度单位(units=0:无单位;units=1:点数/英寸;units=2:点数/厘米)
⑤ X方向像素密度(X density)
⑥ Y方向像素密度(Y density)
⑦缩略图水平像素数目(thumbnail horizontal pixels)
⑧缩略图垂直像素数目(thumbnail vertical pixels)
⑨缩略图RGB位图(thumbnail RGB bitmap)
(3) APPn标记(Markers),其中n=1~15(任选)
① APPn长度(length)
②由于详细信息(application specific information)
(4) 一个或者多个量化表DQT(difine quantization table)
①量化表长度(quantization table length)
②量化表数目(quantization table number)
③量化表(quantization table)
(5) 帧图像开始SOF0(Start of Frame)
①帧开始长度(start of frame length)
②精度(precision),每个颜色分量每个像素的位数(bits per pixel per color component)
③图像高度(image height)
④图像宽度(image width)
⑤颜色分量数(number of color components)
⑥对每个颜色分量(for each component)
o ID
o 垂直方向的样本因子(vertical sample factor)
o 水平方向的样本因子(horizontal sample factor)
o 量化表号(quantization table#)
(6) 一个或者多个霍夫曼表DHT(Difine Huffman Table)
①霍夫曼表的长度(Huffman table length)
②类型、AC或者DC(Type, AC or DC)
③索引(Index)
④位表(bits table)
⑤值表(value table)
(7) 扫描开始SOS(Start of Scan)
①扫描开始长度(start of scan length)
②颜色分量数(number of color components)
③每个颜色分量
o ID
o 交流系数表号(AC table #)
o 直流系数表号(DC table #)
④压缩图像数据(compressed image data)
(8) 图像结束EOI(End of Image)
JFIF格式中APP0域的详细结构
偏移 |
长度 |
内容 |
块的名称 |
说明 |
0 |
2 byte |
0xFFD8 |
(Start of Image,SOI) |
图像开始 |
2 |
2 byte |
0xFFE0 |
APP0(JFIF application segment) |
JFIF应用数据块 |
4 |
2 bytes |
|
length of APP0 block |
APP0块的长度 |
6 |
5 bytes |
|
"JFIF"+"0" |
识别APP0标记 |
11 |
1 byte |
|
<Major version> |
主要版本号(如版本1.02中的1) |
12 |
1 byte |
|
<Minor version> |
次要版本号(如版本1.02中的02) |
13 |
1 byte |
|
<Units for the X |
X和Y的密度单位 units=0:无单位 units=1:点数/英寸 units=2:点数/厘米 |
14 |
2 bytes |
|
<Xdensity> |
水平方向像素密度 |
16 |
2 bytes |
|
<Ydensity> |
垂直方向像素密度 |
18 |
1 byte |
|
<Xthumbnail> |
缩略图水平像素数目 |
19 |
1 byte |
|
<Ythumbnail> |
缩略图垂直像素数目 |
|
3n |
|
< Thumbnail RGB bitmap> |
缩略RGB位图(n为缩略图的像素数) |
|
|
|
Optional JFIF extension APP0 marker segment(s) |
任选的JFIF扩展APP0标记段 |
|
…… |
|
…… |
|
|
2 byte |
0xFFD9 |
(EOI) end-of-file |
图像文件结束标记 |
JPEG文件的格式是分为一个一个的段来存储的(但并不是全部都是段),段的多少和长度并不是一定的。只要包含了足够的信息,该JPEG文件就能够被打开,呈现给人们。
JPEG文件的每个段都一定包含两部分一个是段的标识,它由两个字节构成:第一个字节是十六进制0xFF,第二个字节对于不同的段,这个值是不同的。紧接着的两个字节存放的是这个段的长度(除了前面的两个字节0xFF和0xXX,X表示不确定。他们是不算到段的长度中的)。
注意:这个长度的表示方法是按照高位在前,低位在后的,与Intel的表示方法不同。比方说一个段的长度是0x12AB,那么它会按照0x12,0xAB的顺序存储。但是如果按照Intel的方式:高位在后,低位在前的方式会存储成0xAB,0x12,而这样的存储方法对于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的结构(SOI的具体数值清自己察看相关书籍,本文章中将不作重点介绍),但是后面没有段的长度。在文件的最后,有一个EOI(End Of Image)的标识,它的结构和SOI是类似的。它标志着文件的结束。
在这中间,包含了APP0段,DQT段,SOF0段,DHT段,SOS段。有的段的个数是不唯一的,比方说DQT段。我们现在重点地介绍各个段的作用。