XRef流的偏移量是否应始终存储?应在同一个流中,还是放在其他流中?
请考虑:
C:\>cpdf -create-pdf -create-objstm -stdout
%PDF-2.0
%
% skipped
%
5 0 obj
<</Type/XRef/W[1 2 1]/Root 3 0 R/Size 5/Length 20
% skipped
请注意,“Size”并不像我预期的那样比输出中的最大对象编号多一,而“Length”表示对象编号0到4共有5条条目(解码也证实了这一点)。
我对PDF参考说明是否严格要求,在上述情况下对象5的第6条条目也必须包含感到困惑。对于“Size”,它写道:
The number one greater than the highest object number used in this section...
等。但对象数字“5”究竟在何种程度上会被“使用”?毕竟,为了确定偏移量,然后访问Xref流,需要查阅“startxref”。业界是否有共识(如果有的话)?
好吧,即使有人确认这个CLI工具的输出(以及它所基于的受人尊敬的库)是可以的,我仍觉得有点马虎。先举一个增量更新的例子:比如在Adobe Reader中使用“便签工具”并立即按Ctrl-S。现在文件中有两个编号为“5”的对象,它们都有效且必需。这看起来不太对劲。(但再次强调,其中一个只是通过附加部分中的“Prev”条目访问。)
解决方案
PDF规范明确写道:
Like any stream, a cross-reference stream shall be an indirect object. Therefore, an entry for it shall exist in either a cross-reference stream (usually itself) or in a cross-reference table (in hybridreference files
(ISO 32000-2, section 7.5.8.3)
因此,你所展示的构造严格来说是无效的。
也就是说,PDF中经常可以看到这类错误,大多数PDF处理器会忽略这个错误,甚至往往意识不到。
尽管如此,仍应明确避免这类错误,因为在某些情境下它们可能突然引发问题。就像在Adobe Acrobat中,包含多个签名的PDF的交叉引用表错误会导致验证错误一样。