问题 PDF规范中的最小PDF示例


我从PDF规范中获取了最小的PDF示例 PDF规范,将其复制到NotePad,重命名该文件以具有扩展名 .PDF

我可以用其他PDF查看器打开它(PDF-XChange,SumatraPDF,MuPDF)。但是当我用Adobe Reader打开它时,它说文件坏了。

我不确定其他观众是否将此“损坏”的文件视为空白文件。

该文件应该显示一个空白页面,因为它是一个最小的例子。

实际上,我修改了最小的例子。因为当我将它从PDF规范复制到记事本,并通过十六进制编辑器打开.txt文件时,我看到一个新行 。文本 文件给我2个空间。例如,

1 0 obj
<< /Type /Catalog

给我(在十六进制编辑器中)

1 0 obj  << /Type /Catalog

是(十六进制值)

31 20 30 20 6F 62 6A 0D 0A 3C 3C 20 2F 54 79 70
65 20 2F 43 61 74 61 6C 6F 67

之间的2个空格 j 和 < 是 0D 0A

因此我不在NotePad中创建新行,并修改其中的值 xref 部分。

以下是完整的代码。

你知道这个例子有什么问题吗?为什么Adobe Reader说它坏了?这是因为我给出了错误的价值观 xref

%PDF-1.4 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1 >> endobj 4 0 obj << /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >> endobj 5 0 obj << /Length 35 >> stream … Page-marking operators … endstream endobj 6 0 obj [/PDF] endobj xref 0 7 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000119 00000 n 0000000176 00000 n 0000000295 00000 n 0000000373 00000 n trailer << /Size 7 /Root 1 0 R >> startxref 395 %%EOF

8785
2017-09-30 15:49


起源



答案:


第一: 当您从PDF规范中“复制”示例时,很可能发生了一些使您的副本无法按预期工作的事情:

  • ...你没有通过在文本编辑器中重新键入示例来“复制”,但是
  • ...你使用了copy'n'paste,使用PDF作为源文件。

