MDL-49515 libraries: Update FPDI to 1.5.4
[moodle.git] / mod / assign / feedback / editpdf / fpdi / filters / FilterLZW.php
1 <?php
2 //
3 //  FPDI - Version 1.5.4
4 //
5 //    Copyright 2004-2015 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 //
20 /**
21  * Class FilterLZW
22  */
23 class FilterLZW
24 {
25     protected $_sTable = array();
26     protected $_data = null;
27     protected $_dataLength = 0;
28     protected $_tIdx;
29     protected $_bitsToGet = 9;
30     protected $_bytePointer;
31     protected $_bitPointer;
32     protected $_nextData = 0;
33     protected $_nextBits = 0;
34     protected $_andTable = array(511, 1023, 2047, 4095);
36     /**
37      * Decodes LZW compressed data.
38      *
39      * @param string $data The compressed data.
40      * @throws Exception
41      * @return string
42      */
43     public function decode($data)
44     {
45         if ($data[0] == 0x00 && $data[1] == 0x01) {
46             throw new Exception('LZW flavour not supported.');
47         }
49         $this->_initsTable();
51         $this->_data = $data;
52         $this->_dataLength = strlen($data);
54         // Initialize pointers
55         $this->_bytePointer = 0;
56         $this->_bitPointer = 0;
58         $this->_nextData = 0;
59         $this->_nextBits = 0;
61         $oldCode = 0;
63         $unCompData = '';
65         while (($code = $this->_getNextCode()) != 257) {
66             if ($code == 256) {
67                 $this->_initsTable();
68                 $code = $this->_getNextCode();
70                 if ($code == 257) {
71                     break;
72                 }
74                 if (!isset($this->_sTable[$code])) {
75                     throw new Exception('Error while decompression LZW compressed data.');
76                 }
78                 $unCompData .= $this->_sTable[$code];
79                 $oldCode = $code;
81             } else {
83                 if ($code < $this->_tIdx) {
84                     $string = $this->_sTable[$code];
85                     $unCompData .= $string;
87                     $this->_addStringToTable($this->_sTable[$oldCode], $string[0]);
88                     $oldCode = $code;
89                 } else {
90                     $string = $this->_sTable[$oldCode];
91                     $string = $string . $string[0];
92                     $unCompData .= $string;
94                     $this->_addStringToTable($string);
95                     $oldCode = $code;
96                 }
97             }
98         }
100         return $unCompData;
101     }
104     /**
105      * Initialize the string table.
106      */
107     protected function _initsTable()
108     {
109         $this->_sTable = array();
111         for ($i = 0; $i < 256; $i++)
112             $this->_sTable[$i] = chr($i);
114         $this->_tIdx = 258;
115         $this->_bitsToGet = 9;
116     }
118     /**
119      * Add a new string to the string table.
120      */
121     protected function _addStringToTable($oldString, $newString = '')
122     {
123         $string = $oldString . $newString;
125         // Add this new String to the table
126         $this->_sTable[$this->_tIdx++] = $string;
128         if ($this->_tIdx == 511) {
129             $this->_bitsToGet = 10;
130         } else if ($this->_tIdx == 1023) {
131             $this->_bitsToGet = 11;
132         } else if ($this->_tIdx == 2047) {
133             $this->_bitsToGet = 12;
134         }
135     }
137     /**
138      * Returns the next 9, 10, 11 or 12 bits
139      *
140      * @return int
141      */
142     protected function _getNextCode()
143     {
144         if ($this->_bytePointer == $this->_dataLength) {
145             return 257;
146         }
148         $this->_nextData = ($this->_nextData << 8) | (ord($this->_data[$this->_bytePointer++]) & 0xff);
149         $this->_nextBits += 8;
151         if ($this->_nextBits < $this->_bitsToGet) {
152             $this->_nextData = ($this->_nextData << 8) | (ord($this->_data[$this->_bytePointer++]) & 0xff);
153             $this->_nextBits += 8;
154         }
156         $code = ($this->_nextData >> ($this->_nextBits - $this->_bitsToGet)) & $this->_andTable[$this->_bitsToGet-9];
157         $this->_nextBits -= $this->_bitsToGet;
159         return $code;
160     }
162     /**
163      * NOT IMPLEMENTED
164      *
165      * @param string $in
166      * @return string
167      * @throws LogicException
168      */
169     public function encode($in)
170     {
171         throw new LogicException("LZW encoding not implemented.");
172     }