2014-12-28 133 views
0

我现在正在理解PDF struckture,但是我对计算字符串的字节偏移量有点问题。对象的偏移量从文件开头到对象的索引处开始( 0 obj)。计算字节偏移量的问题

我有一个工作的Hello World PDF文件,但是当我数着偏移,我收到了不同势比外部参照表中的偏移。

如果有人理解这是怎么算的,请让我知道!

实施例:

0 6 OBJ外部参照:9我:17

0 1 OBJ外部参照:60我:72

0 4 OBJ外部参照:145我187

(我以“\ r \ n”(2)作为换行符)

的Adobe斯坦达特:http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf

%PDF-1.4 
%%EOF 
6 0 obj 
<< 
/Type /Catalog 
/Pages 5 0 R 
>> 
endobj 
1 0 obj 
<< 
/Type /Page 
/Parent 5 0 R 
/MediaBox [ 0 0 612 792 ] 
/Resources 3 0 R 
/Contents 2 0 R 
>> 
endobj 
4 0 obj 
<< 
/Type /Font 
/Subtype /Type1 
/Name /F1 
/BaseFont/Helvetica 
>> 
endobj 
2 0 obj 
<< 
/Length 53 
>> 
stream 
BT 
/F1 24 Tf 
1 0 0 1 260 600 Tm 
(Hello World)Tj 
ET 
endstream 
endobj 
5 0 obj 
<< 
/Type /Pages 
/Kids [ 1 0 R ] 
/Count 1 
>> 
endobj 
3 0 obj 
<< 
/ProcSet[/PDF/Text] 
/Font <</F1 4 0 R >> 
>> 
endobj 
xref 
0 7 
0000000000 65535 f 
0000000060 00000 n 
0000000228 00000 n 
0000000424 00000 n 
0000000145 00000 n 
0000000333 00000 n 
0000000009 00000 n 
trailer 
<< 
/Size 7 
/Root 6 0 R 
>> 
startxref 
488 
%%EOF 

回答

1

你不能假设一条线到底是\ r \ n对,也可能是用\ r \ n或\ r \ n,则需要使用二进制编辑器中某些。如果没有访问原始文件,我们也不能告诉你哪个值是正确的,上面的剪切/粘贴不够好,对不起。虽然9不能正确除非即%% EOF为假......

你的报价PDF文件不正确无论如何,你不应该有%% EOF作为第二线,即“应该”是高位设置的二进制字节序列,以确保PDF文件作为二进制文件传输。

你怎么知道你的PDF文件中的外部参照是正确的?如果您使用Acrobat打开它,它是否提供在退出时保存更改?这是一个明确的信号,Acrobat中重建外部参照你的,因为它是不正确.....

[编辑的清晰度和因为太长评论]

我应该在我的解释更清晰。我在最初的答案中将2个陈述合并为1,并打算在评论中澄清。该文件不正确,外部参照偏移看起来对我来说是错误的,并且在初始检查时出现%% EOF错误(但后面会看到),它看起来像某种方式是伪造的(通过剪切/粘贴插入,或由编辑或其他)。

从技术上讲,你可以拥有这一个PDF文件(但外面串并流)的任何地方开始%的任何文字,只要你占了它正常的,不容易PDF语法。但我仍然不会在PDF文件中放入两个%% EOF注释,它可能会让简单的PDF用户感到困惑。

我不认为具有'x y obj'语句之前的注释是一定是错误的(我不会做它,但是这不是一回事)。它也不会完全失效大卫的观点有关:

The idea behind this is that you can open a file, set the file read position to a given offset and start reading. 

前提是PDF消费者准备阅读注释,不期望的空白或'x y obj'陈述(和我有具有看到PDF文件前面的空格在这里)。这是有争议的,虽然我会阅读规范说外部参照偏移量应该准确地指向'x y obj'行的第一个字节,但实际上并没有在规范中说太多的话。并且PDF使用者在对象定义本身的过程中需要能够处理注释。例如,我认为这是:

1 0 obj 
%% Here's a comment 
<< 
/Type /Page 
/Parent 5 0 R 
/MediaBox [ 0 0 612 792 ] 
/Resources 3 0 R 
/Contents 2 0 R 
>> 

会是合法的。该行以'%'开头,它不在字符串或流上下文中,并且不打破PDF语法,消费者应该直接跳过它。

