/**
  * <p>Deduces version information purely from QR Code dimensions.</p>
  *
  * @param dimension dimension in modules
  * @return Version for a QR Code of that dimension
  * @throws FormatException if dimension is not 1 mod 4
  */
 public static function getProvisionalVersionForDimension($dimension)
 {
     if ($dimension % 4 != 1) {
         throw FormatException::getFormatInstance();
     }
     try {
         return self::getVersionForNumber(($dimension - 17) / 4);
     } catch (InvalidArgumentException $ignored) {
         throw FormatException::getFormatInstance();
     }
 }
 private static function parseECIValue($bits)
 {
     $firstByte = $bits->readBits(8);
     if (($firstByte & 0x80) == 0) {
         // just one byte
         return $firstByte & 0x7f;
     }
     if (($firstByte & 0xc0) == 0x80) {
         // two bytes
         $secondByte = $bits->readBits(8);
         return ($firstByte & 0x3f) << 8 | $secondByte;
     }
     if (($firstByte & 0xe0) == 0xc0) {
         // three bytes
         $secondThirdBytes = $bits->readBits(16);
         return ($firstByte & 0x1f) << 16 | $secondThirdBytes;
     }
     throw FormatException::getFormatInstance();
 }
 /**
  * <p>Reads the bits in the {@link BitMatrix} representing the finder pattern in the
  * correct order in order to reconstruct the codewords bytes contained within the
  * QR Code.</p>
  *
  * @return bytes encoded within the QR Code
  * @throws FormatException if the exact number of bytes expected is not read
  */
 function readCodewords()
 {
     $formatInfo = $this->readFormatInformation();
     $version = $this->readVersion();
     // Get the data mask for the format used in this QR Code. This will exclude
     // some bits from reading as we wind through the bit matrix.
     $dataMask = DataMask::forReference($formatInfo->getDataMask());
     $dimension = $this->bitMatrix->getHeight();
     $dataMask->unmaskBitMatrix($this->bitMatrix, $dimension);
     $functionPattern = $version->buildFunctionPattern();
     $readingUp = true;
     if ($version->getTotalCodewords()) {
         $result = fill_array(0, $version->getTotalCodewords(), 0);
     } else {
         $result = array();
     }
     $resultOffset = 0;
     $currentByte = 0;
     $bitsRead = 0;
     // Read columns in pairs, from right to left
     for ($j = $dimension - 1; $j > 0; $j -= 2) {
         if ($j == 6) {
             // Skip whole column with vertical alignment pattern;
             // saves time and makes the other code proceed more cleanly
             $j--;
         }
         // Read alternatingly from bottom to top then top to bottom
         for ($count = 0; $count < $dimension; $count++) {
             $i = $readingUp ? $dimension - 1 - $count : $count;
             for ($col = 0; $col < 2; $col++) {
                 // Ignore bits covered by the function pattern
                 if (!$functionPattern->get($j - $col, $i)) {
                     // Read a bit
                     $bitsRead++;
                     $currentByte <<= 1;
                     if ($this->bitMatrix->get($j - $col, $i)) {
                         $currentByte |= 1;
                     }
                     // If we've made a whole byte, save it off
                     if ($bitsRead == 8) {
                         $result[$resultOffset++] = $currentByte;
                         //(byte)
                         $bitsRead = 0;
                         $currentByte = 0;
                     }
                 }
             }
         }
         $readingUp ^= true;
         // readingUp = !readingUp; // switch directions
     }
     if ($resultOffset != $version->getTotalCodewords()) {
         throw FormatException::getFormatInstance();
     }
     return $result;
 }