Differences Between: [Versions 310 and 311] [Versions 311 and 403] [Versions 39 and 311]
1 <?php 2 3 /** 4 * This file is part of FPDI 5 * 6 * @package setasign\Fpdi 7 * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com) 8 * @license http://opensource.org/licenses/mit-license The MIT License 9 */ 10 11 namespace setasign\Fpdi\PdfParser\Filter; 12 13 /** 14 * Class for handling LZW encoded data 15 */ 16 class Lzw implements FilterInterface 17 { 18 /** 19 * @var null|string 20 */ 21 protected $data; 22 23 /** 24 * @var array 25 */ 26 protected $sTable = []; 27 28 /** 29 * @var int 30 */ 31 protected $dataLength = 0; 32 33 /** 34 * @var int 35 */ 36 protected $tIdx; 37 38 /** 39 * @var int 40 */ 41 protected $bitsToGet = 9; 42 43 /** 44 * @var int 45 */ 46 protected $bytePointer; 47 48 /** 49 * @var int 50 */ 51 protected $nextData = 0; 52 53 /** 54 * @var int 55 */ 56 protected $nextBits = 0; 57 58 /** 59 * @var array 60 */ 61 protected $andTable = [511, 1023, 2047, 4095]; 62 63 /** 64 * Method to decode LZW compressed data. 65 * 66 * @param string $data The compressed data 67 * @return string The uncompressed data 68 * @throws LzwException 69 */ 70 public function decode($data) 71 { 72 if ($data[0] === "\x00" && $data[1] === "\x01") { 73 throw new LzwException( 74 'LZW flavour not supported.', 75 LzwException::LZW_FLAVOUR_NOT_SUPPORTED 76 ); 77 } 78 79 $this->initsTable(); 80 81 $this->data = $data; 82 $this->dataLength = \strlen($data); 83 84 // Initialize pointers 85 $this->bytePointer = 0; 86 87 $this->nextData = 0; 88 $this->nextBits = 0; 89 90 $oldCode = 0; 91 92 $uncompData = ''; 93 94 while (($code = $this->getNextCode()) !== 257) { 95 if ($code === 256) { 96 $this->initsTable(); 97 $code = $this->getNextCode(); 98 99 if ($code === 257) { 100 break; 101 } 102 103 $uncompData .= $this->sTable[$code]; 104 $oldCode = $code; 105 } else { 106 if ($code < $this->tIdx) { 107 $string = $this->sTable[$code]; 108 $uncompData .= $string; 109 110 $this->addStringToTable($this->sTable[$oldCode], $string[0]); 111 $oldCode = $code; 112 } else { 113 $string = $this->sTable[$oldCode]; 114 $string .= $string[0]; 115 $uncompData .= $string; 116 117 $this->addStringToTable($string); 118 $oldCode = $code; 119 } 120 } 121 } 122 123 return $uncompData; 124 } 125 126 /** 127 * Initialize the string table. 128 */ 129 protected function initsTable() 130 { 131 $this->sTable = []; 132 133 for ($i = 0; $i < 256; $i++) { 134 $this->sTable[$i] = \chr($i); 135 } 136 137 $this->tIdx = 258; 138 $this->bitsToGet = 9; 139 } 140 141 /** 142 * Add a new string to the string table. 143 * 144 * @param string $oldString 145 * @param string $newString 146 */ 147 protected function addStringToTable($oldString, $newString = '') 148 { 149 $string = $oldString . $newString; 150 151 // Add this new String to the table 152 $this->sTable[$this->tIdx++] = $string; 153 154 if ($this->tIdx === 511) { 155 $this->bitsToGet = 10; 156 } elseif ($this->tIdx === 1023) { 157 $this->bitsToGet = 11; 158 } elseif ($this->tIdx === 2047) { 159 $this->bitsToGet = 12; 160 } 161 } 162 163 /** 164 * Returns the next 9, 10, 11 or 12 bits. 165 * 166 * @return integer 167 */ 168 protected function getNextCode() 169 { 170 if ($this->bytePointer === $this->dataLength) { 171 return 257; 172 } 173 174 $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff); 175 $this->nextBits += 8; 176 177 if ($this->nextBits < $this->bitsToGet) { 178 $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff); 179 $this->nextBits += 8; 180 } 181 182 $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet - 9]; 183 $this->nextBits -= $this->bitsToGet; 184 185 return $code; 186 } 187 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body