Coder
分类: C/C++
2011-02-28 22:55:11
JPEG文件交换格式
版本 1.02
1992.09.01
Eric Hamilton
C-Cube Microsystems
+1 408 944-6300
Fax: +1 408 944-6314
E-mail:
eric@c3.pla.ca.us
为什么是一个文件交换格式
JPEG文件交换格式是一个允许在各种平台和应用之间交换JPEG比特流的最小的文件格式。这个最小的文件格式不包括TIFF JPEG规范中有的任何的高级特性和任何的特定应用的文件格式。这个简化的格式的唯一目标即是交换JPEG压缩图像,因而也不应该那样做。
JPEG文件交换格式特性
o 使用了JPEG压缩
o 使用JPEG交换格式压缩图像表示
o 兼容PC 或 Mac 或 Unix 工作站
o 标准的颜色空间:一个或三个成分。对于三个成分,则为YCbCr (CCIR 601-256
levels)
o APP0 标记被用于详述单位(Units), X 像素密度, Y 像素密度, thumbnail
o APP0 标记也被用于详述JFIF扩展
o APP0 标记也被用来详述特定应用的信息
JPEG 压缩
尽管JPEG文件交换格式的语法支持所有的JPEG过程,但为了文件交换仍然强烈建议使用JPEG基础过程。这将保证与所有支持JPEG的应用的最大的兼容性。JFIF符合JPEG草案国际标准(ISO DIS 10918-1).
JPEG文件交换格式与标准JPEG交换格式完全兼容;仅有的额外的要求是在SOI标记之后紧接着必须出现APP0标记。注意,JPEG交换格式要求(像JFIF那样)编码过程中使用到的所有的表规范在比特流中的位置要先于使用到它们的位置。
跨平台兼容
JPEG文件交换格式是跨平台兼容的: 比如,它不适用任何的Mac支持而PC或工作站不支持的resource
forks。
标准色彩空间
使用的色彩空间是YCbCr,它由CCIR 601定义(256级)。从YCbCr 到RGB成分的线性转换计算不需要经过伽马校正。如果只使用了一个成分,则其应为Y。
用APP0标记标识JPEG FIF
APP0标记被用来标识一个JPEG FIF文件。JPEG FIF APP0 标记必须紧跟在SOI标记之后。
JFIF APP0是由一个以0结尾的串来确定的:"JFIF"。APP0可被应用程序用于其它的目的,提供它可以与JFIF APP0区分开。
JFIF APP0标记可以提供一些JPEG流中没有的信息:版本号,X和Y像素密度 (点每英寸或点每厘米), 像素长宽比 (得自于X 和Y像素密度), thumbnail.
用APP0标记来详述JFIF扩展
额外APP0标记段可选择性的用来说明JFIF扩展。如果使用了,这些段必须要紧跟在JFIF APP0标记后面。解码器应该跳过所有不支持的JFIF扩展段并继续解码。
JFIF扩展APP0标记用一个以零结尾的串来标识:"JFXX"。JFIF 扩展APP0标记段包含一个用于确认扩展的一字节的代码。本版本,版本1.02,只定义了一个扩展:在格式中额外使用24-bit RGB格式定义缩略图的扩展。
APP0用于特定应用信息
额外的APP0标记可用来包含不影响JFIF文件的可解码性和可显示行的特定应用的信息。特定应用的APP0标记必须在JFIF APP0和所有的JFXX APP0段之后出现。解码器应该跳过所有的无法辨识的特定应用的APP0段。
特定应用的APP0标记可以用一个识别应用的以0结尾的串来标识(担不是"JFIF"或"JFXX")。这个串应该是一个组织的名字或公司的商标。通常情况下,不应该使用dog, cat, tree, etc.这些词。
与RGB的相互转换
R,G,B到Y,Cb,和Cr的转换在CCIR Recommendation 601中定义,但是被规范化了以使其能够处理一个8-bit二进制编码完整的256级。更精确的说即是:
Y = 256 * E'y
Cb = 256 * [ E'Cb ] + 128
Cr = 256 * [ E'Cr ] + 128
E'y,E'Cb和E'Cb在 CCIR 601中定义。由于E'y的范围在0到1.0之间,而E'Cb和E'Cr的范围为-0.5 到 +0.5,当Y,Cb,和Cr为最大值时,他们必须被钳制为255。
RGB到YCbCr的转换
YCbCr (256级)可直接由8-bit RGB按如下方式计算:
Y =
0.299 R +
Cb = -
0.1687 R -
Cr =
0.5 R -
注意 – 不是所有的图象文件格式存储图象数据都是按照顺序R0,G0,B0,... Rn,Gn,Bn。在转换一个RGB文件到JFIF之前,先要改变图象数据的排列顺序。
YCbCr到RGB的
RGB 可直接有YCbCr (256级)按如下方式计算:
R = Y + 1.402 (Cr-128)
G = Y - 0.34414 (Cb-128)
- 0.71414 (Cr-128)
B = Y + 1.772 (Cb-128)
图象方向
在JFIF文件中图象的方向总是自上而下的。这意味着JFIF文件中编码的第一个象素位于图象的左上角,并且,编码的过程是自左至右,自上至下进行的。自上之下的方向被用于完整的图像数据和缩略图。
一个以自下而上的顺序存储象素数据的图像文件到JFIF文件的转换过程一定要包含逆转图像数据行的过程。
成分的空间关系
Spatial Relationship
of Components
Specification of the
spatial positioning of pixel samples within components relative to the samples
of other components is necessary for proper image post processing and accurate
image presentation. In JFIF files, the
position of the pixels in subsampled components are defined with respect to the
highest resolution component. Since
components must be sampled orthogonally (along rows and columns), the spatial
position of the samples in a given subsampled component may be determined by
specifying the horizontal and vertical offsets of the first sample, i.e. the
sample in the upper left corner, with respect to the highest resolution
component.
为了适当的成像后处理和精确的图像显示,特定像素相对于具有其他组分值的像素的空间定位的规范是必须的。在JFIF文件中,二次采样组分中的像素的位置是相对于最高分辨率的组分而定义的。由于组分(components)必须正交的采样(沿行和列), 一个给定的二次采样的组分中的实例的空间位置可能是通过详述其相对于一次采样的水平和竖直偏移来确定的,比如,位于左上角的实例,就最高分辨率组分而言。
在一个二次采样组分中一次采样的水平和垂直偏移,Xoffseti[0,0]和Yoffseti[0,0]被定义为
Xoffseti[0,0] = (
Nsamplesref / Nsamplesi ) / 2 - 0.5
Yoffseti[0,0] = (
Nlinesref / Nlinesi ) / 2 - 0.5
Nsamplesref 是最大组分每行的采样数,
Nsamplesi 是第i个组分每行的采样数,
Nlinesref 是最大组分的行数
Nlinesi 是第i个组分的行数
组分的适当的二次采样包含了一个抗锯齿滤波器,该滤波器可以减小全分辨率组分的光谱带宽。二次采样可以使用一个具有偶数个(系数)对称
Subsampling can
easily be accomplished using a symmetrical digital filter with an even number
of taps (coefficients). A commonly used filter for 2:1 subsampling utilizes two
taps (1/2,1/2).
注意 – 这个定义与Postcript Level 2和QuickTime等工业标准兼容。这个定义与CCIR Recommendation 601-1使用的协议及其他的数字视频格式不兼容。对于这些格式,为了确保压缩图像的精确重新创建,压缩之前色差组分的预处理是必须的。
JPEG文件交换格式规范
JFIF文件的语法与ISO DIS 10918-1的Annex B中定义的交换格式语法一致。 此外,JFIF文件使用APP0标记段,并强制帧头中某一参数具有如下定义。
X'FF', SOI
X'FF', APP0, length, identifier,
version, units, Xdensity,
Ydensity, Xthumbnail,Ythumbnail, (RGB)n
length (2 bytes) APP0总的字节数,包括字节数字段的值
(2 字节),但不包括APP0标记自身
identifier (5 bytes) = X'
以0结尾的串("JFIF")用于识别这个
APP0标记。这个串应该具有零校验(位
7=0)。
version (2 bytes)
= X'0102'
最高有效字节为主修订版本,最低有效
字节为此修订版本版本1.02是当前的
发布版本。
units (1 byte)
X和Y密度的单位
units =
0: 无单位, X和指定了像素
Y的宽高比
units =
1: X和Y指点每英寸
units =
2: X和Y点每厘米
Xdensity (2 bytes)
水平像素密度
Ydensity (2 bytes)
垂直像素密度
Xthumbnail (1 byte) 缩略图水平像素数
Ythumbnail (1 byte) 缩略图垂直像素数
(RGB)n (3n bytes) 缩略图像素的(24-bit)packed RGB值,
n = Xthumbnail * Ythumbnail
[可选的JFIF扩展APP0标记段 – 参见下面内容 ]
o
X'FF', SOFn, length, frame parameters
成分的数量 Nf = 1 or 3
第一个成分 C1 = 1 = Y 成分
第二个成分 C2 = 2 = Cb 成分
第三个成分 C3 = 3 = Cr 成分
o
X'FF', EOI
JFIF扩展APP0标记段
紧跟着JFIF APP0标记段的可能是一个JFIF 扩展APP0标记。这个JFIF
扩展APP0标记段只有在JFIF版本1.02及以上才会出现。JFIF 扩展APP0标记段的语法是:
X'FF', APP0, length, identifier,
extension_code, extension_data
length
(2 bytes) APP0总的字节数,包括字节数字段的值
(2 字节),但不包括APP0标记自身
identifier (5 bytes) = X'
以0结尾的串("JFXX")用于识别这个
APP0标记。这个串应该具有零校验(位
7=0)。
extension_code (1 byte) = 识别扩展的代码。在这个版本中定义了
如下的扩展:
= X'10' 使用JPEG编码缩略图
= X'11' 缩略图使用1字节/像素存储
= X'13' 缩略图使用3字节/像素存储
extension_data (变量)
= JFIF剩余部分的规范
扩展APP0标记段随扩展而变。参见下面的每一扩展的extension_data规范
JFIF扩展:使用JPEG编码缩略图
这个扩展支持使用JPEG压缩缩略图。压缩的缩略图存储于紧跟在extension_code (X'10')后面的extension_data 字段中,并且压缩数据的长度必须要包含在JFIF 扩展APP0标记段的length字段中。
extension_data 字段的语法符合定义在ISO DIS 10918-1的Annex 中的交换格式。但是,不应该出现"JFIF"或"JFXX"标记段。由于在JFIF文件的完整分辨率图像中,extension_data 语法在帧头中包含如下定义的参数:
X'FF', SOI
o
X'FF', SOFn, length, frame parameters
成分的个数 Nf = 1 or 3
第一个成分 C1 = 1 = Y 成分
第二个成分 C2 = 2 = Cb 成分
第三个成分 C3 = 3 = Cr 成分
o
X'FF', EOI
JFIF扩展:缩略图用每像素一字节存储
这个扩展支持缩略图用每像素1字节存储和一个extension_data 字段中的调色板。extension_data 的语法为:
Xthumbnail (1 byte) 缩略图的水平像素数
Ythumbnail (1 byte) 缩略图的垂直像素数
palette (768 bytes) 调色板的24-bit RGB像素值
RGB值定义了每一个8-bit 二进制
码(0 - 255)代表的颜色。
(pixel)n (n bytes) 缩略图像素的8-bit值
n =
Xthumbnail * Ythumbnail
JFIF扩展:缩略图使用三字节每像素存储
这个扩展支持在extension_data字段中,缩略图使用三字节每像素来存储。extension_data语法是:
Xthumbnail (1 byte) 缩略图水平像素数
Ythumbnail (1 byte) 缩略图垂直像素数
(RGB)n (3n bytes) 缩略图像素的packed (24-bit) RGB
值。n = Xthumbnail * Ythumbnail
有用的提示
o 你可以通过查找如下序列来识别一个JFIF文件:X'FF', SOI, X'FF', APP0, <2 字节被跳过>,
"JFIF", X'00。
o 如果你在别处使用APP0,请确保没有串"JFIF"或"JFXX"紧跟在APP0标记后面。
o 如果你不想包含一个缩略图,则设置Xthumbnail = Ythumbnail
= 0.
o 请确保检查特别的APP0字段中的版本号。通常情况下,如果JFIF文件的主版本号与解码器支持的相同,则文件将使可解码的。
o 如果你只是想要指定像素的宽长比则可在特殊APP0字段的units字段中放入0。Xdensity和Ydensity可以被设为需要的宽长比。Xdensity = 1,Ydensity = 1将设置一个1:1的宽长比。Xdensity和Ydensity应该总是非0值。
注:红色的那一段,本人实在是有些读不懂,所以,原文也一并贴出。