通过PDF规范,它说trailerstartxref之前。对我来说,xref可以出现在文档中的任何位置,但是trailer仍然出现在startxref之前。在您必须解析它之前,这是有意义的,因为您必须反向解析,因此无法考虑注释或字符串。让我们变得古怪一点。

trailer<< %\
  /Size 4 %\
  /Root 1 0 R %\
  /Info 4 0 R %\
  /Key (\
trailer<< %\
  /Size 4 %\
  /Root 2 0 R %\
  /Info 3 0 R %\
>>%)
>>&)
% test test )
startxref
 15
%%EOF

这是一个非常有效的预告片。第一个是真正的预告片,但第二个是“字符串”。在这种情况下,反向解析将无法捕获注释。如果字符串尾部包含注释或字符串,则查找字符串尾部将失败。我想知道找出预告片从哪里开始的最佳方法是什么?

更新-此预告片似乎已在Acrobat Reader中打开
%PDF-1.3
%âãÏÓ
xref
0 4
00000000 65535 f
00000110 00000 n
00000250 00000 n
00000315 00000 n
00000576 00000 n

1 0 obj <<
  /Type /Catalog
  /Pages 2 0 R
  /OpenAction [ 3 0 R /XYZ null null null ]
  /PageLabels << /Nums [0 << /S /D >> ] >>
>>
endobj
2 0 obj <<
  /Type /Pages
  /Kids [ 3 0 R ]
  /Count 1
>>
endobj
3 0 obj <<
  /Type /Page
  /Parent 2 0 R
  /Resources << >>
  /MediaBox [ 0 0 612 792 ]
>>
endobj
4 0 obj <<
  /Producer (Me)
  /CreationDate (D:20110626000000Z)
>>
endobj

trailer<< %\
  /Size 4 %\
  /Root 1 0 R %\
  /Info 4 0 R %\
  /Key (\
trailer<< %\
  /Size 4 %\
  /Root 2 0 R %\
  /Info 3 0 R %\
>>%)
>>%)
% test test )
startxref
 15
%%EOF

就语法而言,这符合规范。他们似乎能够以某种方式知道它们是在注释中还是在字符串中。解析L-R时,第二个预告片是一个字符串,尾部带有%,在预告片之后带有注释。但是,通过R-L解析,您不知道第一个)是注释的一部分还是字符串定义的结尾。

另一个例子:
%PDF-1.3
%âãÏÓ
xref
0 8
0000000000 65535 f
0000000210 00000 n
0000000357 00000 n
0000000428 00000 n
0000000533 00000 n
0000000612 00000 n
0000000759 00000 n
0000000830 00000 n
0000000935 00000 n

1 0 obj <<
  /Type /Catalog
  /Pages 2 0 R
  /OpenAction [ 3 0 R /XYZ null null null ]
  /PageLabels << /Nums [0 << /S /D >> ] >>
>>
endobj
2 0 obj <<
  /Type /Pages
  /Kids [ 3 0 R ]
  /Count 1
>>
endobj
3 0 obj <<
  /Type /Page
  /Parent 2 0 R
  /Resources << >>
  /MediaBox [ 0 0 612 792 ]
>>
endobj
4 0 obj <<
  /Producer (Me)
  /CreationDate (D:20110626000000Z)
>>
endobj
5 0 obj <<
  /Type /Catalog
  /Pages 6 0 R
  /OpenAction [ 7 0 R /XYZ null null null ]
  /PageLabels << /Nums [0 << /S /D >> ] >>
>>
endobj
6 0 obj <<
  /Type /Pages
  /Kids [ 7 0 R ]
  /Count 1
>>
endobj
7 0 obj <<
  /Type /Page
  /Parent 6 0 R
  /Resources << >>
  /MediaBox [ 0 0 100 100 ]
>>
endobj
8 0 obj <<
  /Producer (Me)
  /CreationDate (D:20110626000000Z)
>>
endobj

trailer<< %\
  /Size 8 %\
  /Root 1 0 R %\
  /Info 4 0 R %\
  /Key (\
trailer<< %\
  /Size 8 %\
  /Root 5 0 R %\
  /Info 8 0 R %\
>>%)
>>%)
% test test )
startxref
 17
%%EOF

此示例在Adobe中正确显示。在我的最后一个案例中,您声称它会失败,因为“根”节点无效,但是这个新示例(根)是有效的,但从未实际使用过。因此,它不应该显示100x100的窗口,而不是8.5“x11”的窗口吗?

关于资源
  (Required; inheritable) A dictionary containing any resources required by the page
(see Section 3.7.2, “Resource Dictionaries”). If the page requires no resources, the
value of this entry should be an empty dictionary. Omitting the entry entirely
indicates that the resources are to be inherited from an ancestor node in the page
tree.

最佳答案

startxref语句通常位于文件的末尾,尾部在其后。

更新:由于Jeremy Walton正确地观察到,以上介绍性句子的表述不够清晰(尽管我的回答后面的评论暗示了异常(exception)情况)。它应该显示为:“startref语句通常作为单个实例出现在文件的末尾,并且尾随其后(除非您的文件进行了增量更新,在这种情况下,您可能会拥有不同类型的交叉引用实例拖车。”

如果在外部参照表的字节偏移量计算的字节计数中,有注释添加到PDF中,则它们的计数与“真实的” PDF页面描述代码相同。因此,正确解析它不是问题。

要直接引用“从马口中”(PDF specification ISO 32000-1,第7.5.5节):



这里要考虑的关键表达式是“LAST 交叉引用部分”

如果您要考虑更新的预告片,请参阅第7.5.6节。

是的,您必须反向解析。要读取的第一个交叉引用部分是文件中出现的最后一个-它将具有前面的最后一个尾部。要读取的第二个是文件中出现的倒数第二个-带有前一个倒数第二个预告片。 Etc.pp ....如果您必须阅读多个预告片/外部引用部分,则阅读的每一部分都必须包含对下一个要阅读的内容的引用。

如果您认为“注释”是可以在不破坏其结构的情况下自由插入PDF的内容,那么请换个思路。插入注释后,您至少必须更新外部参照表(以及对象的/Length键)。

更新2: Jeremey构建的trailer<<...>>字典可能甚至根本不是有效的字典,因此它也不是有效的预告片字典...

无论如何,根据规范,预告片字典必须由“一系列键值对”组成。预告片字典中的'legal'键仅限于一个非常狭窄的集合,其中一些甚至是可选的(请参见7.5.5节中的表15)。

杰米(Jermey)似乎以某种方式构造了他的示例,以使(误读)此代码段作为可能有效的预告片字典:

trailer<<%) >>
% test test )

当然哪个都不是字典,因为我们在这里看不到任何键值对。

他的完整示例也无效,因为称为/Key的“键”不在预告片的有效键名中(根据表15:/Size/Prev/Root/Encrypt/Info/ID/XRefStm) 。

因此,杰里米(Jeremy)应该在其PDF解析代码中执行与所有理智的乃至大多数理智的PDF处理库相同的操作:放弃明显无效的构造,而不是在它们中进行搜索,并告诉用户“您该死的PDF已损坏,因为我们无法识别文件假定的尾部中的有效 key ”。

关于parsing - 如何找到预告片字典?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6462607/

10-12 02:13