簡體   English   中英

嘗試解壓 PDF 中的 stream 時出錯

[英]Error while trying to decompress stream in PDF

我正在嘗試從該文件中的 PDF Object 解壓縮 stream :

 4 0 obj
<< 
/Filter /FlateDecode
/Length 64
>>
stream
xœs
QÐw34V02UIS0´0P030PIQÐpÉÏKIUH-.ITH.-*Ê··×TÉRp
á T‰
Ê
endstream
endobj

我在名為 Stream.file 的文件中以與原始文件相同的格式復制粘貼了此Stream.file

xœs
QÐw34V02UIS0´0P030PIQÐpÉÏKIUH-.ITH.-*Ê··×TÉRp
á T‰
Ê

這個 stream 應該翻譯成: Donde esta curro?? . 在 C# 控制台應用程序中將 stream 添加到Stream.file中。

using System.IO;
using System.IO.Compression;

namespace Filters
{
    public static class FiltersLoader
    {
        public static void Parse()
        {
            var bytes = File.ReadAllBytes("Stream.file");
            var originalFileStream = new MemoryStream(bytes);

            using (var decompressedFileStream = new MemoryStream())
            using (var decompressionStream = new DeflateStream(originalFileStream, CompressionMode.Decompress))
            {
                decompressionStream.CopyTo(decompressedFileStream);
            }    
        }
    }
}

但是,在嘗試復制它時會產生異常:

The archive entry was compressed using an unsupported compression method.

如果可能的話,我想如何用 .net 代碼解碼這個 stream 。

謝謝。

The main problem is that the DeflateStream class can decode a naked FLATE compressed stream (as per RFC 1951 ) but the content of PDF streams with FlateDecode filter actually is presented in the ZLIB Compressed Data Format (as per RFC 1950 ) wrapping FLATE compressed data.

要解決此問題,只需刪除兩字節 ZLIB header。

另一個問題在您的第一個示例文檔中變得很清楚:該文檔已加密,因此在 FLATE 解碼 stream 內容之前必須解密其中的內容。

刪除 ZLIB header 以獲取 FLATE 編碼數據

The DeflateStream class can decode a naked FLATE compressed stream (as per RFC 1951 ) but the content of PDF streams with FlateDecode filter actually is presented in the ZLIB Compressed Data Format (as per RFC 1950 ) wrapping FLATE compressed data.

幸運的是,跳轉到其中的 FLATE 編碼數據非常容易,只需刪除前兩個字節。 (嚴格來說,它們和 FLATE 編碼數據之間可能有一個字典標識符,但這似乎很少使用。)

如果是您的代碼:

var bytes = File.ReadAllBytes("Stream.file");
var originalFileStream = new MemoryStream(bytes);

originalFileStream.ReadByte();
originalFileStream.ReadByte();

using (var decompressedFileStream = new MemoryStream())
using (var decompressionStream = new DeflateStream(originalFileStream, CompressionMode.Decompress))
{
    decompressionStream.CopyTo(decompressedFileStream);
}   

如果是加密的 PDF,請先解密

您的第一個示例文件pdf-test.pdf已加密,如預告片中存在Encrypt條目所示:

trailer
<</Size 37/Encrypt 38 0 R>>
startxref
116
%%EOF

因此,在解壓縮 stream 內容之前,您必須對其進行解密。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM