Skip to main content

3.1.1.1. Frame Header (帧头部)

帧头部的大小可变,最小为 2 字节,最大为 14 字节,具体取决于可选参数。Frame_Header 的结构如下:

+-------------------------+-----------+
| Frame_Header_Descriptor | 1 byte |
+-------------------------+-----------+
| [Window_Descriptor] | 0-1 byte |
+-------------------------+-----------+
| [Dictionary_ID] | 0-4 bytes |
+-------------------------+-----------+
| [Frame_Content_Size] | 0-8 bytes |
+-------------------------+-----------+

表 2: Frame_Header 的结构

3.1.1.1.1. Frame_Header_Descriptor (帧头部描述符)

头部的第一个字节称为 Frame_Header_Descriptor。它描述了哪些其他字段存在。解码此字节足以确定 Frame_Header 的大小。

比特号 (Bit Number)字段名称 (Field Name)
7-6Frame_Content_Size_Flag
5Single_Segment_Flag
4(未使用, unused)
3(保留, reserved)
2Content_Checksum_Flag
1-0Dictionary_ID_Flag

表 3: Frame_Header_Descriptor

在表 3 中,比特 7 是最高位,而比特 0 是最低位。

3.1.1.1.1.1. Frame_Content_Size_Flag (帧内容大小标志)

这是一个 2 位标志(相当于 Frame_Header_Descriptor 右移 6 位),指定是否在头部内提供 Frame_Content_Size(解压缩数据大小)。Frame_Content_Size_Flag 提供 FCS_Field_Size,即根据表 4 Frame_Content_Size 使用的字节数:

Frame_Content_Size_Flag0123
FCS_Field_Size0 或 1248

表 4: Frame_Content_Size_Flag 提供 FCS_Field_Size

当 Frame_Content_Size_Flag 为 0 时,FCS_Field_Size 取决于 Single_Segment_Flag:如果设置了 Single_Segment_Flag,则 FCS_Field_Size 为 1。否则,FCS_Field_Size 为 0;Frame_Content_Size 不提供。

3.1.1.1.1.2. Single_Segment_Flag (单段标志)

如果设置了此标志,则数据必须在单个连续内存段内重新生成。

在这种情况下,将跳过 Window_Descriptor 字节,但 Frame_Content_Size 必须存在。因此,解码器必须分配大小等于或大于 Frame_Content_Size 的内存段。

为了保护解码器免受不合理的内存需求影响,允许解码器拒绝请求超出解码器授权范围内存大小的压缩帧。

为了更广泛的兼容性,建议解码器至少支持 8 MB 的内存大小。这只是一个建议;每个解码器可以根据本地限制自由支持更高或更低的限制。

3.1.1.1.1.3. Unused Bit (未使用比特)

符合此规范版本的解码器不得解释此比特。它可能在将来的版本中用于表示对正确解码帧非必需的属性。符合此规范的编码器必须将此比特设置为零。

3.1.1.1.1.4. Reserved Bit (保留比特)

此比特保留用于某些未来功能。其值必须为零。符合此规范版本的解码器必须确保它未被设置。此比特可能在将来的修订版中用于表示必须解释才能正确解码帧的功能。

3.1.1.1.1.5. Content_Checksum_Flag (内容校验和标志)

如果设置了此标志,则帧末尾将存在 32 位 Content_Checksum。参见上面对 Content_Checksum 的描述。

3.1.1.1.1.6. Dictionary_ID_Flag (字典ID标志)

这是一个 2 位标志(= Frame_Header_Descriptor & 0x3),指示是否在头部内提供字典 ID。它还将此字段的大小指定为 DID_Field_Size:

Dictionary_ID_Flag0123
DID_Field_Size0124

表 5: Dictionary_ID_Flag

3.1.1.1.2. Window Descriptor (窗口描述符)

这提供了有关解压缩帧所需的最小内存缓冲区的保证。此信息对于解码器分配足够的内存很重要。

Window_Descriptor 字节是可选的。当设置 Single_Segment_Flag 时,Window_Descriptor 不存在。在这种情况下,Window_Size 是 Frame_Content_Size,其值可以从 0 到 2^64 - 1 字节(16 ExaBytes)。

比特号 (Bit Number)7-32-0
字段名称 (Field Name)Exponent (指数)Mantissa (尾数)

表 6: Window_Descriptor

最小内存缓冲区大小称为 Window_Size。它由以下公式描述:

windowLog = 10 + Exponent;
windowBase = 1 << windowLog;
windowAdd = (windowBase / 8) * Mantissa;
Window_Size = windowBase + windowAdd;

最小 Window_Size 为 1 KB。最大 Window_Size 为 (1<<41) + 7*(1<<38) 字节,即 3.75 TB。

一般来说,较大的 Window_Size 值往往会提高压缩比,但代价是增加内存使用量。

要正确解码压缩数据,解码器需要分配至少 Window_Size 字节的缓冲区。

为了保护解码器免受不合理的内存需求影响,允许解码器拒绝请求超出解码器授权范围内存大小的压缩帧。

为了提高互操作性,建议解码器支持高达 8 MB 的 Window_Size 值,编码器不生成需要大于 8 MB 的 Window_Size 的帧。这只是一个建议,解码器可以根据本地限制自由支持更高或更低的限制。

3.1.1.1.3. Dictionary_ID (字典ID)

这是一个可变大小的字段,包含正确解码帧所需的字典 ID。此字段是可选的。当它不存在时,由解码器决定使用哪个字典。

Dictionary_ID 字段大小由 DID_Field_Size 提供。DID_Field_Size 直接从 Dictionary_ID_Flag 的值派生。一个字节可以表示 ID 0-255;2 个字节可以表示 ID 0-65535;4 个字节可以表示 ID 0-4294967295。格式为小端。

允许使用大的 4 字节字典 ID 表示小 ID(例如,13),即使效率较低。

在私有环境中,可以使用任何字典 ID。但是,对于在公共空间中分发的帧和字典,必须仔细分配 Dictionary_ID。以下范围保留仅供已在 IANA 注册的字典使用(参见第 7.4 节):

  • 低范围 (low range): <= 32767
  • 高范围 (high range): >= (1 << 31)

Dictionary_ID 的任何其他值都可以通过参与者之间的私人安排使用。

任何提交用于解压缩且引用未注册保留字典 ID 的有效载荷都会导致错误。

3.1.1.1.4. Frame_Content_Size (帧内容大小)

这是原始(未压缩)大小。此信息是可选的。Frame_Content_Size 使用可变数量的字节,由 FCS_Field_Size 提供。FCS_Field_Size 由 Frame_Content_Size_Flag 的值提供。FCS_Field_Size 可以等于 0(不存在)、1、2、4 或 8 字节。

FCS Field Size (字段大小)Range (范围)
0unknown (未知)
10 - 255
2256 - 65791
40 - 2^32 - 1
80 - 2^64 - 1

表 7: Frame_Content_Size

Frame_Content_Size 格式为小端。当 FCS_Field_Size 为 1、4 或 8 字节时,直接读取值。当 FCS_Field_Size 为 2 时,添加 256 的偏移量。允许使用任何兼容的变体表示小大小(例如,18),即使效率较低。