在 PDF 中编写流式交叉引用:文件被检测为已损坏?

Writing a streamed cross-reference in PDF: file is detected as damaged?

我正在使用 Typescript 在我的 PDF 文件末尾写一个流式交叉引用 table,正如我 previous post

的答案所建议的那样

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

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,92,144,144 ,0,141,44,6,140

我已经逆向了我发现的过程

整理的充气版如下:

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”(在引用的 post 中找到)。但是,即使没有它,似乎也会出现同样的问题。我错过了什么?

3 个问题可以轻松识别。

起始外部参照偏移量不正确

您的 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

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