/** * Read in code lengths for symbols first to last in the given table. * The code lengths are stored in their own special LZX way. * * @param BitReader $reader The reader that provides the data. * @param int $first * @param int $last */ public function readLengthTable(BitReader $reader, $first, $last) { $preTree = new self(6, static::PRETREE_NUM_ELEMENTS); for ($i = 0; $i < $preTree->maxSymbol; ++$i) { $preTree->lens[$i] = $reader->readLE(4); } $preTree->makeSymbolTable(); for ($pos = $first; $pos < $last;) { $symbol = $preTree->readHuffmanSymbol($reader); switch ($symbol) { case 0x11: $pos2 = $pos + $reader->readLE(4) + 4; while ($pos < $pos2) { $this->lens[$pos++] = 0; } break; case 0x12: $pos2 = $pos + $reader->readLE(5) + 20; while ($pos < $pos2) { $this->lens[$pos++] = 0; } break; case 0x13: $pos2 = $pos + $reader->readLE(1) + 4; $symbol = $this->lens[$pos] - $preTree->readHuffmanSymbol($reader); if ($symbol < 0) { $symbol += 0x11; } while ($pos < $pos2) { $this->lens[$pos++] = $symbol; } break; default: $symbol = $this->lens[$pos] - $symbol; if ($symbol < 0) { $symbol += 0x11; } $this->lens[$pos++] = $symbol; break; } } }