这不是非常太大的不同:

%% Here's a comment 
1 0 obj 
<< 
/Type /Page 
/Parent 5 0 R 
/MediaBox [ 0 0 612 792 ] 
/Resources 3 0 R 
/Contents 2 0 R 
>> 

同样,我不会做自己(或者,如果我做了我的外部参照指向的1 0 obj中的开始,但我认为它是可以这样讨论的

但在最初的例子中,我的二进制编辑器说(2字节行结束)对象4从偏移量187开始,如果我使用1个字节的结尾降到170。为了让对象的外部参照是正确的我假设行结束符是1个字节,我删除了“%% EOF \ n”但是从17中减去6个字节0仍然在164处出现,因此在外部参照145所包含的地方几乎没有。我看不出有什么办法让对象4在位置145上,而不需要去除真正的PDF运算符/结构。

+0

* PDF文件不正确* - 您给出的原因是使文件看起来可疑,但还不正确。 – mkl

+0

PDF文件的最后一行应该是%% EOF,实际上不应该是2.虽然(像往常一样)Acrobat容忍这种事情。 KenS

+0

虽然这个文件肯定是不正确的。 xref表示对象6 0位于偏移量9,这是%% EOF的开始,而不是'6 0 obj'行。我想你可以争辩说,由于评论被忽略,这是合法的,但它的头发分裂。该规范说,外部参照偏移应该指向'对象的开始'。这是让外部参照是正确的一种方法,如果Acrobat忽略了这样一个很好的区别,它根本不会让我感到意外。但是没有办法在小于64字节(甚至计算1字节换行符)的情况下得到1 0 obj,并且外部参照显示为60. – KenS

1

这是一个非常有趣的文件,最初阅读PDF规范只是让我更困惑:-)。在这种情况下(我会让这些人疯狂),我会简单地保存示例PDF文件,并像@KenS在他之前的回答中所建议的那样做;在Acrobat中打开它,如果Acrobat报告它已损坏或要求您在关闭文件时保存 - 它不喜欢它,并且您可以认为它错误。

原因这个文件是有趣的是第二行的:

%%EOF 

我不同意KENS具有该行的文件自动失效 - 我可以在ISO 32000没有文字,指出这个。文字说明文件的%% EOF行在文件的末尾具有语法上的含义(并解释了它存在的原因),并指出任何以百分比字符(%)开头的行是评论以及那是什么手段。但是没有一个地方说%% EOF不允许作为文件中其他地方的注释(尽管我认为这是一件愚蠢的事情,但这是不同的)。

如果该%% EOF行不存在,那么XREF表是正确的。如果它在那里,那就错了。更多的解释我在文档中读到的内容:

1)据我所知,偏移量从文件的第一个字节开始(它是一个字节偏移量,不是字符偏移量),它是“0”,然后数起来。这背后的想法是,你可以打开一个文件,将文件读取位置设置为给定的偏移量并开始读取。因此,如果您在显示实际字节数的二进制编辑器中打开文件,则偏移量应与您在此处看到的内容相匹配。如果你的%% EOF行不存在,这意味着第一个对象(6 0 obj)有效地从偏移量9开始(如果你在这里结束字符是单字节行结束)。此时它与PDF规范本身给出的示例相匹配,所以我相信如果第二行(%% EOF)不在PDF文件中,则9的偏移量是正确的。

2)第二行以百分号开头,使其成为评论。 PDF规范规定,注释(从%注册到但不包括行结束字符的所有内容)应被解释为单个空白字符。这很有趣,可能会导致各种猜测,这是否意味着为了抵消它后面的对象,但坦率地说,由于我之前提到的内容,所有这些猜测都是失序和不相关的。

背后的想法是,您可以打开一个文件,将文件读取位置设置为给定的偏移量并开始读取。

这正是交叉引用表的用途,应该从字面上理解。换句话说,假设单字节行结束字符,示例文件中的对象6从偏移量15开始,这就是该对象应该在XREF表中的数字。

再次,考虑@KenS的评论,你不能只是假设行结尾是两个字节,你必须知道他们是什么(他们可能是混合所以你甚至不能假设所有行都有一样)。如果这个文件对于所有行都有两个字节行结束,那么你的计数为17就是正确的。