【问题标题】:For linearized PDF how to determine the length of the cross-reference stream in advance?对于线性化PDF,如何提前确定交叉引用流的长度?
【发布时间】:2014-06-04 18:45:56
【问题描述】:

生成线性化 PDF 时,交叉引用表应存储在文件的最开头。如果是交叉引用流,这意味着表的内容将被压缩,压缩后交叉引用流的实际大小是不可预测的。

所以我的问题是: 如何提前确定这个交叉引用流的实际大小? 如果流的实际大小是不可预测的,那么在对象的偏移量被写入流中并且流被写入文件之后,它会再次改变后面对象的实际偏移量,不是吗?我错过了什么吗?

感谢任何提示。

【问题讨论】:

  • 它会改变后面对象的实际偏移量——这就是为什么这样的交叉引用流通常只包含对它之前的对象的引用。即使在线性化 PDF 中,每个交叉引用表或流通常也只引用前面的对象。
  • 这适用于普通的引用表,它通常只引用前面的对象。但在线性化 PDF 中,第一页、目录等对象的引用表直接遵循线性化字典,该字典位于它引用的对象之前。这就是为什么它让我感到困惑。
  • 嗯。我必须查看这样的文件才能确定,但​​实现这一目标的一种方法可能是使用带有适当预测器的压缩。这将使要压缩的数据事先知道,但第一个偏移量除外。这可以使压缩流的长度可预测。
  • 我检查了很多线性化的pdf,通常在XRefStream中使用Predictor 12(PNG Up),但我不明白为什么使用预测器可以预测压缩数据的大小?你能解释得更详细一点吗?提前致谢!
  • 我用 XRefStream(从 Acrobat 中保存)检查了一些线性化的 PDF,所有的第一个 XRefStream 字典周围都有一些空白填充。实际上,例如QPDF 源代码,名为calculateXrefStreamPadding 的方法具有您可能感兴趣的cmets。事实上,使用 QPDF 工具保存的文件中的填充非常巨大。

标签: pdf pdf-generation pdf-parsing


【解决方案1】:

如何提前确定这个交叉引用流的实际大小?

首先你不知道。至少不完全是。你描述了原因。

但有一个估计就足够了。只需在估计值中添加一些字节,然后用空格填充。 @VadimR 指出这种填充可以在线性化 PDF 中经常观察到。

您可以使用 QPDF 源 @VadimR 中引用的粗略估计,也可以尝试使用更好的估计。

你可以,例如利用预测器:

在您最终必须创建交叉引用流时,所有 PDF 对象都可以按照您需要的顺序进行序列化,但交叉引用流和线性化字典(其中包含 PDF 的最终大小和一些对象偏移)。因此,您已经知道大多数条目的连续外部参照条目值之间的差异。

如果你用完预测变量,你基本上只存储这些差异。因此,您已经知道要压缩的大部分数据。一些条目的更改不会对压缩结果产生太大影响。所以这可能会给你一个更好的估计。

此外,由于第一个交叉引用流通常不包含太多条目,您可以尝试多次压缩该流以获得不同数量的保留字节。

PS:我不知道 Adob​​e 在他们的线性化代码中使用了什么。而且我不知道在这里或多或少地争取几个字节是否有意义;毕竟线性化对于几乎不计几个字节的大文档来说是最明智的。

【讨论】:

  • 非常感谢您的回答,我还观察到在第一个 XRefStream 之后有一些空白填充,似乎用空白填充是解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-09-25
  • 2020-02-19
  • 2015-04-21
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多