JPEG是Joint Photographic Experts Group 的缩写,正是这个专家组制定了JPEG标准以及其他静态图片编解码标准。Joint(联合)是指ISO TC97 WG8(计算机与信息处理技术委员会 第8工作组)和CCITT SGVIII两个工作组的联合. 这个专家组在1992年颁布了第一个JPEG标准, ITU在1992年命名为ITU-T Recommendation T.81, ISO/IEC在1994年命名为10918-1
注意JPEG标准仅仅说明定义了codec部分, 也就是图片如何压缩为字节流以及重新解码为图片的过程. 标准没有涉及到文件的存储格式.
JPEG标准的附录B定义了文件格式"JPEG Interchage Format"(JIF), 不过这个文件格式很少被用到, 主要是因为Encoders和Decoders完整实现JIF很困难, 此外这个标准还缺少以下几个方面:
- Color space定义
- Component sub-sampling 限制
- 像素宽高比
因此其他的JPEG文件格式标准陆续出现了.1992年颁布了JPEG File Interchange Format(JFIF),紧接着出现了Exchange image file format(Exif)和ICC color profiles. 这些格式都符合JIF的字节layout,但是又增加了一些不同的markers.在某种程度上说,JFIF是JIF标准的精简版本.
Exif JPEG文件格式主要用在摄像设备上,摄像产业把Exif作为行业的元数据交换格式.由于Exif标准不支持color profiles,所以大部分软件图像编辑软件使用JFIF格式存储JPEG码流.
不论是Exif还是JFIF格式,都遵守JPEG interchange format(JIF),他们都是由JPEG marker和compressed data组成的.下面列出了JPEG的所有marker
表1 JPEG 的marker定义
短名 | 字节码 | Payload | 名称 | Comments |
SOI | 0xFF, 0xD8 | None | Start Of Image | |
SOF0 | 0xFF, 0xC0 | Variable size | Start Of Frame 0 | Baseline DCT-based JPEG, and specifies the width, height, number of components |
SOF2 | 0xFF, 0xC2 | Variable size | Start of Frame 2 | Progressive DCT-based JPEG |
DHT | 0xFF, 0xC4 | variable size | Define Huffman Table(s) | Specifies one or more Huffman tables |
DQT | 0xFF, 0xDB | variable size | Define Quantization Table(s) | Specifies one or more quantization tables |
DRI | 0xFF, 0xDD | 2 bytes | Define Restart Interval | Specifies the interval between RSTn markers, in macroblocks.This marker is followed by two bytes indicating the fixed size |
SOS | 0xFF, 0xDA | variable size | Start of Scan | Start of Scan |
RSTn | 0xFF, 0xDn | None | Restart | Insert every r macroblocks. where r is the restart interval set by a DRI marker. |
APPn | 0xFF, 0xEn | variable size | Application-sepcific | An Exif JPEG file uses an APP1 marker to store metadata; JFIF JPEG file uses an APP0 marker to store JFIF metadata |
COM | 0xFF, 0xFE | variable | Comment | Contains a text comment |
EOI | 0xFF, 0xD9 | none | End of Image |
表2 JPEG Start of Frame marker结构
字段名称 | 长度 | Comments |
标记代码 | 2 bytes | 固定值0xFFC0 |
数据长度 | 2 bytes | SOF marker长度,包括长度自身但不包含标记代码 |
精度 | 1 bytes | 每个样本数据的位数,通常是8位,一般软件都不支持12位和16位 |
图像高度 | 2 bytes | 图像高度,单位:像素 |
图像宽度 | 2 bytes | 图像宽度,单位:像素 |
颜色分量数 | 1 bytes | 灰度级1,YCbCr或YIQ 3,CMYK 4 |
颜色分量信息 | 颜色分量数x3 | 每个颜色分量:1byte分量ID;1 byte水平垂直采样因子;1 byte 当前分量使用的量化表ID |
表3 JPEG Start of Scan
字段名成 | 长度 | Comments |
标记代码 | 2 bytes | 固定值0xFFDA |
数据长度 | 2 bytes | SOS marker长度,包括长度自身 |
颜色分量数 | 1 bytes | 灰度级1, YCbCr或者YIQ 3, CMDK 4 |
颜色分量信息 | 颜色分量数x3 | 每个样色分量:1 byte 颜色分量ID;1 byte直流/交流系数表号 |
压缩图像数据 | 3bytes | |
1 byte | 谱选择开始 固定为0x00 | |
1 byte | 谱选择结束 固定为0x3f | |
1 byte | 谱选择 在basic JPEG中总为00 |
表4 JEPG APP0 应用程序保留标记0
字段名称 | 字段长度 | Comments |
标记代码 marker | 2 bytes | 固定值0xFF, 0xE0 |
数据长度 length | 2 bytes | APP0总长度,不过括marker,但是包括length |
标识符 identifier | 5 bytes | 固定的字符串"JFIF\0" |
版本号 version | 2 bytes | 一般为0x0101或者0x0102 |
像素单位 unit | 1 bytes | 坐标单位,0没有单位; 1 pixel/inch;2 pixel/cm |
水平像素数目 Xdensity | 2 bytes | |
垂直像素数目 YDensity | 2 bytes | |
缩略图水平像素数目 | 1 byte | |
缩略图垂直像素数目 | 1 byte | |
缩略图RGB位图 | 3n bytes | n = Xthumbnail * Ythumbnail, 这是一个24bits/piexl的RGB位图 |
表5 APPn 应用程序保留标记
字段名称 | 字段长度 | Comments |
标记代码 marker | 2 bytes | 固定值0xFFE1 ~ 0xFFEF, n=1~15 |
数据长度 length | 2 bytes | APPn的总长度,不包括marker的2bytes |
详细信息 | (length - 2) bytes | 内容是应用特定的,比如Exif使用APP1来存放图片的metadata,Adobe Photoshop用APP1和APP13两个标记段分别存储了一副图像的副本。 |
表6 DQT Define Quantization Table
字段名称 | 子字段 | 字段长度 | Comments |
标记代码 marker | 2 bytes | 固定值0xFF, 0xDB | |
量化表长度 length | 2 bytes | DQT的总长度,不包括marker的2bytes | |
量化表 | (length-2)bytes | ||
精度及量化表ID | 1 bytes | 高4位:精度,只有两个可选值,0 8bits,1 16bits; 低4位:量化表ID,取值范围为0~3 | |
表项 | 64*(精度+1) bytes |
EOI marker
End of Image, 图像结束marker,一般来说EOI在JPEG文件的末尾处,但是有的JPEG会在EOI之后添加一些内容。
0xFF在JPEG文件中具有标记性的含义,后一个字节则根据不同意义有不同数值,在每个标记码之前还可以添加书目不限的无意义的0xFF填充,也就是说连续的多个0xFF可以理解为一个0xFF,并表示一个标记码的开始。
注意由于compressed data(jpeg压缩数据流)中可能出现0xFF的,为了和marker区分开,就需要特殊处理。具体的做法是在0xFF后添加一个没有意义的0x00。如果在图像数据流中遇到0xFF,检测紧接着的字符,处理规则如下:
1) 0x00,则表示0xFF是图像流的组成部分。
2) 0xD9,则与0xFF共同组成EOI标记,图像流结束,同时图像文件结束。
3) 0xD0~0xD7,则组成RSTn标记,则要忽视真个RSTn标记,即不对当强的0xFF和紧接着的0xDn两个字节进行译码,并按照RST标记的规则调整译码变量。
4) 0xFF,忽视当前的0xFF,对后一个0xFF在做判断
5) 其他数值,则忽视当前的0xFF,并把紧接着的数值用于译码
JFIF - JPEG FILE Interchange Format
JFIF是为了使得JPEG 码流能够在广泛的平台和应用见进行交换的最小文件格式.这个最小文件格式不包括TIFF JPEG标准任何高级特性,以及任何应用特定的文件格式.这种简化格式的初衷就是为了方便JPEG压缩图像的交换.
JFIF语法符合ISO DIS 10918-1附录B中关于交换文件语法的定义.此外,JFIF 使用APP0 marker来实现JFIF特定于JIF的部分
JFIF格式文件的 layout:
- 0xFF, 0xD8 SOI, Start of Image
- 0xFF, 0xE0 APP0, length, identifies, version, units, Xdensity, YDensity, Xthumbnail, Ythunbnail, (RGB)n
- length 2 bytes: 这个APP0域的长度,包括长度字段本身的2 bytes,但是不包括APP0 marker自身
- identifier 5 bytes: 0x4A, 0x46, 0x49, 0x46, 0x00. 字符串"JFIF"
- version 2 bytes: 版本号,一般为0x0102 或者0x0101,也就是1.01或者1.02
- units 1 bytes: 坐标的单位,units=0: 没有单位;units=1: 每英寸一个点;units=2 每厘米一个点
- Xdensity 2 bytes: 水平像素数
- Ydensity 2 bytes: 垂直像素数
- Xthumbnail 1 bytes: Thumbnail水平像素数
- Ythumbnail 1 bytes: Thumbnail垂直像素数
- (RGB)n 3n bytes: 打包的24bits RGB thumbnail像素 n = Xthumbnail*Ythumbnail
- [可选的JFIF扩展APP0 marker段]
- ...
- ...
- 0xFF, 0xCn SOFn(Start of Frame), length, frame paramters
- ...
- ...
- 0xFF, 0xD9 EOI (End of Image)
Exif - Exchange Image File Format
这个标准是Camera产业联合会发布的,主要目的就是设计一种文件格式,方便交换照片文件的metadata
Exif文件的layout
- SOI 0xFF, 0xD8 Start of frame
- APP1 0xFF, 0xE1 Exif Attribute Information
- APP2 0xFF, 0xE2 Flashpix Externsion data
- ...
- APPz 0xFF, 0xEn
- DQT 0xFF, 0xDB
- DHT 0xFF, 0xC4
- DRI 0xFF, 0xDD
- SOF 0xFF, 0xC0(0xFF, 0xC2)
- SOS 0xFF, 0xDA
- Compressed Data
- EOI 0xFF, 0xD9