【问题标题】:Writing a streamed cross-reference in PDF: file is detected as damaged?在 PDF 中编写流式交叉引用:文件被检测为损坏?
【发布时间】:2021-03-31 10:21:30
【问题描述】:

我正在使用 Typescript 在我的 PDF 文件末尾编写一个流式交叉引用表,正如我的 previous post 的答案所建议的那样

这是我在没有流的情况下编写的 XREF 表:

xref
0 1
0000000000 65535 f 
21 2
0000084670 00000 n 
0000085209 00000 n 
73 6
0000085585 00000 n 
0000086335 00000 n 
0000150988 00000 n 
0000151086 00000 n 
0000151528 00000 n 
0000151707 00000 n 
trailer
<<
/Size 79
/Root 21 0 R
/Info 19 0 R
/Prev 116
>>
startxref
152861
%%EOF

这是流式传输的版本:

79 0 obj
<<
/Type /XRef /Filter /FlateDecode
/Root 21 0 R
/Info 19 0 R
/Index [0 1 21 2 73 7 ] /W[1 3 0] /DecodeParms<</Columns 4/Predictor 12>> /Prev 116 /Length 45 /Size 80>>
stream
(...data..)
endstream
endobj
startxref
152870
%%EOF

关于流的内容,这里是字节数组的形式。使用默认压缩级别的 Poko.deflate() 对其进行了放气:

120,156,99,98,0,2,38,70,70,175,125,76,140,​​12,76,210,64,130,177,2,196,122,7,36,254,244,2,9,134,36,144,216,46,16,107,51,1014,6, ,44,6,140

我已经反转了我找到here的过程

充气版排列如下:

02 00 00 00 00
02 01 01 4a be // = 84670    -> object 21 is at byte position 84670
02 01 00 02 1b // = 539      -> object 22 is at byte position 85209
02 01 00 01 78 // = 376      -> object 73 is at byte position 85585
02 01 00 02 ee // etc
02 01 00 fc 8d
02 01 00 00 62
02 01 00 01 ba
02 01 00 00 b3
02 01 00 04 82 

但是,当我尝试打开生成的文件时,我得到的只是:

我错过了什么?这个过程最奇怪的是每行前面的“02”(在引用的帖子here中找到)。但是,即使没有它,似乎也会出现同样的问题。我错过了什么?

【问题讨论】:

  • 请分享整个PDF进行分析。
  • 问题1,你的startxref偏移量错误,你必须指向间接对象的开始,而不是其中的直接对象。但还有其他错误。

标签: pdf pdf-generation


【解决方案1】:

3 个问题可以轻松识别。

startxref 偏移不正确

您的 startxref 指向流字典的开头,但它应该指向包含流的间接对象的对象编号。

缺少预测字节

您声称 安排的膨胀版本

02 00 00 00 00
02 01 01 4a be // = 84670    -> object 21 is at byte position 84670
02 01 00 02 1b // = 539      -> object 22 is at byte position 85209
02 01 00 01 78 // = 376      -> object 73 is at byte position 85585
02 01 00 02 ee // etc
...

但是给你的信息流膨胀

00 00 00 00
01 01 4a be
01 00 02 1b
01 00 01 78
01 00 02 ee
...

即你忘了添加预测字节。

预测仅适用于偏移量

您修复了上述两个错误并共享了该文件。查看该文件,另一个错误变得清晰:您仅将预测应用于交叉引用条目的偏移部分,而不是用于指示条目类型的初始字节!

您的膨胀流现在如下

 02, 01, 01, 4a, be,
 02, 01, 00, 02, 1b,
 02, 01, 00, 01, 78,
 02, 01, 00, 02, ee,
 02, 01, 00, fc, 8d,
 02, 01, 00, 00, 62,
 02, 01, 00, 01, bc,
 02, 01, 00, 00, b3,
 02, 01, 00, 04, 82 

因此,解决预测会导致

 01, 01, 4a, be,
 02, 01, 4c, d9,
 03, 01, 4d, 51,
 04, 01, 4f, 3f,
 05, 01, 4b, cc,
 06, 01, 4b, 2e,
 07, 01, 4c, ea,
 08, 01, 4c, 9d,
 09, 01, 50, 1f

这包含很多不正确的类型字节。

【讨论】:

  • 谢谢。我已经移动了对象开头的 startxref 位置。至于谓词字节“2”,我忘了我已经评论了添加它的行。当我重新添加它时,遗憾的是问题仍然存在。
  • 更新:我发现我的数组不够长,表中没有列出最后一个对象(感谢 javascript 的静默错误)。现在,我得到一个空白 PDF,其错误与我原来的帖子“期望一个 dict 对象”中的错误相同。如果您想查看当前的 PDF:easyupload.io/p5352r
  • 好的,还有一个我没有立即看到的错误,将我的编辑与我的答案进行比较。
  • 对!没看懂,谢谢!所以我做了更正,现在打开文件时没有错误。但是,我在增量更新(添加签名)中所做的所有更新在生成的 PDF 中都不存在。如果您想查看生成的 PDF:easyupload.io/pvk290 右下角应该有一个大红色方块作为视觉签名
  • 好消息!我找到了解决方案。我删除了/DecodeParams,谓词字节并直接放置字节而不是与先前值的差异,现在一切都按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多