Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASCII85解码和按行编码时出错_C#_Parsing_Pdf_Decoding - Fatal编程技术网

C# ASCII85解码和按行编码时出错

C# ASCII85解码和按行编码时出错,c#,parsing,pdf,decoding,C#,Parsing,Pdf,Decoding,我使用了以下代码来解码pdf格式的文本流。在某些情况下,流需要由2个过滤器解码。 > 我先用ASCII85解码,然后用FlateCode解码流。在某些情况下,flatedecoded最终结果变为空。对这个问题有什么想法吗 public byte[] decode(byte[] encodedInput) { bool strict = false; MemoryStream stream = new MemoryStream(encodedInpu

我使用了以下代码来解码pdf格式的文本流。在某些情况下,流需要由2个过滤器解码。 > 我先用ASCII85解码,然后用FlateCode解码流。在某些情况下,flatedecoded最终结果变为空。对这个问题有什么想法吗

    public byte[] decode(byte[] encodedInput)
    {
        bool strict = false;
        MemoryStream stream = new MemoryStream(encodedInput);
        InflaterInputStream zip = new InflaterInputStream(stream);
        MemoryStream output = new MemoryStream();
        byte[] b = new byte[strict ? 4092 : 1];
        try
        {
            int n;
            while ((n = zip.Read(b, 0, b.Length)) > 0)
            {
                output.Write(b, 0, n);
            }
            zip.Close();
            output.Close();
            return (output.ToArray());
        }
        catch
        {
            if (strict)
                return null;
            return (output.ToArray());
        }
    }

//ASCII85Decode

class ASCII85 : IASCII85
{
    /// <summary>
 /// Prefix mark that identifies an encoded ASCII85 string, traditionally 
'<~'
 /// </summary>
    public string PrefixMark = "<~";
    /// <summary>
    /// Suffix mark that identifies an encoded ASCII85 string, 
traditionally '~>'
    /// </summary>
    public string SuffixMark = "~>";
    /// <summary>
    /// Maximum line length for encoded ASCII85 string; 
    /// set to zero for one unbroken line.
    /// </summary>
    public int LineLength = 75;
    /// <summary>
    /// Add the Prefix and Suffix marks when encoding, and enforce their 
presence for decoding
    /// </summary>
    public bool EnforceMarks = true;

    private const int _asciiOffset = 33;
    private byte[] _encodedBlock = new byte[5];
    private byte[] _decodedBlock = new byte[4];
    private uint _tuple = 0;
    private int _linePos = 0;
    private uint[] pow85 = { 85 * 85 * 85 * 85, 85 * 85 * 85, 85 * 85, 85, 
1 };

