/** * <p>Reads format information from one of its two locations within the QR Code.</p> * * @return {@link FormatInformation} encapsulating the QR Code's format info * @throws FormatException if both format information locations cannot be parsed as * the valid encoding of format information */ function readFormatInformation() { if ($this->parsedFormatInfo != null) { return $this->parsedFormatInfo; } // Read top-left format info bits $formatInfoBits1 = 0; for ($i = 0; $i < 6; $i++) { $formatInfoBits1 = $this->copyBit($i, 8, $formatInfoBits1); } // .. and skip a bit in the timing pattern ... $formatInfoBits1 = $this->copyBit(7, 8, $formatInfoBits1); $formatInfoBits1 = $this->copyBit(8, 8, $formatInfoBits1); $formatInfoBits1 = $this->copyBit(8, 7, $formatInfoBits1); // .. and skip a bit in the timing pattern ... for ($j = 5; $j >= 0; $j--) { $formatInfoBits1 = $this->copyBit(8, $j, $formatInfoBits1); } // Read the top-right/bottom-left pattern too $dimension = $this->bitMatrix->getHeight(); $formatInfoBits2 = 0; $jMin = $dimension - 7; for ($j = $dimension - 1; $j >= $jMin; $j--) { $formatInfoBits2 = $this->copyBit(8, $j, $formatInfoBits2); } for ($i = $dimension - 8; $i < $dimension; $i++) { $formatInfoBits2 = $this->copyBit($i, 8, $formatInfoBits2); } $parsedFormatInfo = FormatInformation::decodeFormatInformation($formatInfoBits1, $formatInfoBits2); if ($parsedFormatInfo != null) { return $parsedFormatInfo; } throw FormatException::getFormatInstance(); }
static function decodeVersionInformation($versionBits) { $bestDifference = PHP_INT_MAX; $bestVersion = 0; for ($i = 0; $i < count(self::$VERSION_DECODE_INFO); $i++) { $targetVersion = self::$VERSION_DECODE_INFO[$i]; // Do the version info bits match exactly? done. if ($targetVersion == $versionBits) { return self::getVersionForNumber($i + 7); } // Otherwise see if this is the closest to a real version info bit string // we have seen so far $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion); if ($bitsDifference < $bestDifference) { $bestVersion = $i + 7; $bestDifference = $bitsDifference; } } // We can tolerate up to 3 bits of error since no two version info codewords will // differ in less than 8 bits. if ($bestDifference <= 3) { return self::getVersionForNumber($bestVersion); } // If we didn't find a close enough match, fail return null; }