🛀 cleanup

This commit is contained in:
codemasher
2021-06-05 01:16:21 +02:00
parent d60a4e0f55
commit f4401a4b2b
10 changed files with 72 additions and 42 deletions
+2 -2
View File
@@ -36,8 +36,8 @@ final class Binarizer{
// This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
// So this is the smallest dimension in each axis we can accept.
private const BLOCK_SIZE_POWER = 3;
private const BLOCK_SIZE = 8; // ...0100...00
private const BLOCK_SIZE_MASK = 7; // ...0011...11
private const BLOCK_SIZE = 8; // ...0100...00
private const BLOCK_SIZE_MASK = 7; // ...0011...11
private const MINIMUM_DIMENSION = 40;
private const MIN_DYNAMIC_RANGE = 24;
+1 -2
View File
@@ -13,7 +13,6 @@ namespace chillerlan\QRCode\Decoder;
use chillerlan\QRCode\Common\{MaskPattern, Version};
use InvalidArgumentException;
use function chillerlan\QRCode\Common\uRShift;
use function array_fill, count;
final class BitMatrix{
@@ -110,7 +109,7 @@ final class BitMatrix{
$this->bits[$offset] ??= 0;
return (uRShift($this->bits[$offset], ($x & 0x1f)) & 1) !== 0;
return (BitMatrixParser::uRShift($this->bits[$offset], ($x & 0x1f)) & 1) !== 0;
}
/**
+28 -5
View File
@@ -13,8 +13,7 @@ namespace chillerlan\QRCode\Decoder;
use RuntimeException;
use chillerlan\QRCode\Common\{Version, FormatInformation};
use function chillerlan\QRCode\Common\numBitsDiffering;
use const PHP_INT_MAX;
use const PHP_INT_MAX, PHP_INT_SIZE;
/**
* @author Sean Owen
@@ -219,7 +218,7 @@ final class BitMatrixParser{
return new FormatInformation($maskedBits);
}
$bitsDifference = numBitsDiffering($maskedFormatInfo1, $dataBits);
$bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $dataBits);
if($bitsDifference < $bestDifference){
$bestFormatInfo = $maskedBits;
@@ -228,7 +227,7 @@ final class BitMatrixParser{
if($maskedFormatInfo1 !== $maskedFormatInfo2){
// also try the other option
$bitsDifference = numBitsDiffering($maskedFormatInfo2, $dataBits);
$bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $dataBits);
if($bitsDifference < $bestDifference){
$bestFormatInfo = $maskedBits;
@@ -319,7 +318,7 @@ final class BitMatrixParser{
// Otherwise see if this is the closest to a real version info bit string
// we have seen so far
/** @phan-suppress-next-line PhanTypeMismatchArgumentNullable ($targetVersionPattern is never null here) */
$bitsDifference = numBitsDiffering($versionBits, $targetVersionPattern);
$bitsDifference = self::numBitsDiffering($versionBits, $targetVersionPattern);
if($bitsDifference < $bestDifference){
$bestVersion = $i;
@@ -336,4 +335,28 @@ final class BitMatrixParser{
return null;
}
public static function uRShift(int $a, int $b):int{
if($b === 0){
return $a;
}
return ($a >> $b) & ~((1 << (8 * PHP_INT_SIZE - 1)) >> ($b - 1));
}
private static function numBitsDiffering(int $a, int $b):int{
// a now has a 1 bit exactly where its bit differs with b's
$a ^= $b;
// Offset i holds the number of 1 bits in the binary representation of i
$BITS_SET_IN_HALF_BYTE = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4];
// Count bits set quickly with a series of lookups:
$count = 0;
for($i = 0; $i < 32; $i += 4){
$count += $BITS_SET_IN_HALF_BYTE[self::uRShift($a, $i) & 0x0F];
}
return $count;
}
}
+6 -2
View File
@@ -12,7 +12,7 @@
namespace chillerlan\QRCode\Decoder;
use InvalidArgumentException;
use function chillerlan\QRCode\Common\arraycopy;
use function array_slice, array_splice;
/**
* The purpose of this class hierarchy is to abstract different bitmap implementations across
@@ -82,7 +82,11 @@ abstract class LuminanceSource{
throw new InvalidArgumentException('Requested row is outside the image: '.$y);
}
return arraycopy($this->luminances, $y * $this->width, [], 0, $this->width);
$arr = [];
array_splice($arr, 0, $this->width, array_slice($this->luminances, $y * $this->width, $this->width));
return $arr;
}
/**
+1 -4
View File
@@ -14,7 +14,6 @@ namespace chillerlan\QRCode\Detector;
use chillerlan\QRCode\Decoder\BitMatrix;
use function abs, count;
/**
* <p>This class attempts to find alignment patterns in a QR Code. Alignment patterns look like finder
* patterns but are smaller and appear at regular intervals throughout the image.</p>
@@ -35,7 +34,6 @@ final class AlignmentPatternFinder{
private float $moduleSize;
/** @var \chillerlan\QRCode\Detector\AlignmentPattern[] */
private array $possibleCenters;
private array $crossCheckStateCount;
/**
* <p>Creates a finder that will look in a portion of the whole image.</p>
@@ -47,7 +45,6 @@ final class AlignmentPatternFinder{
$this->bitMatrix = $image;
$this->moduleSize = $moduleSize;
$this->possibleCenters = [];
$this->crossCheckStateCount = [];
}
/**
@@ -228,7 +225,7 @@ final class AlignmentPatternFinder{
*/
private function crossCheckVertical(int $startI, int $centerJ, int $maxCount, int $originalStateCountTotal):?float{
$maxI = $this->bitMatrix->getDimension();
$stateCount = $this->crossCheckStateCount;
$stateCount = [];
$stateCount[0] = 0;
$stateCount[1] = 0;
$stateCount[2] = 0;
+4 -5
View File
@@ -15,7 +15,6 @@ use RuntimeException;
use chillerlan\QRCode\Common\Version;
use chillerlan\QRCode\Decoder\BitMatrix;
use function abs, is_nan, max, min, round;
use function chillerlan\QRCode\Common\distance;
use const NAN;
/**
@@ -210,7 +209,7 @@ final class Detector{
if(($state === 1) === $this->bitMatrix->get($realX, $realY)){
if($state === 2){
return distance($x, $y, $fromX, $fromY);
return FinderPattern::distance($x, $y, $fromX, $fromY);
}
$state++;
@@ -233,7 +232,7 @@ final class Detector{
// is "white" so this last po$at (toX+xStep,toY) is the right ending. This is really a
// small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this.
if($state === 2){
return distance($toX + $xstep, $toY, $fromX, $fromY);
return FinderPattern::distance($toX + $xstep, $toY, $fromX, $fromY);
}
// else we didn't find even black-white-black; no estimate is really possible
@@ -252,8 +251,8 @@ final class Detector{
FinderPattern $bottomLeft,
float $moduleSize
):int{
$tltrCentersDimension = (int)round($topLeft->distance($topRight) / $moduleSize);
$tlblCentersDimension = (int)round($topLeft->distance($bottomLeft) / $moduleSize);
$tltrCentersDimension = (int)round($topLeft->getDistance($topRight) / $moduleSize);
$tlblCentersDimension = (int)round($topLeft->getDistance($bottomLeft) / $moduleSize);
$dimension = (int)((($tltrCentersDimension + $tlblCentersDimension) / 2) + 7);
switch($dimension % 4){
+18 -7
View File
@@ -11,7 +11,7 @@
namespace chillerlan\QRCode\Detector;
use function chillerlan\QRCode\Common\{distance, squaredDistance};
use function sqrt;
/**
* <p>Encapsulates a finder pattern, which are the three square patterns found in
@@ -24,10 +24,10 @@ final class FinderPattern extends ResultPoint{
private int $count;
public function __construct(float $posX, float $posY, float $estimatedModuleSize, int $count = 1){
public function __construct(float $posX, float $posY, float $estimatedModuleSize, int $count = null){
parent::__construct($posX, $posY, $estimatedModuleSize);
$this->count = $count;
$this->count = $count ?? 1;
}
public function getCount():int{
@@ -39,15 +39,15 @@ final class FinderPattern extends ResultPoint{
*
* @return float distance between two points
*/
public function distance(FinderPattern $b):float{
return distance($this->getX(), $this->getY(), $b->getX(), $b->getY());
public function getDistance(FinderPattern $b):float{
return self::distance($this->x, $this->y, $b->x, $b->y);
}
/**
* Get square of distance between a and b.
*/
public function squaredDistance(FinderPattern $b):float{
return squaredDistance($this->getX(), $this->getY(), $b->getX(), $b->getY());
public function getSquaredDistance(FinderPattern $b):float{
return self::squaredDistance($this->x, $this->y, $b->x, $b->y);
}
/**
@@ -66,4 +66,15 @@ final class FinderPattern extends ResultPoint{
);
}
private static function squaredDistance(float $aX, float $aY, float $bX, float $bY):float{
$xDiff = $aX - $bX;
$yDiff = $aY - $bY;
return $xDiff * $xDiff + $yDiff * $yDiff;
}
public static function distance(float $aX, float $aY, float $bX, float $bY):float{
return sqrt(self::squaredDistance($aX, $aY, $bX, $bY));
}
}
+8 -11
View File
@@ -35,8 +35,6 @@ final class FinderPatternFinder{
/** @var \chillerlan\QRCode\Detector\FinderPattern[] */
private array $possibleCenters;
private bool $hasSkipped = false;
/** @var int[] */
private array $crossCheckStateCount;
/**
* <p>Creates a finder that will search the image for three finder patterns.</p>
@@ -44,9 +42,8 @@ final class FinderPatternFinder{
* @param BitMatrix $bitMatrix image to search
*/
public function __construct(BitMatrix $bitMatrix){
$this->bitMatrix = $bitMatrix;
$this->possibleCenters = [];
$this->crossCheckStateCount = $this->getCrossCheckStateCount();
$this->bitMatrix = $bitMatrix;
$this->possibleCenters = [];
}
/**
@@ -649,7 +646,7 @@ final class FinderPatternFinder{
for($j = $i + 1; $j < $startSize - 1; $j++){
$fpj = $this->possibleCenters[$j];
$squares0 = $fpi->squaredDistance($fpj);
$squares0 = $fpi->getSquaredDistance($fpj);
for($k = $j + 1; $k < $startSize; $k++){
$fpk = $this->possibleCenters[$k];
@@ -661,8 +658,8 @@ final class FinderPatternFinder{
}
$a = $squares0;
$b = $fpj->squaredDistance($fpk);
$c = $fpi->squaredDistance($fpk);
$b = $fpj->getSquaredDistance($fpk);
$c = $fpi->getSquaredDistance($fpk);
// sorts ascending - inlined
if($a < $b){
@@ -734,9 +731,9 @@ final class FinderPatternFinder{
private function orderBestPatterns(array $patterns):array{
// Find distances between pattern centers
$zeroOneDistance = $patterns[0]->distance($patterns[1]);
$oneTwoDistance = $patterns[1]->distance($patterns[2]);
$zeroTwoDistance = $patterns[0]->distance($patterns[2]);
$zeroOneDistance = $patterns[0]->getDistance($patterns[1]);
$oneTwoDistance = $patterns[1]->getDistance($patterns[2]);
$zeroTwoDistance = $patterns[0]->getDistance($patterns[2]);
// Assume one closest to other two is B; A and C will just be guesses at first
if($oneTwoDistance >= $zeroOneDistance && $oneTwoDistance >= $zeroTwoDistance){
+2 -2
View File
@@ -132,10 +132,10 @@ final class GridSampler{
for($y = 0; $y < $dimension; $y++){
$max = count($points);
$iValue = (float)$y + 0.5;
$iValue = $y + 0.5;
for($x = 0; $x < $max; $x += 2){
$points[$x] = (float)($x / 2) + 0.5;
$points[$x] = ($x / 2) + 0.5;
$points[$x + 1] = $iValue;
}
+2 -2
View File
@@ -32,11 +32,11 @@ abstract class ResultPoint{
}
public function getX():float{
return (float)$this->x;
return $this->x;
}
public function getY():float{
return (float)$this->y;
return $this->y;
}
public function getEstimatedModuleSize():float{