    /// <summary>
    /// Decodes an ASCII85 encoded string into the original binary data
    /// </summary>
    /// <param name="inputString">ASCII85 encoded string</param>
    /// <returns>byte array of decoded binary data</returns>
    public byte[] decode(string inputString)
    {
        if (EnforceMarks)
        {
            bool x = !inputString.StartsWith(PrefixMark);
            bool y = !inputString.EndsWith(SuffixMark);
            bool a = !inputString.StartsWith(PrefixMark) && 
!inputString.EndsWith(SuffixMark);             
            if (a)
            {
                throw new Exception("ASCII85 encoded data should begin with 
'" + PrefixMark +
                    "' and end with '" + SuffixMark + "'");
            }
        }
        if (inputString.StartsWith("<~"))
        {
            inputString = inputString.Substring(PrefixMark.Length);
        }
        if (inputString.EndsWith("~>"))
        {
            inputString = inputString.Substring(0, inputString.Length - 
SuffixMark.Length);
        }

        MemoryStream ms = new MemoryStream();
        int count = 0;
        bool processChar = false;

        foreach (char c in inputString)
        {
            switch (c)
            {
                case 'z':
                    if (count != 0)
                    {
                        throw new Exception("The character 'z' is invalid 
inside an ASCII85 block.");
                    }
                    _decodedBlock[0] = 0;
                    _decodedBlock[1] = 0;
                    _decodedBlock[2] = 0;
                    _decodedBlock[3] = 0;
                    ms.Write(_decodedBlock, 0, _decodedBlock.Length);
                    processChar = false;
                    break;
                case '\n':
                case '\r':
                case '\t':
                case '\0':
                case '\f':
                case '\b':
                    processChar = false;
                    break;
                default:
                    if (c < '!' || c > 'u')
                    {
                        throw new Exception("Bad character '" + c + "' 
                    found. ASCII85 only allows characters '!' to 'u'.");
                    }
                    processChar = true;
                    break;
            }

            if (processChar)
            {
                _tuple += ((uint)(c - _asciiOffset) * pow85[count]);
                count++;
                if (count == _encodedBlock.Length)
                {
                    DecodeBlock();
                    ms.Write(_decodedBlock, 0, _decodedBlock.Length);
                    _tuple = 0;
                    count = 0;
                }
            }
        }

        if (count != 0)
        {
            if (count == 1)
            {
                throw new Exception("The last block of ASCII85 data cannot 
be a single byte.");
            }
            count--;
            _tuple += pow85[count];
            DecodeBlock(count);
            for (int i = 0; i < count; i++)
            {
                ms.WriteByte(_decodedBlock[i]);
            }
        }
        return ms.ToArray();
    }

    /// <summary>
    /// Encodes binary data into a plaintext ASCII85 format string
    /// </summary>
    /// <param name="ba">binary data to encode</param>
    /// <returns>ASCII85 encoded string</returns>
    public string encode(byte[] ba)
    {
        StringBuilder sb = new StringBuilder((int)(ba.Length *  
(_encodedBlock.Length / _decodedBlock.Length)));
        _linePos = 0;

        if (EnforceMarks)
        {
            AppendString(sb, PrefixMark);
        }

        int count = 0;
        _tuple = 0;
        foreach (byte b in ba)
        {
            if (count >= _decodedBlock.Length - 1)
            {
                _tuple |= b;
                if (_tuple == 0)
                {
                    AppendChar(sb, 'z');
                }
                else
                {
                    EncodeBlock(sb);
                }
                _tuple = 0;
                count = 0;
            }
            else
            {
                _tuple |= (uint)(b << (24 - (count * 8)));
                count++;
            }
        }

        if (count > 0)
        {
            EncodeBlock(count + 1, sb);
        }

        if (EnforceMarks)
        {
            AppendString(sb, SuffixMark);
        }
        return sb.ToString();
    }

    private void EncodeBlock(StringBuilder sb)
    {
        EncodeBlock(_encodedBlock.Length, sb);
    }

    private void EncodeBlock(int count, StringBuilder sb)
    {
        for (int i = _encodedBlock.Length - 1; i >= 0; i--)
        {
            _encodedBlock[i] = (byte)((_tuple % 85) + _asciiOffset);
            _tuple /= 85;
        }

        for (int i = 0; i < count; i++)
        {
            char c = (char)_encodedBlock[i];
            AppendChar(sb, c);
        }

    }

    private void DecodeBlock()
    {
        DecodeBlock(_decodedBlock.Length);
    }

    private void DecodeBlock(int bytes)
    {
        for (int i = 0; i < bytes; i++)
        {
            _decodedBlock[i] = (byte)(_tuple >> 24 - (i * 8));
        }
    }

    private void AppendString(StringBuilder sb, string s)
    {
        if (LineLength > 0 && (_linePos + s.Length > LineLength))
        {
            _linePos = 0;
            sb.Append('\n');
        }
        else
        {
            _linePos += s.Length;
        }
        sb.Append(s);
    }

    private void AppendChar(StringBuilder sb, char c)
    {
        sb.Append(c);
        _linePos++;
        if (LineLength > 0 && (_linePos >= LineLength))
        {
            _linePos = 0;
            sb.Append('\n');
        }
    }

    public string decode(byte[] ba)
    {
        throw new NotImplementedException();
    }
}
公共字节[]解码(字节[]编码输入)
{
布尔严格=假;
MemoryStream stream=新的MemoryStream(encodedInput);
充气输入流zip=新充气输入流(流);
MemoryStream输出=新的MemoryStream();
字节[]b=新字节[strict?4092:1];
尝试
{
int n;
而((n=zip.Read(b,0,b.Length))>0)
{
输出写入(b,0,n);
}
zip.Close();
output.Close();
return(output.ToArray());
}
抓住
{
如果(严格)
返回null;
return(output.ToArray());
}
}
//ASCII85解码
ASCII85类:IASCII85
{
/// 
///识别编码ASCII85字符串的前缀标记,传统上
''
/// 
公共字符串后缀标记=“~>”;
/// 
///编码ASCII85字符串的最大行长度;
///对于一条未中断的线,将其设置为零。
/// 
公共整数线宽=75;
/// 
///编码时添加前缀和后缀标记,并强制其
用于解码的存在
/// 
公共bool EnforceMarks=true;
私有常量int_asciiOffset=33;
私有字节[]_encodedBlock=新字节[5];
私有字节[]_decodedBlock=新字节[4];
私有uint _tuple=0;
私有整数_linePos=0;
私人单位[]功率85={85*85*85*85,85*85*85,85*85,85,
1 };
/// 
///将ASCII85编码字符串解码为原始二进制数据
/// 
///ASCII85编码字符串
///解码二进制数据的字节数组
公共字节[]解码(字符串输入字符串)
{
如果(强制执行标记)
{
boolx=!inputString.StartsWith(PrefixMark);
bool y=!inputString.EndsWith(后缀标记);
bool a=!inputString.StartsWith(PrefixMark)和
!inputString.EndsWith(后缀标记);
如果(a)
{
抛出新异常(“ASCII85编码数据应以
“+PrefixMark+
“'并以“+SuffixMark+””结尾”;
}
}
if(inputString.StartsWith(“”)
{
inputString=inputString.Substring(0,inputString.Length-
后缀标记长度);
}
MemoryStream ms=新的MemoryStream();
整数计数=0;
bool processChar=false;
foreach(inputString中的字符c)
{
开关(c)
{
案例“z”:
如果(计数!=0)
{
抛出新异常(“字符“z”无效
在ASCII85区块内。”);
}
_decodedBlock[0]=0;
_decodedBlock[1]=0;
_decodedBlock[2]=0;
_decodedBlock[3]=0;
ms.Write(_decodedBlock,0,_decodedBlock.Length);
processChar=false;
打破
案例“\n”:
案例'\r':
案例'\t':
案例“\0”:
案例'\f':
案例'\b':
processChar=false;
打破
违约:
如果(c<'!'| c>'u')
{
抛出新异常(“坏字符“+c+””
已找到。ASCI85仅允许字符“!”到“u”。);
}
processChar=true;
打破
}
if(processChar)
{
_元组+=((uint)(c-_asciiOffset)*pow85[计数];
计数++;
if(count==\u encodedBlock.Length)
{
解码块();
ms.Write(_decodedBlock,0,_decodedBlock.Length);
_元组=0;
计数=0;
}
}
}
如果(计数!=0)
{
如果(计数=1)
{
抛出新异常(“最后一块ASCII85数据无法
是一个单字节。“);
}
计数--;
_元组+=pow85[计数];
解码块(计数);
for(int i=0;i=\u decodedBlock.Length-1)
{
_元组|=b;
如果(_tuple==0)
{
(sb,'z');
}
其他的
{
编码块(sb);
}
_元组=0;
计数=0;
}
其他的
{
_元组|=(uint)(b0)
{
编码块(计数+1,sb);
}
如果(强制执行标记)
{
追加字符串(sb,后缀标记);
}
使某人返回字符串();
}
专用块(StringBuilder sb)
{
EncodeBlock(_encodedBlock.Length,sb);
ASCII85 ascii85 = new ASCII85();
ascii85.EnforceMarks = false;
byte[] ascii85Decoded = ascii85.decode(rawStreamChars);

using (MemoryStream stream = new MemoryStream(ascii85Decoded))
{
    // Remove 2 bytes zlib header
    stream.ReadByte();
    stream.ReadByte();
    using (DeflateStream decompressionStream = new DeflateStream(stream, CompressionMode.Decompress))
    using (MemoryStream result = new MemoryStream())
    {
        decompressionStream.CopyTo(result);
        Console.Out.WriteLine(Encoding.GetEncoding("windows-1252").GetString(result.ToArray()));
    }
}