根据您的文本编辑器,该方法可能导致换行符约定的转换从[cr] + [lf]更改为[cr],反之亦然。这反过来意味着对象'目录'中的字节偏移数字(''xref'-table)不再有效。

另一个问题 使用您发布的PDF源代码,它现在不包含任何换行符 一点都不。有些观众可能仍然可以默默地解析这个东西,但不是全部都是。它肯定违反了规范,因为根据规范,在第7.5.2章中明确指出了这一点

“PDF文件的第一行应为包含5个字符%PDF的标题,后跟1.N形式的版本号,其中N是0到7之间的数字。

您的标头违反了该规则。

也, 中的'流' 5 0 obj 不是任何有效的PDF代码,它只是占位符文本(… Page-marking operators …)。一些观众在遇到这种“垃圾”时可能会倾斜。

最后, 你的 startxref 价值不正确。

所以这是一个有效的文件。我在文本编辑器中对它进行了修复,然后将原始代码作为注释 %%EOF 供比较和参考:

%PDF-1.4
1 0 obj
<< /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>
endobj
2 0 obj
<< /Type Outlines /Count 0 >>
endobj
3 0 obj
<< /Type /Pages /Kids [4 0 R] /Count 1 >>
endobj
4 0 obj
<< /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >>
endobj
5 0 obj
<< /Length 35 >>
stream
… Page-marking operators …
endstream 
endobj
6 0 obj
[/PDF]
endobj
xref
0 7
0000000000 65535 f 
0000000009 00000 n 
0000000074 00000 n 
0000000119 00000 n 
0000000176 00000 n 
0000000295 00000 n 
0000000376 00000 n 
trailer 
<< /Size 7 /Root 1 0 R >>
startxref
394
%%EOF

%% %PDF-1.4 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1 >> endobj 4 0 obj << /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >> endobj 5 0 obj << /Length 35 >> stream … Page-marking operators … endstream endobj 6 0 obj [/PDF] endobj xref 0 7 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000119 00000 n 0000000176 00000 n 0000000295 00000 n 0000000373 00000 n trailer << /Size 7 /Root 1 0 R >> startxref 395

16
2017-09-30 16:55



谢谢Kurt,但为什么startxref的值是394而不是396.这个值是不应该是字符'x'的字节偏移量 xref 在这个文件?十六进制编辑器中为396。但是对于396,该文件被破坏,394工作。我不知道原因。 - user565739
@ user565739:你应该跑 dd bs=1 skip=394 if=this.pdf。这意味着您在转储文件时跳过了前394个字节。现在输出应该从 xref 在它自己的一条线上。 - Kurt Pfeifle
当我复制/粘贴它时,我不得不将“页面标记操作符”周围的单个字符“...”更改为三个字符“...”,并将startxref从394更改为398.我怀疑当我复制/粘贴时单个字符“......”被吹了。通过扩展到三个,个人“。”在流的任一侧,增加了另外4个字节,从x4表开始,将我从394移动到398。 - Pat
当我尝试添加一些内容时,我只得到一个空白页面,例如,使用“BT 10 50 Td(AwaY!)Tj ET”(指令和开始/结束标记在不同的行中)作为对象5的流 - 以及之后调整相应的字节偏移量。预览打开很好,但只显示一个空白页面。我在OX 10.6.8上使用Preview ver 5 - MASL
@MASL:可以在这里找到一些(手工编码的)PDF示例: github.com/angea/PDF101/tree/master/handcoded。 - Kurt Pfeifle


答案:


第一: 当您从PDF规范中“复制”示例时,很可能发生了一些使您的副本无法按预期工作的事情:

  • ...你没有通过在文本编辑器中重新键入示例来“复制”,但是
  • ...你使用了copy'n'paste,使用PDF作为源文件。

根据您的文本编辑器,该方法可能导致换行符约定的转换从[cr] + [lf]更改为[cr],反之亦然。这反过来意味着对象'目录'中的字节偏移数字(''xref'-table)不再有效。

另一个问题 使用您发布的PDF源代码,它现在不包含任何换行符 一点都不。有些观众可能仍然可以默默地解析这个东西,但不是全部都是。它肯定违反了规范,因为根据规范,在第7.5.2章中明确指出了这一点

“PDF文件的第一行应为包含5个字符%PDF的标题,后跟1.N形式的版本号,其中N是0到7之间的数字。

您的标头违反了该规则。

也, 中的'流' 5 0 obj 不是任何有效的PDF代码,它只是占位符文本(… Page-marking operators …)。一些观众在遇到这种“垃圾”时可能会倾斜。

最后, 你的 startxref 价值不正确。

所以这是一个有效的文件。我在文本编辑器中对它进行了修复,然后将原始代码作为注释 %%EOF 供比较和参考:

%PDF-1.4
1 0 obj
<< /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>
endobj
2 0 obj
<< /Type Outlines /Count 0 >>
endobj
3 0 obj
<< /Type /Pages /Kids [4 0 R] /Count 1 >>
endobj
4 0 obj
<< /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >>
endobj
5 0 obj
<< /Length 35 >>
stream
… Page-marking operators …
endstream 
endobj
6 0 obj
[/PDF]
endobj
xref
0 7
0000000000 65535 f 
0000000009 00000 n 
0000000074 00000 n 
0000000119 00000 n 
0000000176 00000 n 
0000000295 00000 n 
0000000376 00000 n 
trailer 
<< /Size 7 /Root 1 0 R >>
startxref
394
%%EOF

%% %PDF-1.4 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1 >> endobj 4 0 obj << /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >> endobj 5 0 obj << /Length 35 >> stream … Page-marking operators … endstream endobj 6 0 obj [/PDF] endobj xref 0 7 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000119 00000 n 0000000176 00000 n 0000000295 00000 n 0000000373 00000 n trailer << /Size 7 /Root 1 0 R >> startxref 395

16
2017-09-30 16:55



谢谢Kurt,但为什么startxref的值是394而不是396.这个值是不应该是字符'x'的字节偏移量 xref 在这个文件?十六进制编辑器中为396。但是对于396,该文件被破坏,394工作。我不知道原因。 - user565739
@ user565739:你应该跑 dd bs=1 skip=394 if=this.pdf。这意味着您在转储文件时跳过了前394个字节。现在输出应该从 xref 在它自己的一条线上。 - Kurt Pfeifle
当我复制/粘贴它时,我不得不将“页面标记操作符”周围的单个字符“...”更改为三个字符“...”,并将startxref从394更改为398.我怀疑当我复制/粘贴时单个字符“......”被吹了。通过扩展到三个,个人“。”在流的任一侧,增加了另外4个字节,从x4表开始,将我从394移动到398。 - Pat
当我尝试添加一些内容时,我只得到一个空白页面,例如,使用“BT 10 50 Td(AwaY!)Tj ET”(指令和开始/结束标记在不同的行中)作为对象5的流 - 以及之后调整相应的字节偏移量。预览打开很好,但只显示一个空白页面。我在OX 10.6.8上使用Preview ver 5 - MASL
@MASL:可以在这里找到一些(手工编码的)PDF示例: github.com/angea/PDF101/tree/master/handcoded。 - Kurt Pfeifle