一、JPEG文件格式
JPEG文件使用的数据存储方式有多种,最常用的是JPEG文件交换格式(JPEG File Interchange Format, JFIF),JPEG文件大体上分为两部分:标记码(Tag)和压缩数据,遵循JPEG Marker
+ Compressed Data格式
。
1、标记码
标记码由两字节组成,其前一个字节为固定值0xFF,后一个字节则是根据不同的意义有不同的数值。在每个标记码之前还可以添加数量不限的无意义的0xFF填充,也就是说连续多个0xFF可以理解为单个0xFF,表示一个标记码的开始。而在一个完整的两字节的标记码后就是该标记码对应的压缩数据流,记录关于该文件的诸种信息。
Marker名称 | Marker内容 | 说明 | |
---|---|---|---|
SOI | 0xFFD8 | Start Of Image | 图像开始 |
SOF0 | 0xFFC0 | Start Of Frame 0 | 帧图像开始 |
SOF2 | 0xFFC2 | Start of Frame 2 | |
DHT | 0xFFC4 | Define Huffman Table(s) | 定义哈夫曼表 |
DQT | 0xFFDB | Define Quantization Table(s) | 定义量化表 |
DRI | 0xFFDD | Define Restart Interval | 定义差分编码累计复位的间隔 |
SOS | 0xFFDA | Start of Scan | 扫描开始 |
RST0~RST7 | 0xFFD0 ~ 0xFFD7 | Restart | |
APP0~APP15 | 0xFFE0 ~ 0xFFEF | Application-sepcific | 应用程序保留标记,0为JFIF特有部分,1~15支持用户自定义 |
COM | 0xFFFE | Comment | |
EOI | 0xFFD9 | End of Image | 图像结束 |
1、JPEG文件都是以十六进制 '0xFFD8'开始,以'0xFFD9'结束
2、0xFF + 标志数字(1字节) + 数据大小(2字节) + 数据(n字节)
数据大小 (2字节) 是大端顺序表示(Motorola方式),从高字节开始。请注意“数据”包含了数据大小的描述,如果一个标志为:
FF C1 00 0C
则表示标志0xFFC1有0x000C(十进制12)个字节的数据,但是数据的大小 '12' 也包含了记录“数据大小”的字节,所以在0x000C 后面只有10个字节的数据量。
3、由于在JPEG文件中0xFF具有标志性的意思,所以在压缩数据流(真正的图像信息)中出现0xFF,就需要作特别处理。具体方法是,在数据0xFF后添加一个没有意义的0x00。换句话说,如果在图像数据流中遇到0xFF,应该检测其紧接着的字符,如果是
1)0x00,则表示0xFF是图像流的组成部分,需要进行译码;
2)0xD9,则与0xFF组成标记EOI,则图像流结束,同时图像文件结束;
3)0xD0~0xD7,则组成RSTn标记,则要忽视整个RSTn标记,即不对当前0xFF和紧接的0xDn两个字节进行译码,并按RST标记的规则调整译码变量;
3)0xFF,则忽视当前0xFF,对后一个0xFF再作判断;
4)其他数值,则忽视当前0xFF,并保留紧接的此数值用于译码。
SOI(0xFFD8) |
APP0(0xFFE0) |
[APPn(0xFFEn)]可选 |
DQT(0xFFDB) |
SOF0(0xFFC0) |
DHT(0xFFC4) |
SOS(0xFFDA) |
压缩数据 |
EOI(0xFFD9) |