🚿 clean up some (int) casts

This commit is contained in:
smiley
2023-07-12 21:23:43 +02:00
parent edbc995b63
commit 5a280c8107
13 changed files with 89 additions and 81 deletions
+6 -6
View File
@@ -14,7 +14,7 @@ namespace chillerlan\QRCode\Common;
use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\QRCode\QRCodeException;
use Closure;
use function abs, array_search, count, min;
use function abs, array_search, count, intdiv, min;
/**
* ISO/IEC 18004:2000 Section 8.8.1
@@ -102,10 +102,10 @@ final class MaskPattern{
self::PATTERN_001 => fn(int $x, int $y):bool => ($y % 2) === 0,
self::PATTERN_010 => fn(int $x, int $y):bool => ($x % 3) === 0,
self::PATTERN_011 => fn(int $x, int $y):bool => (($x + $y) % 3) === 0,
self::PATTERN_100 => fn(int $x, int $y):bool => (((int)($y / 2) + (int)($x / 3)) % 2) === 0,
self::PATTERN_101 => fn(int $x, int $y):bool => (($x * $y) % 6) === 0, // ((($x * $y) % 2) + (($x * $y) % 3)) === 0,
self::PATTERN_110 => fn(int $x, int $y):bool => (($x * $y) % 6) < 3, // (((($x * $y) % 2) + (($x * $y) % 3)) % 2) === 0,
self::PATTERN_111 => fn(int $x, int $y):bool => (($x + $y + (($x * $y) % 3)) % 2) === 0, // (((($x * $y) % 3) + (($x + $y) % 2)) % 2) === 0,
self::PATTERN_100 => fn(int $x, int $y):bool => ((intdiv($y, 2) + intdiv($x, 3)) % 2) === 0,
self::PATTERN_101 => fn(int $x, int $y):bool => (($x * $y) % 6) === 0,
self::PATTERN_110 => fn(int $x, int $y):bool => (($x * $y) % 6) < 3,
self::PATTERN_111 => fn(int $x, int $y):bool => (($x + $y + (($x * $y) % 3)) % 2) === 0,
][$this->maskPattern];
}
@@ -310,7 +310,7 @@ final class MaskPattern{
}
}
return ((int)(abs($darkCells * 2 - $totalCells) * 10 / $totalCells) * 10);
return (intdiv((abs($darkCells * 2 - $totalCells) * 10), $totalCells) * 10);
}
}
+2 -2
View File
@@ -12,7 +12,7 @@ namespace chillerlan\QRCode\Data;
use chillerlan\QRCode\Common\{BitBuffer, Mode};
use function array_flip, ceil, str_split;
use function array_flip, ceil, intdiv, str_split;
/**
* Alphanumeric mode: 0 to 9, A to Z, space, $ % * + - . / :
@@ -118,7 +118,7 @@ final class AlphaNum extends QRDataModeAbstract{
}
$nextTwoCharsBits = $bitBuffer->read(11);
$result .= $toAlphaNumericChar((int)($nextTwoCharsBits / 45));
$result .= $toAlphaNumericChar(intdiv($nextTwoCharsBits, 45));
$result .= $toAlphaNumericChar($nextTwoCharsBits % 45);
$length -= 2;
}
+2 -2
View File
@@ -13,7 +13,7 @@ namespace chillerlan\QRCode\Data;
use chillerlan\QRCode\Common\{BitBuffer, Mode};
use Throwable;
use function chr, implode, is_string, mb_convert_encoding, mb_detect_encoding,
use function chr, implode, intdiv, is_string, mb_convert_encoding, mb_detect_encoding,
mb_detect_order, mb_internal_encoding, mb_strlen, ord, sprintf, strlen;
/**
@@ -188,7 +188,7 @@ final class Hanzi extends QRDataModeAbstract{
while($length > 0){
// Each 13 bits encodes a 2-byte character
$twoBytes = $bitBuffer->read(13);
$assembledTwoBytes = ((((int)($twoBytes / 0x060)) << 8) | ($twoBytes % 0x060));
$assembledTwoBytes = ((intdiv($twoBytes, 0x060) << 8) | ($twoBytes % 0x060));
$assembledTwoBytes += ($assembledTwoBytes < 0x00a00) // 0x003BF
? 0x0a1a1 // In the 0xA1A1 to 0xAAFE range
+2 -2
View File
@@ -13,7 +13,7 @@ namespace chillerlan\QRCode\Data;
use chillerlan\QRCode\Common\{BitBuffer, Mode};
use Throwable;
use function chr, implode, is_string, mb_convert_encoding, mb_detect_encoding,
use function chr, implode, intdiv, is_string, mb_convert_encoding, mb_detect_encoding,
mb_detect_order, mb_internal_encoding, mb_strlen, ord, sprintf, strlen;
/**
@@ -174,7 +174,7 @@ final class Kanji extends QRDataModeAbstract{
while($length > 0){
// Each 13 bits encodes a 2-byte character
$twoBytes = $bitBuffer->read(13);
$assembledTwoBytes = ((((int)($twoBytes / 0x0c0)) << 8) | ($twoBytes % 0x0c0));
$assembledTwoBytes = ((intdiv($twoBytes, 0x0c0) << 8) | ($twoBytes % 0x0c0));
$assembledTwoBytes += ($assembledTwoBytes < 0x01f00)
? 0x08140 // In the 0x8140 to 0x9FFC range
+4 -4
View File
@@ -12,7 +12,7 @@ namespace chillerlan\QRCode\Data;
use chillerlan\QRCode\Common\{BitBuffer, Mode};
use function array_flip, ceil, str_split, substr, unpack;
use function array_flip, ceil, intdiv, str_split, substr, unpack;
/**
* Numeric mode: decimal digits 0 to 9
@@ -140,8 +140,8 @@ final class Number extends QRDataModeAbstract{
throw new QRCodeDataException('error decoding numeric value');
}
$result .= $toNumericChar((int)($threeDigitsBits / 100));
$result .= $toNumericChar((int)($threeDigitsBits / 10) % 10);
$result .= $toNumericChar(intdiv($threeDigitsBits, 100));
$result .= $toNumericChar(intdiv($threeDigitsBits, 10) % 10);
$result .= $toNumericChar($threeDigitsBits % 10);
$length -= 3;
@@ -159,7 +159,7 @@ final class Number extends QRDataModeAbstract{
throw new QRCodeDataException('error decoding numeric value');
}
$result .= $toNumericChar((int)($twoDigitsBits / 10));
$result .= $toNumericChar(intdiv($twoDigitsBits, 10));
$result .= $toNumericChar($twoDigitsBits % 10);
}
elseif($length === 1){
+2 -2
View File
@@ -11,7 +11,7 @@
namespace chillerlan\QRCode\Data;
use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern, ReedSolomonEncoder, Version};
use function array_fill, array_map, array_reverse, count, floor;
use function array_fill, array_map, array_reverse, count, floor, intdiv;
/**
* Holds an array representation of the final QR Code that contains numerical values for later output modifications;
@@ -485,7 +485,7 @@ class QRMatrix{
if($bits !== null){
for($i = 0; $i < 18; $i++){
$a = (int)($i / 3);
$a = intdiv($i, 3);
$b = (($i % 3) + ($this->moduleCount - 8 - 3));
$v = (($bits >> $i) & 1) === 1;
+7 -6
View File
@@ -12,7 +12,7 @@
namespace chillerlan\QRCode\Decoder;
use chillerlan\QRCode\Data\QRMatrix;
use function array_fill, count, max;
use function array_fill, count, intdiv, max;
/**
* This class implements a local thresholding algorithm, which while slower than the
@@ -167,13 +167,14 @@ final class Binarizer{
// Quickly calculates the histogram by sampling four rows from the image. This proved to be
// more robust on the blackbox tests than sampling a diagonal as we used to do.
$buckets = array_fill(0, self::LUMINANCE_BUCKETS, 0);
$right = intdiv(($width * 4), 5);
$x = intdiv($width, 5);
for($y = 1; $y < 5; $y++){
$row = (int)($height * $y / 5);
$row = intdiv(($height * $y), 5);
$localLuminances = $this->source->getRow($row);
$right = (int)(($width * 4) / 5);
for($x = (int)($width / 5); $x < $right; $x++){
for(; $x < $right; $x++){
$pixel = ($localLuminances[$x] & 0xff);
$buckets[($pixel >> self::LUMINANCE_SHIFT)]++;
}
@@ -262,7 +263,7 @@ final class Binarizer{
//
// The default assumption is that the block is light/background. Since no estimate for
// the level of dark pixels exists locally, use half the min for the block.
$average = (int)($min / 2);
$average = ($min / 2);
if($y > 0 && $x > 0){
// Correct the "white background" assumption for blocks that have neighbors by comparing
@@ -272,7 +273,7 @@ final class Binarizer{
// the boundaries is used for the interior.
// The (min < bp) is arbitrary but works better than other heuristics that were tried.
$averageNeighborBlackPoint = (int)(
$averageNeighborBlackPoint = (
($blackPoints[($y - 1)][$x] + (2 * $blackPoints[$y][($x - 1)]) + $blackPoints[($y - 1)][($x - 1)]) / 4
);
+2 -2
View File
@@ -14,7 +14,7 @@ namespace chillerlan\QRCode\Detector;
use chillerlan\QRCode\Decoder\{Binarizer, LuminanceSourceInterface};
use chillerlan\QRCode\Common\Version;
use chillerlan\QRCode\Decoder\BitMatrix;
use function abs, is_nan, max, min, round;
use function abs, intdiv, is_nan, max, min, round;
use const NAN;
/**
@@ -42,7 +42,7 @@ final class Detector{
$moduleSize = $this->calculateModuleSize($topLeft, $topRight, $bottomLeft);
$dimension = $this->computeDimension($topLeft, $topRight, $bottomLeft, $moduleSize);
$provisionalVersion = new Version((int)(($dimension - 17) / 4));
$provisionalVersion = new Version(intdiv(($dimension - 17), 4));
$alignmentPattern = null;
// Anything above version 1 has an alignment pattern
+2 -2
View File
@@ -14,7 +14,7 @@
namespace chillerlan\QRCode\Detector;
use chillerlan\QRCode\Decoder\BitMatrix;
use function abs, count, usort;
use function abs, count, intdiv, usort;
use const PHP_FLOAT_MAX;
/**
@@ -56,7 +56,7 @@ final class FinderPatternFinder{
// Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
// image, and then account for the center being 3 modules in size. This gives the smallest
// number of pixels the center could be, so skip this often.
$iSkip = (int)((3 * $dimension) / (4 * self::MAX_MODULES));
$iSkip = intdiv((3 * $dimension), (4 * self::MAX_MODULES));
if($iSkip < self::MIN_SKIP){
$iSkip = self::MIN_SKIP;
+50 -45
View File
@@ -14,7 +14,7 @@ namespace chillerlan\QRCode\Detector;
use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\QRCode\Decoder\BitMatrix;
use Throwable;
use function array_fill, count, sprintf;
use function array_fill, count, intdiv, sprintf;
/**
* Implementations of this class can, given locations of finder patterns for a QR code in an
@@ -31,6 +31,8 @@ use function array_fill, count, sprintf;
*/
final class GridSampler{
private array $points;
/**
* Checks a set of points that have been transformed to sample points on an image against
* the image's dimensions to see if the point are even within the image.
@@ -42,20 +44,18 @@ final class GridSampler{
* For efficiency, the method will check points from either end of the line until one is found
* to be within the image. Because the set of points are assumed to be linear, this is valid.
*
* @param \chillerlan\QRCode\Decoder\BitMatrix $matrix image into which the points should map
* @param float[] $points actual points in x1,y1,...,xn,yn form
* @param int $dimension matrix width/height
*
* @throws \chillerlan\QRCode\Detector\QRCodeDetectorException if an endpoint is lies outside the image boundaries
*/
private function checkAndNudgePoints(BitMatrix $matrix, array $points):void{
$dimension = $matrix->getSize();
$nudged = true;
$max = count($points);
private function checkAndNudgePoints(int $dimension):void{
$nudged = true;
$max = count($this->points);
// Check and nudge points from start until we see some that are OK:
for($offset = 0; $offset < $max && $nudged; $offset += 2){
$x = (int)$points[$offset];
$y = (int)$points[($offset + 1)];
$x = (int)$this->points[$offset];
$y = (int)$this->points[($offset + 1)];
if($x < -1 || $x > $dimension || $y < -1 || $y > $dimension){
throw new QRCodeDetectorException(sprintf('checkAndNudgePoints 1, x: %s, y: %s, d: %s', $x, $y, $dimension));
@@ -64,31 +64,31 @@ final class GridSampler{
$nudged = false;
if($x === -1){
$points[$offset] = 0.0;
$nudged = true;
$this->points[$offset] = 0.0;
$nudged = true;
}
elseif($x === $dimension){
$points[$offset] = ($dimension - 1);
$nudged = true;
$this->points[$offset] = ($dimension - 1);
$nudged = true;
}
if($y === -1){
$points[($offset + 1)] = 0.0;
$nudged = true;
$this->points[($offset + 1)] = 0.0;
$nudged = true;
}
elseif($y === $dimension){
$points[($offset + 1)] = ($dimension - 1);
$nudged = true;
$this->points[($offset + 1)] = ($dimension - 1);
$nudged = true;
}
}
// Check and nudge points from end:
$nudged = true;
$offset = (count($points) - 2);
for(; $offset >= 0 && $nudged; $offset -= 2){
$x = (int)$points[$offset];
$y = (int)$points[($offset + 1)];
for($offset = ($max - 2); $offset >= 0 && $nudged; $offset -= 2){
$x = (int)$this->points[$offset];
$y = (int)$this->points[($offset + 1)];
if($x < -1 || $x > $dimension || $y < -1 || $y > $dimension){
throw new QRCodeDetectorException(sprintf('checkAndNudgePoints 2, x: %s, y: %s, d: %s', $x, $y, $dimension));
@@ -97,24 +97,25 @@ final class GridSampler{
$nudged = false;
if($x === -1){
$points[$offset] = 0.0;
$nudged = true;
$this->points[$offset] = 0.0;
$nudged = true;
}
elseif($x === $dimension){
$points[$offset] = ($dimension - 1);
$nudged = true;
$this->points[$offset] = ($dimension - 1);
$nudged = true;
}
if($y === -1){
$points[($offset + 1)] = 0.0;
$nudged = true;
$this->points[($offset + 1)] = 0.0;
$nudged = true;
}
elseif($y === $dimension){
$points[($offset + 1)] = ($dimension - 1);
$nudged = true;
$this->points[($offset + 1)] = ($dimension - 1);
$nudged = true;
}
}
}
/**
@@ -133,31 +134,36 @@ final class GridSampler{
throw new QRCodeDetectorException('invalid matrix size');
}
$bits = new BitMatrix($dimension);
$points = array_fill(0, (2 * $dimension), 0.0);
$bits = new BitMatrix($dimension);
$this->points = array_fill(0, (2 * $dimension), 0.0);
for($y = 0; $y < $dimension; $y++){
$max = count($points);
$max = count($this->points);
$iValue = ($y + 0.5);
for($x = 0; $x < $max; $x += 2){
$points[$x] = (($x / 2) + 0.5);
$points[($x + 1)] = $iValue;
$this->points[$x] = (($x / 2) + 0.5);
$this->points[($x + 1)] = $iValue;
}
$transform->transformPoints($points);
// phpcs:ignore
[$this->points, ] = $transform->transformPoints($this->points);
// Quick check to see if points transformed to something inside the image;
// sufficient to check the endpoints
$this->checkAndNudgePoints($matrix, $points);
$this->checkAndNudgePoints($matrix->getSize());
try{
// no need to try/catch as QRMatrix::set() will silently discard out of bounds values
# try{
for($x = 0; $x < $max; $x += 2){
// Black(-ish) pixel
$bits->set(($x / 2), $y, $matrix->check((int)$points[$x], (int)$points[($x + 1)]), QRMatrix::M_DATA);
$bits->set(
intdiv($x, 2),
$y,
$matrix->check((int)$this->points[$x], (int)$this->points[($x + 1)]),
QRMatrix::M_DATA
);
}
}
// @codeCoverageIgnoreStart
catch(Throwable $aioobe){//ArrayIndexOutOfBoundsException
# }
# catch(Throwable $aioobe){//ArrayIndexOutOfBoundsException
// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
// transform gets "twisted" such that it maps a straight line of points to a set of points
// whose endpoints are in bounds, but others are not. There is probably some mathematical
@@ -165,9 +171,8 @@ final class GridSampler{
// This results in an ugly runtime exception despite our clever checks above -- can't have
// that. We could check each point's coordinates but that feels duplicative. We settle for
// catching and wrapping ArrayIndexOutOfBoundsException.
throw new QRCodeDetectorException('ArrayIndexOutOfBoundsException');
}
// @codeCoverageIgnoreEnd
# throw new QRCodeDetectorException('ArrayIndexOutOfBoundsException');
# }
}
+6 -4
View File
@@ -150,12 +150,12 @@ final class PerspectiveTransform{
}
/**
*
* @return array[] [$xValues, $yValues|null]
*/
public function transformPoints(array &$xValues, array &$yValues = null):void{
public function transformPoints(array $xValues, array $yValues = null):array{
$max = count($xValues);
if($yValues !== null){
if($yValues !== null){ // unused
for($i = 0; $i < $max; $i++){
$x = $xValues[$i];
@@ -165,7 +165,7 @@ final class PerspectiveTransform{
$yValues[$i] = (($this->a12 * $x + $this->a22 * $y + $this->a32) / $denominator);
}
return;
return [$xValues, $yValues];
}
for($i = 0; $i < $max; $i += 2){
@@ -175,6 +175,8 @@ final class PerspectiveTransform{
$xValues[$i] = (($this->a11 * $x + $this->a21 * $y + $this->a31) / $denominator);
$xValues[($i + 1)] = (($this->a12 * $x + $this->a22 * $y + $this->a32) / $denominator);
}
return [$xValues, $yValues];
}
}
+3 -3
View File
@@ -16,7 +16,7 @@ use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\Settings\SettingsContainerInterface;
use ErrorException, Throwable;
use function array_values, count, extension_loaded, imagecolorallocate, imagecolortransparent, imagecreatetruecolor,
imagedestroy, imagefilledellipse, imagefilledrectangle, imagegif, imagejpeg, imagepng, imagescale, intval,
imagedestroy, imagefilledellipse, imagefilledrectangle, imagegif, imagejpeg, imagepng, imagescale, intdiv, intval,
is_array, is_numeric, max, min, ob_end_clean, ob_get_contents, ob_start, restore_error_handler, set_error_handler;
/**
@@ -250,8 +250,8 @@ class QRGdImage extends QROutputAbstract{
$this->options->drawCircularModules && !$this->matrix->checkTypeIn($x, $y, $this->options->keepAsSquare)
? imagefilledellipse(
$this->image,
(int)(($x * $this->scale) + ($this->scale / 2)),
(int)(($y * $this->scale) + ($this->scale / 2)),
(($x * $this->scale) + intdiv($this->scale, 2)),
(($y * $this->scale) + intdiv($this->scale, 2)),
(int)(2 * $this->options->circleRadius * $this->scale),
(int)(2 * $this->options->circleRadius * $this->scale),
$color
+1 -1
View File
@@ -132,7 +132,7 @@ interface QROutputInterface{
public static function moduleValueIsValid($value):bool;
/**
* generates the output, optionally dumps it to a file, and returns it
* Generates the output, optionally dumps it to a file, and returns it
*
* please note that the value of QROptions::$cachefile is already evaluated at this point.
* if the output module is invoked manually, it has no effect at all.