1
#region PDFsharp - A .NET library for processing PDF
4
// David Stephensen (mailto:David.Stephensen@pdfsharp.com)
6
// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
8
// http://www.pdfsharp.com
9
// http://sourceforge.net/projects/pdfsharp
11
// Permission is hereby granted, free of charge, to any person obtaining a
12
// copy of this software and associated documentation files (the "Software"),
13
// to deal in the Software without restriction, including without limitation
14
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
// and/or sell copies of the Software, and to permit persons to whom the
16
// Software is furnished to do so, subject to the following conditions:
18
// The above copyright notice and this permission notice shall be included
19
// in all copies or substantial portions of the Software.
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
// DEALINGS IN THE SOFTWARE.
31
using System.Diagnostics;
35
namespace PdfSharp.Pdf.Filters
38
/// Implements the LzwDecode filter.
40
public class LzwDecode : Filter
43
/// Throws a NotImplementedException because the obsolete LZW encoding is not supported by PDFsharp.
45
public override byte[] Encode(byte[] data)
47
throw new NotImplementedException("PDFsharp does not support LZW encoding.");
51
/// Decodes the specified data.
53
public override byte[] Decode(byte[] data, FilterParms parms)
55
if (data[0] == (byte)0x00 && data[1] == (byte)0x01)
56
throw new Exception("LZW flavour not supported.");
58
MemoryStream outputStream = new MemoryStream();
60
InitializeDictionary();
69
int code, oldCode = 0;
72
while ((code = this.NextCode) != 257)
76
InitializeDictionary();
82
outputStream.Write(stringTable[code], 0, stringTable[code].Length);
88
if (code < tableIndex)
90
str = stringTable[code];
91
outputStream.Write(str, 0, str.Length);
92
AddEntry(stringTable[oldCode], str[0]);
97
str = stringTable[oldCode];
98
outputStream.Write(str, 0, str.Length);
99
AddEntry(str, str[0]);
105
if (outputStream.Length >= 0)
107
outputStream.Capacity = (int)outputStream.Length;
108
return outputStream.GetBuffer();
114
/// Initialize the dictionary.
116
void InitializeDictionary()
118
stringTable = new byte[8192][];
120
for (int i = 0; i < 256; i++)
122
stringTable[i] = new byte[1];
123
stringTable[i][0] = (byte)i;
131
/// Add a new entry to the Dictionary.
133
void AddEntry(byte[] oldstring, byte newstring)
135
int length = oldstring.Length;
136
byte[] str = new byte[length + 1];
137
Array.Copy(oldstring, 0, str, 0, length);
138
str[length] = newstring;
140
stringTable[tableIndex++] = str;
142
if (tableIndex == 511)
144
else if (tableIndex == 1023)
146
else if (tableIndex == 2047)
151
/// Returns the next set of bits.
159
nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
162
if (nextBits < bitsToGet)
164
nextData = (nextData << 8) | (data[bytePointer++] & 0xff);
168
int code = (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet - 9];
169
nextBits -= bitsToGet;
180
int[] andTable = { 511, 1023, 2047, 4095 };
181
byte[][] stringTable;
183
int tableIndex, bitsToGet = 9;