1 | <?php |
---|
2 | // |
---|
3 | // FPDI - Version 1.2 |
---|
4 | // |
---|
5 | // Copyright 2004-2007 Setasign - Jan Slabon |
---|
6 | // |
---|
7 | // Licensed under the Apache License, Version 2.0 (the "License"); |
---|
8 | // you may not use this file except in compliance with the License. |
---|
9 | // You may obtain a copy of the License at |
---|
10 | // |
---|
11 | // http://www.apache.org/licenses/LICENSE-2.0 |
---|
12 | // |
---|
13 | // Unless required by applicable law or agreed to in writing, software |
---|
14 | // distributed under the License is distributed on an "AS IS" BASIS, |
---|
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
---|
16 | // See the License for the specific language governing permissions and |
---|
17 | // limitations under the License. |
---|
18 | // |
---|
19 | |
---|
20 | class LZWDecode { |
---|
21 | |
---|
22 | var $sTable = array(); |
---|
23 | var $data = null; |
---|
24 | var $tIdx; |
---|
25 | var $bitsToGet = 9; |
---|
26 | var $bytePointer; |
---|
27 | var $bitPointer; |
---|
28 | var $nextData = 0; |
---|
29 | var $nextBits = 0; |
---|
30 | var $andTable = array(511, 1023, 2047, 4095); |
---|
31 | |
---|
32 | function LZWDecode(&$fpdi) { |
---|
33 | $this->fpdi =& $fpdi; |
---|
34 | } |
---|
35 | |
---|
36 | /** |
---|
37 | * Method to decode LZW compressed data. |
---|
38 | * |
---|
39 | * @param string data The compressed data. |
---|
40 | */ |
---|
41 | function decode(&$data) { |
---|
42 | |
---|
43 | if($data[0] == 0x00 && $data[1] == 0x01) { |
---|
44 | $this->fpdi->error("LZW flavour not supported."); |
---|
45 | } |
---|
46 | |
---|
47 | $this->initsTable(); |
---|
48 | |
---|
49 | $this->data =& $data; |
---|
50 | |
---|
51 | // Initialize pointers |
---|
52 | $this->bytePointer = 0; |
---|
53 | $this->bitPointer = 0; |
---|
54 | |
---|
55 | $this->nextData = 0; |
---|
56 | $this->nextBits = 0; |
---|
57 | |
---|
58 | $oldCode = 0; |
---|
59 | |
---|
60 | $string = ""; |
---|
61 | $uncompData = ""; |
---|
62 | |
---|
63 | while (($code = $this->getNextCode()) != 257) { |
---|
64 | if ($code == 256) { |
---|
65 | $this->initsTable(); |
---|
66 | $code = $this->getNextCode(); |
---|
67 | |
---|
68 | if ($code == 257) { |
---|
69 | break; |
---|
70 | } |
---|
71 | |
---|
72 | $uncompData .= $this->sTable[$code]; |
---|
73 | $oldCode = $code; |
---|
74 | |
---|
75 | } else { |
---|
76 | |
---|
77 | if ($code < $this->tIdx) { |
---|
78 | $string = $this->sTable[$code]; |
---|
79 | $uncompData .= $string; |
---|
80 | |
---|
81 | $this->addStringToTable($this->sTable[$oldCode], $string[0]); |
---|
82 | $oldCode = $code; |
---|
83 | } else { |
---|
84 | $string = $this->sTable[$oldCode]; |
---|
85 | $string = $string.$string[0]; |
---|
86 | $uncompData .= $string; |
---|
87 | |
---|
88 | $this->addStringToTable($string); |
---|
89 | $oldCode = $code; |
---|
90 | } |
---|
91 | } |
---|
92 | } |
---|
93 | |
---|
94 | return $uncompData; |
---|
95 | } |
---|
96 | |
---|
97 | |
---|
98 | /** |
---|
99 | * Initialize the string table. |
---|
100 | */ |
---|
101 | function initsTable() { |
---|
102 | $this->sTable = array(); |
---|
103 | |
---|
104 | for ($i = 0; $i < 256; $i++) |
---|
105 | $this->sTable[$i] = chr($i); |
---|
106 | |
---|
107 | $this->tIdx = 258; |
---|
108 | $this->bitsToGet = 9; |
---|
109 | } |
---|
110 | |
---|
111 | /** |
---|
112 | * Add a new string to the string table. |
---|
113 | */ |
---|
114 | function addStringToTable ($oldString, $newString="") { |
---|
115 | $string = $oldString.$newString; |
---|
116 | |
---|
117 | // Add this new String to the table |
---|
118 | $this->sTable[$this->tIdx++] = $string; |
---|
119 | |
---|
120 | if ($this->tIdx == 511) { |
---|
121 | $this->bitsToGet = 10; |
---|
122 | } else if ($this->tIdx == 1023) { |
---|
123 | $this->bitsToGet = 11; |
---|
124 | } else if ($this->tIdx == 2047) { |
---|
125 | $this->bitsToGet = 12; |
---|
126 | } |
---|
127 | } |
---|
128 | |
---|
129 | // Returns the next 9, 10, 11 or 12 bits |
---|
130 | function getNextCode() { |
---|
131 | if ($this->bytePointer == strlen($this->data)) |
---|
132 | return 257; |
---|
133 | |
---|
134 | $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff); |
---|
135 | $this->nextBits += 8; |
---|
136 | |
---|
137 | if ($this->nextBits < $this->bitsToGet) { |
---|
138 | $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff); |
---|
139 | $this->nextBits += 8; |
---|
140 | } |
---|
141 | |
---|
142 | $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9]; |
---|
143 | $this->nextBits -= $this->bitsToGet; |
---|
144 | |
---|
145 | return $code; |
---|
146 | } |
---|
147 | } |
---|
148 | |
---|
149 | |
---|
150 | |
---|
151 | ?> |
---|