接上篇学习了JPEG的编码原理,本篇学习JPEG文件压缩数据格式,文章内容主要来自ITU-t81标准,加之个人的理解说明。
一、文件结构
JPEG文件使用JFIF格式作为交换格式标准。如下图所示,JPG文件由各种数据段组成,解码时依次解析段得到原始数据。
二、 压缩数据格式规范的通用方面
从文件结构上看,JPG文件由参赛、标记(Markers)、熵编码数据段的有序集合构成。标记和参数通常依次组织为参数段。由于所有的这些组成部分都用字节对齐的代码表示,所以每个压缩哦数据格式都由8位字节的有序序列组成。对于每个字节,规范定义了最高有效位(MSB)和最低有效位(LSB)。
2.1 构成部分
本小节对压缩数据格式的每个组成部分进行一般性描述。
2.1.1 参数
参数是整型值,指定了编码过程、原图像特征和应用程序可选择的其他特性。参数被分配4-bit、1-byte或者2-byte的码字。除了某些可选的参数组之外,参数编码了关键信息,没有这些信息,没有这些信息,解码器不能正常的重建原始图像。
参数的码字应该分配为指定长度的无符号整型(以位为单位),并赋值为特定的值。
对于长度为2Byte的参数,最高有效字节应在压缩数据的有序字节序中首先出现。长度为4bit的参数始终成对出现,且该参数对应始终以单个字节编码,该参数对的第一个参数应该为字节的高4bit。在所有的16bit、8bit或4bit参数中,MSB在前,LSB在后。总结即参数解析使用大端模式。
2.1.2 标记(Markers)
标记用于识别压缩数据格式的各种结构部分。大部分的标记从包含一组相关参数的标记字段开始;也有些标记是独立的。所有的标记占用2Byte:0xF+规定字段(不等于0x0和0xFF,具体如下表所示)。任何的标记前面都可以可选地加上任意数量的填充字节,这些字节的值应等于0xFF。标记使得解码器能够解析压缩数据并定位其各个部分,而不必解码图像数据的其他片段。
2.1.3 标记分配
任何的标记应该分配2Byte:0xFF+非0x0和0xFF字节。第二个字节如下表定义所指定。*号标记标记代表是独立的标记,不属于某个标记段的开始。
2.1.4 标记段(Marker segment)
一个标记段由标记+相关的标记类型参数序列组成。标记段中第一个参数是2字节的长度。这个长度参数表示标记段中的字节数,包括长度参数(2Byte),不包括开始的标记(2Byte)。由SOF和SOS标记码标识的标记段被称为报头:分别为帧头(the frame header)和扫描头(the scan header)。
2.1.5 熵编码数据段
熵编码数据段包含熵编码过程的数据输出。该段由整数字节组成,无论使用的熵编码算法是哈夫曼编码还是算术编码。
使熵编码段为整数字节的操作如下:对于哈夫曼编码,如果需要,使用1bit来填充压缩数据的结尾,以完成段的最后一个字节;对于算术编码,在终止熵编码段的过程中执行字节对齐。
为了确保熵编码数据段中不出现和标记(Marker)值数据。任何由哈夫曼编码器或算法编码器生成的0xFF字节,或由前述中哈夫曼1bit填充生成的0xFF字节,后跟“填充”零字节。
2.2 语法
在2.2和2.3小节中指定交换格式的语法。就本规范而言,这些语法规范包括:
1、要求提供标记、参数和熵编码数据段;
2、可选或有条件组成部分的标识;
3、每个标记和参数的名称、符号和定义;
4、每个参数的合法值;
5、其他编码器的限制;
2.2和2.3节中的语法图规定了各组成部分的顺序以及可选或有条件的标识。名称、符号、定义、合法值、条件和限制由各个语法指定。
2.3 语法图公约
在图B.2和B.3中的语法属于交换格式规范的一部分,以图B.1中的语法说明表示方法:
parameter/marker indicator: 一个细线框包含一个参数或者一个标记;
segment indicator: 一个粗线框包含一个标记段、熵编码数据段或者两者的组合;
parameter length indicator:细线框的宽度与所包含的标记或参数的参数长度(4、8或16bit,分别如图B.1中的E、B和D所示)成比例;粗线框的宽度没有意义;
ordering: 在交换格式中,图中所示的参数或标记位于其右侧所示的所有参数或标记之前,并位于其左侧所示的全部参数或标记之后;
entropy-coded data indicator:尖括号表示包含的实体已经被熵编码;
2.4 符号、代码长度和值的公约
在B.2和B.3中的每个语法图之后,指定了图中所示每个标记和参数的符号、名称和定义。对于每个参数,长度和允许值也以表格形式指定。
以下约定适用于标记和参数的符号:
a、所有标记符号都有三个大写字母,有些还带有下标。例如:SOI,SOFn;
b、所有参数符号都有一个大写字母,有些还有一个小写字母有些还有下标。例如:Y,Nf,Hi,Tqi;
三、通用顺序和渐进语法
本条款规定了适用于基于顺序DCT、基于渐进DCT和无损操作模式的所有编码过程的交换格式语法。
3.1 高层语法
图B.2规定了本规范中规定的所有非分级编码过程的交换格式的高级组成部分的顺序。
图B.2所示的三个标记的定义如下:
SOI:图像开始标记;标记以交换格式或缩写格式表示的压缩图像的开始。
EOI:图像结束标记;标记以交换格式或缩写格式表示的压缩图像的结束。
RSTm:复位标记;只有当复位使能时,才会将其置于熵编码段之间的条件标记。有8个唯一的复位标记(m=0-7),它们从0到7依次重复,每次扫描从零开始,以提供模8间隔计数。
图B.2的语法顶层规定,非分层交换格式应以SOI标记开始,应包含一个帧,并以EOI标记结束。
图B.2的第二级规定,帧应以帧头开头,并应包含一个或多个扫描。帧头前面可以有一个或更多规范表或3.4小节中规定的其他标记段。如果存在DNL段(见3.5),则应在第一次扫描后立即进行。对于基于DCT的连续无损处理,每个扫描应包含一到四个图像分量。如果扫描中包含两到四个组件,则应在扫描中交错。对于基于渐进DCT的处理,每个图像分量仅部分包含在任何一次扫描中。仅可对分量(其仅包含DC系数数据)的第一扫描进行交织。
图B.2的第三级规定,扫描应以扫描头开始,并应包含一个或多个熵编码数据段。每个扫描头前面可以有一个或多个规范表中的或其他标记部分。如果未启用RST,则只有一个熵编码段(标记为“最后”的段),且不应存在RST标记。如果启用了RST,则熵编码段的数量由图像的大小和RST间隔定义。在这种情况下,除最后一个段外,每一个熵编码段后面都应该有一个RST标记。
图B.2的第四级规定每个熵编码段由一系列熵编码MCU组成。如果RST被启用并且RST间隔被定义为Ri,则除最后一个段外的每个熵编码段应包含Ri个MCU。最后一个应包含完成扫描的全部数量的MCU。
图B.2规定了规范表标记段可能出现的位置。然而,本规范在此规定,交换格式应包含解码压缩图像所需的所有规范表数据。因此,所需的规范表数据应出现在一个或多个允许的位置。
3.2 帧头语法(Frame header syntax)
图B.3规定帧头应该出现在帧数据的开始。这个帧头指明了原图像的特征(see A.1) ,帧的分量和每个分量的采样因子,并指定了检索每个分量使用的量化表的索引。
图B.3中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.2中给出。在表B.2中(以及随后类似的表),值选择用逗号(例如8、12)分割,取值范围包含边界(例如0-3),用破折号分隔。
SOFn: 帧开始标记;标记帧参数的开始。下标n标识编码过程是基线顺序(baseline)、扩展顺序(extended)、渐进(progressive)还是无损(lossless),以及使用哪个熵编码过程。
SOF0: Baseline DCT
SOF1: Extended sequential DCT, Huffman coding
SOF2: Progressive DCT, Huffman coding
SOF3: Lossless(sequential), Huffman coding
SOF9: Extended sequential DCT, arithmetic coding
SOF10: Progressive DCT, arithmetic coding
SOF11: Lossless(sequential), arithmetic coding
Lf: 帧头长度;指定图B.3所示帧头的长度;(see 2.1.4).
P: 采样精度;指定帧中各分量采样的精度(以位为单位)。
Y: 行数,即高度;指定源图像中的最大行数。这应等于具有最大垂直样本数的部件中的线数(见A.1.1)。值0表示高度应在第一次扫描结束时由DNL标记和参数定义(见B.2.5)。
X: 每行采样数,即宽度;指定源图像中每行的最大采样数。这应等于具有最大水平样本数的部件中每行样本数(见A.1.1)。
Nf: 帧所包含的图像分量;指定了帧源图像的颜色分量;Nf的值应该等于帧头中帧分量规范参数的设置数(Ci,Hi,Vi和Tqi);
Ci: 分量标号;为帧分量规范参数指定第i个分量的唯一标签。这些值应用于扫描头中,以识别扫描的分量。Ci值不同于C1值Ci-1的值;
Hi:水平采样因子;指定分量水平尺寸和最大图像尺寸X之间的关系(见A.1.1);还指定了当在扫描中编码多于一个分量时每个MCU中分量Ci的水平数据单元的数量。
Vi:垂直采样因子;指定分量垂直尺寸和最大图像尺寸Y之间的关系(见A.1.1);还指定了当在扫描中编码多于一个分量时每个MCU中分量Ci的垂直数据单元的数量。
Tqi: 量化表选择器;指定使用四个可能的量化表其中之一,从中检索用于分量Ci的DCT系数的反量化的量化表。如果解码过程使用反量化程序,则在解码器准备解码包含分量Ci的扫描时,该表应已部署在解码端。在完成包含Ci的所有扫描之前,不得重新指定或更改其内容。
3.3 扫描头语法(Scan header syntax)
图B.4规定了扫描开始时应出现的扫描头。该头指定扫描中包含哪些分量,指定检索每个分量使用的熵表,以及(对于逐行DCT)扫描中包含DCT量化系数数据的哪部分。对于无损压缩,扫描参数指定预测器和点变换。如果扫描中只有一个图像分量,则根据定义,该分量是非交错的。如果在扫描中存在不止一个图像分量,则根据定义,存在的分量是交错的。
图B.4中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.3中给出。
SOS: 扫描标记开始;标记扫描参数的开始;
Ls: 扫描头长度;指定图B.4所示的扫描头长度;(见B.1.1.4)
Ns: 扫描中的图像分量数量;指定扫描中源图像的色彩分量。Ns的值应该等于扫描头中扫描规范参数的数量(Csj, Tdj和Taj)。
Csj: 扫描分量选择器;选择选择帧参数中指定的Nf图像分量中的哪一个应为扫描中的第j个分量。每个Csj应与帧头(SOF)中指定的Ci值之一相匹配,扫描头中的排序应遵循帧头中的顺序。如果Ns>1,则MCU中交织组件的顺序为Cs1第一,Cs2第二,等等。扫描中包含的图像成分应受到以下限制:
其中Hj和Vj是扫描分量j的水平和垂直采样因子。这些采样因子在分量i的帧头(SOF)中指定,其中i是帧分量标识符Ci与扫描分量选择器Csj匹配的帧分量规范索引。例如,考虑具有3个分量的图像,最大尺寸为512行,每行512个采样,采样因子如下:
然后根据公式求和:Hj x Vj = (4 x 1) + (1 x 2) + (2 x 2) = 10。
Csj的值应与Cs1至Csj–1的值不同。
Tdj: 直流熵编码表选择器;指定4个可能的目标直流熵编码表中的一个,从而检索对分量Csj的DC系数进行解码所需的熵表。在解码器准备解码当前扫描时,DC熵表应已部署在此目的地(见B.2.4.2和B.2.4.3)。此参数指定无损过程的目标熵编码表。
Taj: 交流熵编码表选择器;指定4个可能的目标交流熵编码表中的一个,从而检索对分量Csj的AC系数进行解码所需的熵表。在解码器准备解码当前扫描时,AC熵表应已部署在此目的地(见B.2.4.2和B.2.4.3)。此参数指定无损过程的目标熵编码表。
Ss: 频谱或预测器选择的开始;在DCT操作模式中,该参数以zig-zag字形顺序指定每个块中的第一个DCT系数,该系数应在扫描中进行编码。对于连续DCT过程,此参数应设置为零。在无损操作模式中,此参数用于选择预测器。
Se: 频谱选择的结束;以zig-zag字形顺序指定每个块中的最后一个DCT系数,该系数应在扫描中进行编码。对于连续DCT过程,此参数应设置为63。在无损操作模式下,此参数没有意义。应将其设置为零。
Ah: 逐次逼近比特位高;此参数指定在前一次扫描中使用的点变换(即,在前一扫描中的逐次逼近比特位低),用于由Ss和Se指定的系数带。对于每个系数带的第一次扫描,该参数应设置为零。在无损操作模式下,此参数没有意义。应将其设置为零。
Al: 逐次逼近比特位低;在DCT操作模式中,此参数指定在编码由Ss和Se指定的系数带之前使用的点变换(即低位)。对于连续DCT过程,此参数应设置为零。在无损操作模式下,此参数指定点变换Pt。
熵编码表目的选择器Tdj和Taj指定霍夫曼表(使用霍夫曼编码的帧)或算术编码表(使用算术编码的帧中)。在后一种情况下,熵编码表目标选择器指定目标算术编码训练表和相关的统计区域。
3.4 表规范和各种标记字段语法
图B.5规定,在图B.2所示的位置,3.4.1至3.4.6中规定的任何表的规范段或其他标记段可以以任何顺序出现,且不限制段的数量。
如果任何一个为了特定目的的规范表出现在压缩数据中,那么它应该取代相同目的而指定的之前的规范表,并且,无论何时帧中剩余的扫描或者随后在压缩图像数据的缩略格式中出现的图像指定了这个目的,则都应该使用这个表规范。如果对于一个给定的目的有多于一个的规范表出现在压缩图像数据中,则每一个规范都应该取代前面的规范,即当遇到有相同标号的量化表定义,以最后一个定义为准。量化规范表在一个给定成分的增量式DCT扫描之间不应该发生改变。
3.4.1 量化表规范语法
图B.6指定了定义1个或多个量化表的标记字段,即一个DQT标记段中可以携带一个或多个量化表。
图B.6中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.4中给出。
DQT: 定义量化表标记;标记量化规范表参数的开始。
Lq: 量化表定义字段的长度;指定图B.6中所示的所有量化表参数的长度。(见B.1.1.4)
Pq: 量化表元素精度;指定Qk只的精度。当值为0时,标识Qk值为8bit;当值为1是,标识Qk值为16bit。对于8位样本精度P,Pq应为零。(见2.2节)
Tq: 量化表目标标识符;指定解码器中应部署四个可能量化表之一。
Qk: 量化表元素;指定64个量化表元素中的第k个(即每个量化表为8x8=64个元素,因为JPG按照8x8块编码),其中k是DCT系数zig-zag字形排序中的索引。
表B.4中的值n是DQT标记段中指定的量化表的数量。一旦为特定目的地定义了量化表,它将替换存储在该解码器中的先前定义的表,并且当被引用时,应在当前图像的剩余扫描中以及以压缩图像数据的缩写格式表示的后续图像中使用。如果从未为特定目标定义量化表,那么当在帧头中指定该目标量化表时,结果是不可预测的。基于8位DCT的量化过程不应使用16位精度量化表。
3.4.2 霍夫曼表规范语法
图B.7规定了定义1个或多个霍夫曼表规范的标记段。即一个DHT标记段中可以携带一个或多个霍夫曼表。
图B.7中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.5中给出。
DHT: 定义霍夫曼表标记;标记霍夫曼表定义参数的开始。
Lh: 霍夫曼表定义长度;指定图B.7所示的当前标记字段中所有霍夫曼表参数的长度。(见1.1.4)
Tc: 表类型;0=DC表或无损表,1=AC表。
Th: 霍夫曼表目标标识符;指定解码器中应部署四个可能霍夫曼表之一。
Li: 长度为i的霍夫曼码数量;指定本规范允许的16种(即i∈[0, 15])可能长度中每种长度的霍夫曼代码数。Li是列表BITS的元素。
Vi,j: 与每个霍夫曼代码关联的值;为每个i指定与长度为i的每个霍夫曼代码相关联的值。每个值的含义由霍夫曼编码模型确定。Vi,j是列表HUFFVAL的元素。
表B.5中的值n是DHT标记段中指定的霍夫曼表的数量。值mt是根据第t个霍夫曼表的16个Li(t)参数计算得出,由下式给出:
即mt等于16个Li之和,mt也就是Vi,j的数量。
一旦为特定目的地定义了霍夫曼表,它将替换存储在该解码器中的先前定义的表,并且当被引用时,应在当前图像的剩余扫描中以及以压缩图像数据的缩写格式表示的后续图像中使用。如果从未为特定目标定义霍夫曼表,那么当在帧头中指定该目标霍夫曼表时,结果是不可预测的。
3.4.3 算术调节表规范语法
图B.8指定的标记段定义一个或多个算术编码调节表的规范。这些替代了SOI标记为算术编码过程建立的默认算术编码条件表。
图B.8中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.6中给出。
DCA: 定义算法编码调节表标记;标记算法编码调节标记段定义的开始。
La: 算术编码调节定义长度;指定图B.8所示的所有算术编码调节参数的总长度。
Tc: 表类型;0=DC表或无损表 , 1=AC表
Tb: 算术编码调节表目标标记;指定解码器的四个算术编码条件表可能目的地之一。
Cs: 调节表的值(DC表或者AC表中的值)。每个Tb值后应随附一个Cs值。对于AC调节表,Tc应为1,Cs应包含1到63范围内的Kx值。对于DC(和无损)调节表,Tc应为零,Cs应包含两个4bit的参数U和L。U和L的值应该在范围0<=L<=U<=15,同时Cs的值应该等于L+16*U。
表B.6中的n标识DAC标记段中算术编码调节表的数量。对于DC(和无损)调节表,Tc应为零,Cs应包含两个4位参数U和L。参数L和U是用于DC系数编码和无损编码的算术编码程序中的调节下限和上限。为DCT编码列出的单独值范围1-63是AC系数编码中使用的Kx条件。
3.4.4 重启间隔定义语法
图B.9指定的标记段定义了重启间隔。
图B.9中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.7中给出。
DRI: 定义重启间隔标记;标记定义重启间隔参数的开始。
Lr: 定义重启间隔字段长度;指定图B.9所示的DRI段参数的长度。
Ri: 重启间隔;指定重启间隔中MCU的数量。
重启间隔定义语法在表B.7中,值n是重新启动间隔中MCU的行数。值MCUR是构成扫描中每个组件的一行样本所需的MCU数量。SOI标记禁用重启间隔。一个Ri非零的DRI标记段使能后续扫描的重启间隔处理。Ri等于零的DRI标记段表示禁用后续扫描的重启间隔。
3.4.5 注释语法
图B.10指定了一个注释字段的标记段结构。
图B.10中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.8中给出。
COM: 注释标记。
Lc: 注释段长度;指定图B.10所示的注释段的长度。
Cmq: 注释字节;由应用程序指定的注释内容。
3.4.6 应用数据语法
图B.11指定一个应用数据段的标记段结构。
图B.11中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.9中给出。
APPn: 应用数据标记;标记一个应用数据段的开始。
Lp: 应用数据段长度;指定图B.11所示的应用数据段的长度。(见2.1.4节)
Api: 应用数据字节;由应用指定的数据内容。
APPn段是为应用使用所保留的字段。由于对于不同的应用程序,这些段的定义可能不同,因此在应用程序环境之间交换数据时,应删除这些段。
3.5 定义行数语法
图B.12指定定义行数的标记段。DNL(Define Number of Lines)段提供了一种机制,用于在第一次扫描结束时定义或重新定义帧中的行数(帧头中的Y参数)。指定的值应与第一次扫描中编码的MCU行数一致。如果使用了该段,则该段只能在第一次扫描结束时出现,并且只能在对整数个MCU-rows进行编码之后出现。如果帧头中指定的行数(Y)值为零,则此标记段是必需的。
图B.12中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.10中给出。
DNL: 定义行数标记;标记定义行数段的开始。
Ld: 定义行数段的长度;指定图B.12所示的定义行数段的长度。
NL: 行数;指定图像帧中的行数。(见3.2节中行数定义)
四、分层语法
4.1 高级分层模式语法
B.13规定了分层编码过程交换格式的高级组成部分的顺序。
分层模式语法需要出现在非差分帧之间的DHP标记段。分层模式压缩图像数据可包括EXP标记段和跟随初始非差分帧的差分帧。分层模式下的帧结构与非分层模式下帧结构相同。分层序列中的非差分帧应使用为SOFn标记指定的编码过程之一:SOF0, SOF1, SOF2, SOF3, SOF9, SOF10和SOF11。差分帧应采用以下规定的过程之一:SOF5, SOF6, SOF7, SOF13, SOF14和SOF15。
所有帧的样本精度(P)应保持恒定,并具有与DHP标记段中编码的值相同的值。所有帧的每行样本数(X)不得超过DHP标记段中编码的值。如果DHP标记段中的行数(Y)为非零,则所有帧的行数不得超过DHP标记线段中的值。
4.2 DHP段语法
DHP段定义了完整的帧分层序列的图像分量、大小和采样因子。DHP段应在第一帧之前;单个DHP段将出现在压缩图像数据中。DHP段结构与帧头语法相同,只是使用了DHP标记而不是SOFn标记。3.2中的数字和说明同样适用,但DHP段中的量化表目标选择器参数应设置为零。
4.3 EXP段语法
图B.14规定了EXP段的标记段结构。当(且仅当)需要水平或垂直扩展参考部件时,应存在EXP段。EXP段参数仅适用于图像中的下一帧(应为差分帧)。如果需要,EXP段应为表规范段或帧头之前的其他标记段之一;EXP段不应是扫描头或DHP标记段之前的表规范段或其他标记段之一。
图B.14中所示的标记和参数定义如下。每个参数的尺寸和合法值在表B.11中给出。
EXP: 扩展参考组件标记;标记扩展参考组件段的开始。
Le: 扩展参考组件段的长度;指定扩展参考组件段的长度。
Eh: 水平扩展;如果是1,则参考组件应水平扩展2倍。如果不需要水平扩展,则该值应为零。
Ev:垂直扩展;如果是1,则参考组件应垂直扩展2倍。如果不需要垂直扩展,则该值应为零。
如果需要水平和垂直扩展,Eh和Ev应为1。
五、压缩图像数据的缩写格式
图B.2展示了交换格式的高级组成部分。此格式包括解码所需的所有表规范。如果应用环境提供用于表规范的方法而不是通过压缩图像数据,则可以省略一些或所有的表规范。缺少解码所需的任何表规范数据的压缩图像数据具有缩写格式。
六、表格规范数据的缩写格式
图B.2展示了交换格式的高级组成部分。如果压缩图像数据中不存在帧,则压缩图像数据的唯一目的是传达表规范或 3.4.1、3.4.2、3.4.5 和 3.4.6 中定义的杂项标记段。在这种情况下,压缩图像数据具有表规范数据的缩写格式(见图 B.15)。
七、总结
图B.16和B.17总结了交换格式的组成部分和所有标记段结构的顺序。请注意,在图 B.16中,双线框包含标记段。 在图B.16和B.17中,粗线框仅包含标记(没有段数据)。
EXP段可以与帧头之前的其他表/杂项标记段混合,但不能与DHP段或扫描头之前的表/杂项标记段混合。
标签:编码,定义,标记,--,扫描,指定,JPEG,参数,数据格式 From: https://www.cnblogs.com/hankgo/p/17172044.html