JPEG文件格式介绍
JPEG文件的存储格式有很多种,但最常用的是JFIF格式,即JPEG File Interchange Format。JPEG文件大体可以分为两个部分:
(1)标记码;由两个字节构成,其中,前一个字节是固定值0XFF代表了一个标记码的开始,后一个字节不同的值代表着不同的含义。需要提醒的是,连续的多个0XFF可以理解为一个0XFF,并表示一个标记码的开始。另外,标记码在文件中一般是以标记代码的形式出现的。例如,SOI的标记代码是0XFFD8,即,如果JPEG文件中出现了0XFFD8,则代表此处是一个SOI标记。
(2)压缩数据;一个完整的两字节标记码的后面,就是该标记码对应的压缩数据了,它记录了关于文件的若干信息。
一些典型的标记码,及其所代表的含义如下所示:
SOI,Start Of Image, 图像开始,标记代码为固定值0XFFD8,用2字节表示;
APP0,Application 0, 应用程序保留标记0,标记代码为固定值0XFFE0,用2字节表示;该标记码之后包含了9个具体的字段:
(1)数据长度:2个字节,用来表示(1)--(9)的9个字段的总长度,即不包含标记代码但包含本字段;
(2)标示符:5个字节,固定值0X4A6494600,表示了字符串“JFIF0”;
(3)版本号:2个字节,一般为0X0102,表示JFIF的版本号为1.2;但也可能为其它数值,从而代表了其它版本号;
(4)X,Y方向的密度单位:1个字节,只有三个值可选,0:无单位;1:点数每英寸;2:点数每厘米;
(5)X方向像素密度:2个字节,取值范围未知;
(6)Y方向像素密度:2个字节,取值范围未知;
(7)缩略图水平像素数目:1个字节,取值范围未知;
(8)缩略图垂直像素数目:1个字节,取值范围未知;
(9)缩略图RGB位图:长度可能是3的倍数,保存了一个24位的RGB位图;如果没有缩略位图(这种情况更常见),则字段(7)(8)的取值均为0;
APPn, Application n, 应用程序保留标记n(n=1---15),标记代码为2个字节,取值为0XFFE1--0XFFFF;包含了两个字段:
(1)数据长度,2个字节,表示(1)(2)两个字段的总长度;即,不包含标记代码,但包含本字段;
(2)详细信息:数据长度-2个字节,内容不定;
DQT,Define Quantization Table, 定义量化表;标记代码为固定值0XFFDB;包含9个具体字段:
(1)数据长度:2个字节,表示(1)和多个(2)字段的总长度;即,不包含标记代码,但包含本字段;
(2)量化表:数据长度-2个字节,其中包括以下内容:
(a)精度及量化表ID,1个字节,高4位表示精度,只有两个可选值,0:8位;1:16位;低4位表示量化表ID,取值范围为0--3;
(b)表项,64*(精度取值+1)个字节,例如,8位精度的量化表,其表项长度为64*(0+1)=64字节;
本标记段中,(2)可以重复出现,表示多个量化表,但最多只能出现4次;
SOFO,Start Of Frame, 帧图像开始,标记代码为固定值0XFFC0;包含9个具体字段:
(1)数据长度:2个字节,(1)--(6)共6个字段的总长度;即,不包含标记代码,但包含本字段;
(2)精度:1个字节,代表每个数据样本的位数;通常是8位;
(3)图像高度:2个字节,表示以像素为单位的图像高度,如果不支持DNL就必须大于0;
(4)图像宽度:2个字节,表示以像素为单位的图像宽度,如果不支持DNL就必须大于0;
(5)颜色分量个数:1个字节,由于JPEG采用YCrCb颜色空间,这里恒定为3;
(6)颜色分量信息:颜色分量个数*3个字节,这里通常为9个字节;并依此表示如下一些信息:
(a)颜色分量ID: 1个字节;
(b)水平/垂直采样因子:1个字节,高4位代表水平采样因子,低4位代表垂直采样因子;
(c)量化表:1个字节,当前分量使用的量化表ID;
本标记段中,字段(6)应该重复出现3次,因为这里有3个颜色分量;
DHT,Define Huffman Table定义Huffman表,标记码为0XFFC4;包含2个字段:
(1)数据长度,2个字节,表示(1)--(2)的总长度,即,不包含标记代码,但包含本字段;
(2)Huffman表,数据长度-2个字节,包含以下字段:
(a)表ID和表类型,1个字节,高4位表示表的类型,取值只有两个;0:DC直流;1:AC交流;低4位,Huffman表ID;需要提醒的是,DC表和AC表分开进行编码;
(b)不同位数的码字数量,16个字节;
(c)编码内容,16个不同位数的码字数量之和(字节);
本标记段中,字段(2)可以重复出现,一般需要重复4次。
DRI,Define Restart Interval,定义差分编码累计复位的间隔,标记码为固定值0XFFDD;
包含2个具体字段:
(1)数据长度:2个字节,取值为固定值0X0004,表示(1)(2)两个字段的总长度;即,不包含标记代码,但包含本字段;
(2)MCU块的单元中重新开始间隔:2个字节,如果取值为n,就代表每n个MCU块就有一个RSTn标记;第一个标记是RST0,第二个是RST1,RST7之后再从RST0开始重复;如果没有本标记段,或者间隔值为0,就表示不存在重开始间隔和标记RST;
SOS,Start Of Scan,扫描开始;标记码为0XFFDA,包含2个具体字段:
(1)数据长度:2个字节,表示(1)--(4)字段的总长度;
(2)颜色分量数目:1个字节,只有3个可选值,1:灰度图;3:YCrCb或YIQ;4:CMYK;
(3)颜色分量信息:包括以下字段,
(a)颜色分量ID:1个字节;
(b)直流/交流系数表ID,1个字节,高4位表示直流分量的Huffman表的ID;低4位表示交流分量的Huffman表的ID;
(4)压缩图像数据
(a)谱选择开始:1个字节,固定值0X00;
(b)谱选择结束:1个字节,固定值0X3F;
(c)谱选择:1个字节,固定值0X00;
本标记段中,(3)应该重复出现,有多少个颜色分量,就重复出现几次;本段结束之后,就是真正的图像信息了;图像信息直到遇到EOI标记就结束了;
EOI,End Of Image,图像结束;标记代码为0XFFD9;
另外,需要说明的是,在JPEG中0XFF具有标记的意思,所以在压缩数据流(真正的图像信息)中,如果出现了0XFF,就需要做特别处理了。方法是,如果在图像数据流中遇到0XFF,应该检测其紧接着的字符,如果是:
(1)0X00,表示0XFF是图像流的组成部分;需要进行译码;
(2)0XD9,表示与0XFF组成标记EOI,即,代表图像流的结束,同时,图像文件结束;
(3)0XD0--0XD7,组成RSTn标记,需要忽视整个RSTn标记,即不对当前0XFF和紧接着的0XDn两个字节进行译码,并按RST标记的规则调整译码变量;
(4)0XFF,忽略当前0XFF,对后一个0XFF进行判断;
(5)其它数值,忽然当前0XFF,并保留紧接着此数值用于译码;
需要说明的是,JPEG文件格式中,一个字(16位)的存储使用的是Motorola格式,而不是Intel格式。也就是说,一个字的高字节(高8位)在数据流的前面,低字节(低8位)在数据流的后面,与平时习惯的Intel格式有所不同。这种字节顺序问题的起因在于早期的硬件发展上。在8位CPU的时代,许多8位CPU都可以处理16位的数据,但它们显然是分两次进行处理的。这个时候就出现了先处理高位字节还是先处理低位字节的问题。以Intel为代表的厂家生产的CPU采用先低字节后高字节的方式;而以Motorola,IBM为代表的厂家生产的CPU则采用了先高字节后低字节的方式。Intel的字节顺序也称为little-endian,而Motorola的字节顺序就叫做big-endian。而JPEG/JFIF文件格式则采用了big-endian格式。下面的函数,实现了从intel格式到motolora格式的转换
USHORT Intel2Moto(USHORT val)
{
BYTE highBits = BYTE(val / 256);
BYTE lowBits = BYTE(val % 256);
return lowBits * 256 + highBits;
}
__________________________________________________
JPEG文件由八个部分组成,每个部分的标记字节为两个,首字节固定为:0xFF,当然,准 许在其前面再填充多个0xFF,以最后一个为准。下面为各部分的名称和第二个标记字节的数值,用ultraedit的16进制搜索功能可找到各部分的起始 位置,在嵌入式系统中可用类似的数值匹配法定位。
一、图像开始SOI(Start of Image)标记,数值0xD8
二、APP0标记(Marker),数值0xE0
1、APP0长度(length) 2byte
2、标识符(identifier) 5byte
3、版本号(version) 2byte
4、X和Y的密度单位(units=0:无单位;units=1:点数/英寸;units=2:点数/厘米) 1byte
5、X方向像素密度(X density) 2byte
6、Y方向像素密度(Y density) 2byte
7、缩略图水平像素数目(thumbnail horizontal pixels) 1byte
8、缩略图垂直像素数目(thumbnail vertical pixels) 1byte
9、缩略图RGB位图(thumbnail RGB bitmap),由前面的数值决定,取值3n,n为缩略图总像素 3n byte
三、APPn标记(Markers),其中n=1~15,数值对应0xE1~0xEF
1、APPn长度(length)
2、应用细节信息(application specific information)
四、一个或者多个量化表DQT(difine quantization table),数值0xDB
1、量化表长度(quantization table length)
2、量化表数目(quantization table number)
3、量化表(quantization table)
五、帧图像开始SOF0(Start of Frame),数值0xC0
1、帧开始长度(start of frame length)
2、精度(precision),每个颜色分量每个像素的位数(bits per pixel per color component)
3、图像高度(image height)
4、图像宽度(image width)
5、颜色分量数(number of color components)
6、对每个颜色分量(for each component)
包括:ID、垂直方向的样本因子(vertical sample factor)、水平方向的样本因子(horizontal sample factor) 、量化表号(quantization table#)
六、一个或者多个霍夫曼表DHT(Difine Huffman Table),数值0xC4
1、霍夫曼表的长度(Huffman table length)
2、类型、AC或者DC(Type, AC or DC)
3、索引(Index)
4、位表(bits table)
5、值表(value table)
七、扫描开始SOS(Start of Scan),数值0xDA
1、扫描开始长度(start of scan length)
2、颜色分量数(number of color components)
3、每个颜色分量
包括:ID、交流系数表号(AC table #)、直流系数表号(DC table #)
4、压缩图像数据(compressed image data)
八、图像结束EOI(End of Image),数值0xD9
如果这篇文章帮助到了你,你可以请作者喝一杯咖啡
![](https://img2020.cnblogs.com/blog/938105/202010/938105-20201013171833350-276632012.png)