PDF 的流对象和过滤器学习
PDF 的官方文档 (https://opensource.adobe.com/dc-acrobat-sdk-docs/pdflsdk/#pdf-reference),版本为 1.5,3.2.7 和 3.3 小节
一、流对象 (Stream Objects)
流对象 (Stream Objects) 和字符串对象一样,是一个字节 (bytes) 序列。PDF 应用程序可以增量读取流,而字符串须完整读取,此外,流的长度没有限制,而字符串的长度是有限制的,正因此,具有潜在大量数据的对象被表示为流,例如 images 和 page 描述。
一个流由一个字节序列字典组成,位于 strem
和 endstream
之间 0 个或多个字节
dictionary
stream
... Zero or more bytes...
endstream
所有流必须是间接对象 (参见文档中第 3.2.9 节 "Indirect Objects"),流中的字典为直接对象,字典后面的 stream 应该跟一个行结束标记,该标记由回车和换行或仅换行组成,而不是单独跟一个回车。组成流的字节序列位于 stream
和 endstream
之间,流字典指定了确切的字节数,建议在数据之后和 endstream
之前有一个行结束标记,该标记不包括在流长度中。
注:如果不限制在 stream
后面单独使用回车符,就无法区分使用回车符作为行尾标记并将换行符作为第一个数据字节流与使用回车-换行序列表示行尾的流
下表列出了流字典中所有通用的字段,某些类型的流可以具有附加的字典段,如在哪里描述这些流所指示的,关于流的过滤器的可选字段指示在使用流中的数据之前是否以及如何对其进行转换 ("解码"),过滤器在后面会有进一步的描述。
每个流字典都有一个 Length 字段,表示 PDF 文件中当前流中有多少个字节,如果流有一个过滤器,Length 是编码数据的字节数。此外,大多数过滤器都被定义为数据是自限制的,也就是说,它们使用一种编码方案,其中显式数据结束 (end-of-data,EOD) 标记界定数据的范围,最后,流用于表示许多对象,从这些对象的属性可以推断出长度,所有这些约束必须是一致的。
例如,使用单个颜色分量和每个分量 8 位的具有 10 行 20 列的图像正好需要 200 个字节的图像数据。如果流使用过滤器,则 PDF 文件中必须有足够字节的编码数据来产生这 200 个字节,如果 Length 太小,显示 EOD 标记出现得太快,或者如果解码的数据不包含 200 个字节,则会发生错误。
如果流包含的数据太多,这也是一个错误,但 PDF 文件中 endstream
之前可能有一个额外的行尾标记。
二、过滤器 (Filters)
上一小节简单提到了流过滤器,过滤器是流规范的可选部分,表示流在使用之前必须进行解码。例如,如果流具有 ASCIIHexDecode 过滤器,一个读取该流中数据的应用程序将把流中的 ASCII 十六进制编码数据转为二进制数据。
生成 PDF 文件的应用程序可以对某些信息 (例如采样图像的数据) 进行编码,以对其进行压缩或将其转换为可移植的 ASCII 表示。然后,读取 PDF 文件的应用程序可以调用相应的解码过滤器,将信息转换回其原始形式。
流的过滤器由字典中的 filter 字段指定 (如果流是外部的,则由 FFilter 字段指定),过滤器可以级联以形成一个管道,使流按顺序通过两个或多个解码转换,例如,使用 LZW 和 ASCII base-85 编码 (按顺序) 编码的数据可以使用字典中的以下字段进行编码:
/Filter [/ASCII85Decode /LZWDecode]
一些过滤器可能采用参数来控制其操作方式,这些可选参数由流字典中的 DecdoeArms 字段指定 (如果流是外部的,则由 FDecodeParms 字段指定),PDF 支持一组标准的过滤器,可分为两大类:
- ASCII 过滤器能够对编码 ASCII 文本的任意 8 位二进制数据进行解码,请注意,ASCII 过滤器在加密的 PDF 文件中没有任何用途;
- Decompression 过滤器能够对已压缩的数据进行解码,压缩数据始终是 8 位二进制格式,即使原始数据恰好是 ASCII 文本。压缩对大采样图像特别有价值,因为它减少了存储要求和传输空间,请注意,某些类型的压缩是有损耗的,这意味着在编码过程中会丢失一些数据,导致数据解压缩时质量下降,不发生数据丢失的压缩称为无损压缩。
下表中总结了标准过滤器,还指出了它们是否接受任何可选参数。以下部分更详细地描述了这些过滤器及其参数 (如果有的话),包括一些过滤器的编码算法规范。
2.1 ASCIIHexDecode 过滤器
ASCIIHexDecode 过滤器对以 ASCII 十六进制形式编码的数据进行解码,ASCII 十六进制编码和 ASCII base-85 编码将二进制数据 (例如 image 数据) 转换为 7 位 ASCII 字符。一般来说,ASCII base-85 编码优于 ASCII 十六进制编码,因为它更紧凑,它将数据扩展为 4:5 的倍数,而 ASCII 十六进制编码为 1:2。
对于每对 ASCII 十六进制数字 (0 – 9、A – F、a – f),ASCIIHexDecode 过滤器会生成一个字节的二进制数据。所有空白字符都将被忽略。右尖括号字符 > 表示 EOD,任何其他字符都会导致错误。如果过滤器在读取奇数个十六进制数字后遇到 EOD 标记,就像最后一个数字后面跟着 0 一样。
2.2 ASCII85Decode 过滤器
ASCII85Decode 过滤器对以 ASCII base-85 编码的数据进行解码并生成二进制数据,以下描述了以 ASCII base-85 编码二进制数据的过程,ASCII85Decode 过滤器反转此过程。
ASCII base-85 编码使用字符 ! 通过 u 和字符 z,以 2 字符序列 ~> 作为其 EOD 标记。ASCII85Decode 过滤器忽略所有空白字符。任何其他字符,以及在 ASCII base-85 编码中表示不可能组合的任何字符序列,都将导致错误。
具体来说,ASCII base-85 编码为每 4 个字节的二进制数据生成 5 个 ASCII 字符,每组 4 个二进制输入字节 (\(b_1b_2b_3b_4\)) 被转换为一组 5 个输出字节 (\(c_1c_2c_3c_4c_5\)),使用以下关系:
\((b_1 * 256^3) + (b_2 * 256^2) + (b_3 * 256^1) + b_4 = (c_1 * 85^4) + (c_2 * 85^3) + (c_3 * 85^2) + (c_4 * 85^1) + c_5\)
换句话说,4 个字节的二进制数据被解释为 base-256 数字,然后转换为 base-85 数字。通过在每个数字上添加 33 (字符的 ASCII 代码),将 base-85 的五个数字转换为 ASCII 字符。生成的编码数据仅包含代码范围为 33 (!) 到 117 (u) 的可打印 ASCII 字符。作为一种特殊情况,如果五个数字全部为 0,则用代码 122 (z) 的字符表示,而不是用五个感叹号 (!!!!!) 表示。
如果要编码的二进制数据的长度不是 4 的倍数,则最后一个 4 的部分组用于生成最后一个 5 个输出字符的部分组。给定 n (1、2 或 3) 个字节的二进制数据,编码器首先附加 4−n 个零字节以形成一个完整的 4 字节组。然后它以通常的方式对该组进行编码,但不应用特殊的 z 情况。最后,它只写入生成的 5 个字符组的前 n + 1 个字符。这些字符后面紧跟 ~>EOD 标记。
以下情况 (在正确编码的字节序列中永远不会出现) 将在解码过程中导致错误:
- 一组 5 个字符表示的值大于 \(2^{32} - 1\);
- z 字符出现在组的中间;
- 最后的部分组仅包含一个字符;
2.3 LZWDecode 和 FlateDecode 过滤器
LZWDecode 和 FlateDecode 过滤器有很多共同点,因此本节将一起讨论,它们分别对使用 LZW 或 Flate 数据压缩方法编码的数据进行解码。
- LZW (Lempel-Ziv-Welch) 是一种可变长度的自适应压缩方法,已被采用为标签图像文件格式 (TIFF) 标准中的标准压缩方法之一。 下一节将详细介绍 LZW 编码;
- Flate 方法基于公开的 zlib/deflate 压缩方法,它是一种与 Huffman 编码级联的变长 Lempel-Ziv 自适应压缩方法,在 Internet RFC 1950、ZLIB 压缩数据格式规范和 1951、DEFLATE 压缩数据格式规范中得到了完整定义。
这两种方法都压缩二进制数据或 ASCII 文本,但 (与所有压缩方法一样) 总生成二进制数据,即使原始数据是文本。
LZW 和 Flate 压缩方法可以发现和利用输入数据中的许多模式,无论数据是文本还是图像。两个过滤器都支持通过预测函数进行的可选变换,这改进了采样图像数据的压缩。由于其级联自适应 Huffman 编码,对于相同输入,Flate 编码输出通常比 LZWencoded 输出紧凑得多。Flate 和 LZW 解码速度相当,但 Flate 比 LZW 编码慢得多。
Flate 和 LZW 编码通常都会对其进行实质性压缩,然而在最坏的情况下 (没有一对相邻字符出现两次),Flate 编码将其输入扩展不超过 11 个字节或 1.003 倍 (以较大者为准),加上 PNG 预测器添加的算法标签的影响,对于 LZW 编码,最好的情况 (全零) 为长文件提供接近 1365:1 的压缩,但最坏情况的扩展至少是 1.125 倍,在某些实现中可以增加到接近 1.5 (加上与 Flate 编码一样的 PNG 标签的影响)。
2.3.1 LZW 编码的细节
使用 LZW 压缩方法编码的数据由 9 至 12 位长的代码序列组成,每个代码表示输入数据的单个字符 (0–255)、清除表标记 (256)、EOD 标记 (257) 或表示先前在输入中遇到的多字符序列的表条目 (258 或更大)。
最初,代码长度为 9 位,LZW 表仅包含 258 个固定代码的条目。随着编码的进行,条目被附加到表中,将新代码与越来越长的输入字符序列相关联,编码器和解码器维护该表的相同副本。
每当编码器和解码器独立 (但同步) 意识到当前代码长度不再足以表示表中的条目数时,它们会将每个代码的位数增加 1。第一个输出代码为 10 位长是创建表条目 511 之后的位长,对于 11 (1023) 和 12 (2047) 位也类似。代码永远不会超过 12 位,因此条目 4095 是 LZW 表的最后一个项。
编码器执行以下步骤序列来生成每个输出代码:
- 累积与表中已存在的序列匹配的一个或多个输入字符的序列,为了最大程度地压缩,编码器会寻找最长的此类序列;
- 发出与该序列对应的代码;
- 为第一个未使用的代码创建一个新表条目,它的值是在步骤 1 中找到的序列,后跟下一个输入字符;
例如,假设输入由以下 ASCII 字符代码序列组成:
45 45 45 45 45 65 45 45 45 66
从空表开始,编码器按表 3.6 所示进行
代码被打包成连续的比特流,高位在前。然后该流被分为 8 位字节,高位在前。因此,代码可以任意跨越字节边界。在 EOD 标记 (代码值 257) 之后,最后一个字节中的任何剩余位都设置为 0。
在上面的例子中,所有的输出代码都是 9 位长,它们将按如下方式打包为字节 (以十六进制表示):
80 0B 60 50 22 0C 0C 85 01
为了适应不断变化的输入序列,编码器可以在任何时候发出可清除的代码,这使得编码器和解码器都以初始表和 9 位代码长度重新启动。按照惯例,编码器首先发出一个清表代码。当表已满时,必须发出清表代码,它可能会更快这样做。
注意:LZW 压缩方法是 Unisys Corporation 拥有的美国专利号 4,558,302 和相应外国专利的主题。Adobe Systems 已授权该专利用于其 Acrobat 产品; 然而,独立软件供应商 (ISV) 可能需要直接从 Unisys 获得该专利许可,才能开发使用 LZW 方法压缩 PDF 文件中数据的软件。
2.3.2 LZWDecode 和 FlateDecode 参数
LZWDecode 和 FlateDecode 过滤器接受可选参数来控制解码过程,这些参数中的大多数都与减少压缩采样图像大小的技术相关。例如,图像数据在不同样本之间通常变化很小,减去相邻样本的值 (称为求差的过程),并对差异而不是原始样本值进行编码,可以减少输出数据的大小。此外,当图像数据每个样本包含多个颜色分量 (红-绿-蓝或青-品红-黄-黑) 时,取相邻样本中相应分量的值之间的差,而不是同一样本中不同颜色分量之间的差,通常会减少输出数据的大小。
表 3.7 显示了可以选择为 LZWDecode 和 FlateDecode 过滤器指定的参数。除非另有说明,提供给解码过滤器的任何可选参数的所有值都必须与数据编码时使用的值匹配。
2.3.3 LZW 和 Flate Predictor 函数
如果 LZW 和 Flate 编码的输入数据高度可预测,那么它们的压缩效果会更紧凑。提高许多连续色调采样图像的可预测性的一种方法是用每个样本与应用于较早相邻样本的预测函数之间的差异来替换该样本。如果 Predictor 函数运行良好,则预测后数据将向 0 聚集。
支持两组 Predictor 函数,第一个是 TIFF 组,由 TIFF 标准中的 Predictor 2 单一函数组成 (在 TIFF 标准中,Predictor 2 仅适用于 LZW 压缩,但这里也适用于 Flate 压缩) TIFF Predictor 2 预测样本的每个颜色分量将立即与样本的相应颜色分量相同,从而它的左边。
第二组受支持的 predictor 函数 PNG 组由万维网联盟的便携式网络图形推荐的过滤器组成,记录在 Internet RFC 2083,PNG (便携式网络图形) 规范中。这里使用术语预测器而不是过滤器以避免混淆,有五种基本的 PNG predictor 算法 (还有第六种算法为每行单独选择最佳 predictor 函数):
要使用的 predictor 算法 (如果有) 由 predictor 过滤器参数指示 (参见表 3.7),该参数可以具有表 3.8 中列出的任何值。
对于 LZWDecode 和 FlateDecode,predictor 值大于或等于 10 仅表示正在使用 PNG predictor,使用的特定 predictor 在输入数据中显式编码。如果解码过滤器提供的 Predictor 值都大于或等于 10,则它们不需要与数据编码时使用的值匹配。
两组 predictor 函数有一些共同点,两者均假设以下条件:
- 数据按从顶行到底行的顺序显示,并且在一行内从左到右;
- 一行占用整数个字节,如有必要,将进行四舍五入;
- 样本及其组件按照从高位到低位的顺序打包成字节;
- 图像外部样本的所有颜色分量 (边界附近的预测所必需的) 均为 0,predictor 函数组也有显着差异;
- 每个 PNG 预测行的预测后数据以显式算法标记开始,因此可以使用不同的算法预测不同的行,以提高压缩率,TIFF Predictor 2 没有此类标识符,相同的算法适用于所有行;
- TIFF 函数组根据每个颜色分量的先前实例来预测该分量,同时考虑每个分量的位数和每个样本的分量数。相比之下,PNG 函数组将数据的每个字节预测为一个或多个先前图像样本的相应字节的函数,无论一个字节中是否存在多个颜色分量,或者单个颜色分量是否跨越多个字节。这可以显着提高速度,但代价是压缩效果稍差;
2.4 RunLengthDecode 过滤器
RunLengthDecode 过滤器根据运行长度对以简单的面向字节格式编码的数据进行解码。编码的数据是一个运行序列,其中每个运行由一个长度字节和 1 到 128 字节的数据组成。如果长度字节在 0 到 127 的范围内,则在解压缩期间将按字面顺序复制以下长度 +1 (1 到 128) 个字节。如果长度在 129 到 255 的范围内,则在解压缩期间,以下单个字节将被复制 257− 长度 (2 到 128) 次。长度值 128 表示 EOD。通过游程编码实现的压缩取决于输入数据。在最好的情况下(全为零),长文件的压缩率约为 64:1。最坏的情况 (十六进制序列 00 与 FF 交替)导致 127:128 的扩展。
2.5 CCITTFaxDecode 过滤器
CCITTFaxDecode 过滤器对使用第 3 组或第 4 组 CCITT 传真 (fax) 编码进行编码的图像数据进行解码。CCITT 编码旨在以相对较低的分辨率实现单色 (每像素 1 位) 图像数据的高效压缩,因此仅适用于位图图像数据,不适用于彩色图像、灰度图像或一般数据。
CCITT 编码标准由国际电信联盟 (ITU) 定义,该联盟以前称为 Comité Consultatif International Téléphonique et Télégraphique (国际电话和电报协调委员会)。这里不详细描述编码算法,但可以在 ITU 建议 T.4 和 T.6 中找到。由于历史原因,我们将这些文档称为 CCITT 标准。
CCITT 编码是面向位的,而不是面向字节的。这意味着,原则上,编码或解码的数据可能不会以字节边界结束。该问题通过以下方式处理:
- 未编码的数据被视为完整的扫描线,在每条扫描线的末尾插入未使用的位以填充最后一个字节,这与采样图像数据的 PDF 约定兼容;
- 编码数据通常被视为连续、不间断的比特流,EncodedByteAlign 参数可用于使每个编码扫描线填充到字节边界,尽管 CCITT 标准没有规定这一点,并且传真机也不会这样做,但某些软件包发现以这种方式编码数据很方便;
- 当过滤器到达 EOD 时,它总是跳到编码数据后面的下一个字节边界;
如果 CCITTFaxDecode 过滤器遇到编码不正确的源数据,则会发生错误。过滤器不会执行任何纠错或重新同步,除非表 3.9 中的 DamagedRowsBeforeError 参数注明。表 3.9 列出了可用于控制解码的可选参数,除非另有说明,否则提供给解码过滤器的所有值 这些参数中的任何一个都必须与数据编码时使用的参数相匹配。
使用 CCITT 编码实现的压缩取决于数据以及各种可选参数的值。对于 Group 3 一维编码,在最好的情况下 (全零),每条扫描线压缩为 4 字节,压缩因子取决于扫描线的长度。如果扫描线长 300 字节,则可实现大约 75:1 的压缩比。最坏的情况,即 1 和 0 交替出现的图像,会产生 2:9 的扩展。
2.6 JBIG2Decode 过滤器
JBIG2Decode 过滤器对使用 JBIG2 编码进行编码的单色(每像素 1 位)图像数据进行解码。JBIG 代表联合双层图像专家组,是国际标准化组织 (ISO) 内开发该格式的一个小组。JBIG2 是最初作为 JBIG1 发布的标准的第二个版本,在本书出版时即将获得标准批准。
JBIG2 编码提供有损和无损压缩,仅适用于单色图像,不适用于彩色图像、灰度图像或一般数据。编码器使用的算法,以及格式的细节,这里不再描述,JBIG2 规范的工作草案可以通过 JBIG 和 JPEG (联合图像专家组) 委员会的网站 http://www.jpeg.org 找到。
一般来说,JBIG2 提供比现有 CCITT 标准好得多的压缩,它实现的压缩很大程度上取决于图像的性质,包含任何语言文本的页面图像的压缩效果都特别好,对于满文本的页面,典型的压缩比为 20:1 到 50:1。JBIG2 编码器构建图像中找到的唯一符号位图表,并且稍后在图像中找到的其他符号与该表进行匹配。匹配的符号由表中的索引替换,无法匹配的符号将添加到表中,表本身是使用其他方式压缩的,对于经常重复相同符号的文档,这会产生高压缩比,这对于扫描文本页面创建的图像来说是典型的情况。这种方法还导致图像中空白的高度压缩,不需要编码,因为它不包含符号。
虽然文本图像可以实现最佳压缩,但 JBIG2 标准还包括用于压缩包含抖动半色调图像 (例如照片) 的图像区域的算法。
JBIG2 压缩方法还可用于将多个图像编码为单个 JBIG2 比特流。通常,这些图像将是多页文档的扫描页面,由于使用单个符号位图表来匹配多个页面上的符号,因此与使用 JBIG2 单独编码每个页面相比,这种类型的编码可以产生更高的压缩比。
一般来说,图像可以在 PDF 中指定为图像 XObject 或内联图像,但是,JBIG2Decode 过滤器只能应用于图像 XObject。
该过滤器通过将每个 JBIG2 页面表示为 PDF 图像来处理单页和多页 JBIG2 位流,如下所示:
- 该过滤器使用 JBIG2 的嵌入式文件组织 (ISO 规范的附件中提供了此文件组织和其他类型的文件组织的详细信息) 规范中提到的可选 2 字节组合(标记)在 PDF 中未使用,随机访问组织中的 JBIG2 比特流应转换为嵌入式文件组织,顺序组织中的比特流不需要重新组织,除了下面描述的映射之外;
- PDF 中不使用 JBIG2 文件头、页尾段和文件尾段,在创建下面描述的 PDF 对象之前应删除这些内容;
- 应用 JBIG2Decode 过滤器的图像 XObject 包含与该图像表示的 JBIG2 页面关联的所有段,即其段页面关联字段包含该图像表示的 JBIG2 页面的页码的所有段。然而,在图像 XObject 中,段的页号应始终为 1,即,当将每个此类段写入 XObject 时,其段页关联字段的值应设置为 1;
- 如果位流包含全局段 (段页关联字段包含 0 的段),则这些段必须放置在单独的 PDF 流中,并且表 3.10 中列出的过滤器参数应引用该流。该流可由多个图像 XObject 共享,这些图像 XObject 的 JBIG2 编码使用相同的全局段;
下面这个例子显示了使用 JBIG2 压缩方法压缩然后以 ASCII 十六进制表示形式编码的图像,由于 JBIG2 位流包含全局段,因此这些全局段被放置在单独的 PDF 流中,如 JBIG2Globals 过滤器参数所示
5 0 obj
<< /Type /XObject
/Subtype /Image
/Width 52
/Height 66
/ColorSpace /DeviceGray
/BitsPerComponent 1
/Length 224
/Filter [/ASCIIHexDecode /JBIG2Decode]
/DecodeParms [null << /JBIG2Globals 6 0 R >>]
>>
stream
000000013000010000001300000034000000420000000000
00000040000000000002062000010000001e000000340000
004200000000000000000200100000000231db51ce51ffac>
endstream
endobj
6 0 obj
<< /Length 126
/Filter /ASCIIHexDecode
>>
stream
0000000000010000000032000003fffdff02fefefe000000
01000000012ae225aea9a5a538b4d9999c5c8e56ef0f872
7f2b53d4e37ef795cc5506dffac>
endstream
endobj
本例的 JBIG2 比特流如下:
97 4A 42 32 0D 0A 1A 0A 01 00 00 00 01 00 00 00 00 00 01 00 00 00 00 32
00 00 03 FF FD FF 02 FE FE FE 00 00 00 01 00 00 00 01 2A E2 25 AE A9 A5
A5 38 B4 D9 99 9C 5C 8E 56 EF 0F 87 27 F2 B5 3D 4E 37 EF 79 5C C5 50 6D
FF AC 00 00 00 01 30 00 01 00 00 00 13 00 00 00 34 00 00 00 42 00 00 00
00 00 00 00 00 40 00 00 00 00 00 02 06 20 00 01 00 00 00 1E 00 00 00 34
00 00 00 42 00 00 00 00 00 00 00 00 02 00 10 00 00 00 02 31 DB 51 CE 51
FF AC 00 00 00 03 31 00 01 00 00 00 00 00 00 00 04 33 01 00 00 00 00
该比特流由下面列出的部分组成 (按列出的顺序)
JBIG2 文件头
97 4A 42 32 0D 0A 1A 0A 01 00 00 00 01
由于 PDF 中不使用 JBIG2 文件头,因此该头不会放置在 JBIG2 流对象中,而是被丢弃。
第一个 JBIG2 段 (段 0),在本例中为符号字典段
00 00 00 00 00 01 00 00 00 00 32 00 00 03 FF FD FF 02 FE FE FE 00 00 00
01 00 00 00 01 2A E2 25 AE A9 A5 A5 38 B4 D9 99 9C 5C 8E 56 EF 0F 87 27
F2 B5 3D 4E 37 EF 79 5C C5 50 6D FF AC
这是一个全局段 (段页关联 = 0),因此被放置在 JBIG2Globals 流中。
页面信息段
00 00 00 01 30 00 01 00 00 00 13 00 00 00 34 00 00 00 42 00 00 00 00
00 00 00 00 40 00 00
直接文本区域段
00 00 00 02 06 20 00 01 00 00 00 1E 00 00 00 34 00 00 00 42 00 00 00
00 00 00 00 00 02 00 10 00 00 00 02 31 DB 51 CE 51 FF AC
这两个段构成了 JBIG2 页面的内容,并放置在表示该图像的 PDF XObject 中。
页尾段
00 00 00 03 31 00 01 00 00 00 00
文件结尾段
00 00 00 04 33 01 00 00 00 00
由于 PDF 中未使用这些内容,因此它们被丢弃。然后,生成的 PDF 图像对象包含页面信息段和直接文本区域段,并引用包含符号字典段的 JBIG2Globals 流。
2.7 DCTDecode 过滤器
DCTDecode 过滤器对以 JPEG 基线格式编码的灰度或彩色图像数据进行解码,JPEG 代表联合图像专家组,这是国际标准化组织内开发该格式的一个小组,DCT 代表离散余弦变换,是编码中使用的主要技术。
JPEG 编码是一种有损压缩方法,专为采样连续色调图像的压缩而设计,不适用于一般数据压缩。使用 JPEG 编码的数据由图像样本流组成,每个样本由一个、两个、三个或四个组成 颜色成分。特定样本的颜色分量值必须连续出现,每个分量值占用一个 8 位字节。
在编码过程中,有几个参数控制算法和信息丢失。这些参数的值 (包括图像的尺寸和每个样本的分量数量) 完全由编码器控制并存储在编码数据中。DCTDecode一般直接从编码数据中获取它需要的参数值。然而,在一种情况下,参数可能不存在于编码数据中,但必须是在过滤器参数字典中指定。
此处未介绍编码算法的详细信息,但可以在 ISO 规范和 JPEG:Pennebaker 和 Mitchell 编写的静态图像数据压缩标准中找到。简而言之,JPEG 算法将图像分成 8 个样本宽 x 8 个高的块。图像中的每个颜色分量都被单独处理,对每个执行二维 DCT 堵塞,该运算产生 64 个系数,然后对其进行量化。每个系数可以用不同的步长来量化。正是这种量化导致了 JPEG 算法中的信息丢失,然后压缩量化的系数。
编码算法可以通过减小量化中的步长来减少信息损失,但代价是减少算法实现的压缩量。JPEG 算法实现的压缩取决于被压缩的图像和可接受的损失量。通常,可以在没有明显信息损失的情况下实现 15:1 的压缩,并且 30:1 的压缩几乎不会对图像造成损害。
对于分别处理亮度和色度的颜色空间,通常可以比不处理的颜色空间进行更好的压缩。由滤波器提供的 RGB 到 YUV 转换是分离亮度和色度的一种尝试,它符合 CCIR 建议 601-1。其他颜色空间,如CIE 1976 Lab* 空间也可以实现这一目标。然后,通过使用更粗糙的采样或量化,色度分量可以比亮度压缩得更多,而质量不会降低。
Adobe Acrobat 产品中的 JPEG 过滤器实现不支持与图像无关的 JPEG 标准功能。此外,还对保留的标记代码和标准的其他可选功能进行了某些选择。有关详细信息,请参阅 Adobe 技术说明,支持 PostScriptLevel2 中的 DCT 过滤器。
除了基线 JPEG 格式外,从 PDF1.3 开始,DCTDecode 过滤器支持渐进式 JPEG 扩展。此扩展不会向 DCTDecode 参数字典添加任何条目,在编码数据中表示基线 JPEG 和渐进 JPEG 之间的区别。
注意:对于嵌入 PDF 文件中的流数据,使用渐进式 JPEG 没有任何好处。与基线 JPEG 相比,对渐进式 JPEG 的解码速度较慢,并且消耗更多内存。此功能的目的是使流能够引用外部文件,而该文件的数据恰好已经用渐进式 JPEG 编码。
2.8 JPXDecode 过滤器
JPXDecode 过滤器对使用 JPEG2000 压缩方法 (图像数据压缩和打包的国际标准) 编码的数据进行解码,JPEG2000 定义了一种基于小波的图像压缩方法,与常规 JPEG 或 CCITT 等其他方法相比,该方法可以更好地缩小尺寸。尽管该过滤器可以再现无损压缩的样本,但建议仅将其用于图像而不用于一般数据压缩。
在 PDF 中,此过滤器只能应用于图像 XObject,而不能应用于内联图像。它既适用于具有单个颜色分量的图像,也适用于具有多个颜色分量的图像。图像中的颜色分量每个样本可能具有不同的位数,允许使用 1 到 38 之间的任何值。
根据单个 JPEG2000 数据流,可以对图像的多个版本进行解码,这些不同的版本形成了四个自由度的级数:采样分辨率、颜色深度、波段和位置。例如,随着分辨率的提高,可以从数据中解码图像的缩略图版本,然后是图像的其他版本的序列,每个版本的样本数量大约是前一版本的 4 倍 (宽度的两倍乘以高度的两倍),最后一个版本是全分辨率图像。
查看和打印应用程序可以通过使用分辨率级数获得性能优势,如果全分辨率图像是密集采样的,则应用程序可能能够仅选择并解码构成较低分辨率版本的数据,从而花费较少的解码时间,需要处理的字节更少,这在通过 Web 查看文件时是一个好处。如果仅需要显示或打印图像的某些区域,则图像的平铺结构也可以提供益处。
注意:有关这些进展的信息已编码在数据中,不需要解码参数来描述它们。解码器处理它遇到的任何进展以提供正确的图像数据,不感兴趣的进展可能只会对性能产生影响。
JPEG2000 规范定义了两种广泛使用的格式 JP2 和 JPX,用于打包压缩图像数据,JP2 是 JPX 的子集。这些包含正确解释图像数据所需的所有信息,包括色彩空间、每个组件的位数和图像尺寸。换句话说,它们是图像的完整描述 (与需要外部参数才能正确解释的图像数据相反)。JPXDecode 过滤器期望读取完整的 JPX 文件结构 —— 无论是 PDF 文件的内部结构还是外部文件的结构。
为了促进互操作性,规范定义了 JPX 的一个子集,称为 JPX 基线 (JP2 也是其中的一个子集)。JPX 功能基线集的完整详细信息包含在 ISO/IEC 15444-2,信息技术 — JPEG 2000 图像编码系统:扩展中(请参阅参考书目)。 另请参见 http://www.jpeg.org/JPEG2000.html。
PDF 图像 XObject 中使用的数据应限于 JPX 基线功能集,枚举颜色空间 19 (CIEJab) 除外。此外,PDF 还支持枚举色彩空间 12 (CMYK),它是 JPX 的一部分,但不是 JPX 基线。
JPX 文件描述图像数据中存在的通道集合,通道可以具有以下三种类型之一:
- 普通通道包含的值在解码时会成为指定颜色分量的样本;
- 不透明度通道提供被解释为原始不透明度信息的样本;
- 预乘不透明度通道提供的样本已与与其关联的那些通道的颜色样本相乘;
不透明度和预乘不透明度通道与特定颜色通道相关联,与给定颜色通道关联的不透明度通道(任一类型)绝不会超过一个。例如,一个不透明度通道可以应用于红色样本,而另一个不透明度通道可以应用于 RGB 图像的绿色和蓝色通道。
注意:虽然一种可能的方法显示了正常的混合模式,但未明确指定使用不透明度信息的方法。
除了使用不透明度通道来描述透明度之外,JPX 文件还能够指定色度键透明度。单一颜色是通过给出一组值来指定的,每个颜色通道一个值。任何与此颜色匹配的图像位置都被认为是完全透明的。
在 JPX 文件中,图像的颜色空间可能是以下之一:
- 从枚举颜色空间列表中选择的预定义颜色空间,其中两个实际上是空间族,并且包含参数;
- 受限 ICC 配置文件,这些是 JP2 文件中允许的唯一 ICC 配置文件类型;
- 由 ICC-1 定义的任何类型的输入 ICC 配置文件;
- 供应商定义的色彩空间;
可以为图像指定多个颜色空间,每个空间都标有优先级和近似值,该近似值指示其表示正确颜色空间的程度。此外,图像的色彩空间可以作为使用来自图像数据通道的样本选择的调色板的基础,相当于 PDF 中的索引色彩空间。
除了描述简单图像之外,JPX 格式还有其他功能。这些功能包括描述分层和给出合成指令、指定简单动画以及包括通用 XML 元数据 (以及此类数据的 JPEG2000 特定模式) 的规定。建议 (但不要求) 将相关元数据以 XMP 格式复制到图像字典的元数据流中。
当将 JPXDecode 过滤器与图像 XObject 一起使用时,图像字典中的某些项会发生更改和限制:
- 宽度和高度必须与 JPEG2000 数据中相应的宽度和高度值匹配;
- ColorSpace 是可选的,因为JPEG2000 数据包含色彩空间规范。如果存在,则它确定如何解释图像样本,并且忽略 JPEG2000 数据中的色彩空间规范。JPEG2000 数据中包含的颜色通道数量必须与颜色空间中的分量数量相匹配;PDF 的制作者必须确保样本与所使用的色彩空间一致。可以指定除图案之外的任何颜色空间。如果使用索引色彩空间,则受 256 色 PDF 限制的约束。JPEG2000 颜色规范中的类似概念是调色板颜色空间,其限制为 1024 种颜色。如果颜色空间与 JPX 枚举的颜色空间之一不匹配 (例如,如果它具有 2 个或 4 以上颜色分量),可以将其指定为 JPX 数据中的供应商色彩空间。如果图像字典中不存在 ColorSpace,则使用 JPEG2000 数据中的颜色空间信息。查看器应用程序必须支持枚举色彩空间的 JPX 基线集,它们还负责处理颜色空间和样本位深度之间的交互。如果 JPEG2000 数据中给出了多个色彩空间规范,则渲染应用程序应尝试使用具有最高优先级和最佳近似值的色彩空间规范。如果颜色空间由不支持的 ICC 配置文件指定,则使用优先级和近似值较低的下一个颜色空间。如果未找到支持的颜色空间,则使用的颜色空间应为 DeviceGray、DeviceRGB 或 DeviceCMYK ,具体取决于 JPEG2000 数据中的颜色通道数;
- SMaskInData 指定是否应使用与图像样本一起打包的软掩模信息(请参阅第 512 页上的“软掩模图像”); 如果是,则不需要 SMask 条目。 如果 SMaskInData 非零,则 JPEG2000 数据中必须只有一个不透明度通道,并且它必须适用于所有颜色通道;
- 解码将被忽略,除非图像被视为蒙版; 也就是说,当 ImageMask 为 true 时。 在这种情况下,JPEG2000 数据必须提供具有 1 位样本的单一颜色通道;
2.9 Crypt 过滤器
Crypt 过滤器允许文档级安全处理程序确定应使用哪些算法来解密输入数据,该过滤器的解码参数字典中的 Name 参数指定了应使用文档中的哪种密码过滤器
此外,解码参数字典可以包括对于安全处理程序的私有项,当解密数据或提供解密数据的密钥时,安全处理程序可以使用来自密码过滤器解码参数字典和密码过滤器字典的信息。
注意:将私有数据添加到解码参数字典时,安全处理程序应根据 PDF 名称注册表对这些项进行命名。