Pārlūkot izejas kodu

:shower: clean up some (int) casts

smiley 2 gadi atpakaļ
vecāks
revīzija
5a280c8107

+ 6 - 6
src/Common/MaskPattern.php

@@ -14,7 +14,7 @@ namespace chillerlan\QRCode\Common;
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\QRCodeException;
 use chillerlan\QRCode\QRCodeException;
 use Closure;
 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
  * 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_001 => fn(int $x, int $y):bool => ($y % 2) === 0,
 			self::PATTERN_010 => fn(int $x, int $y):bool => ($x % 3) === 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_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];
 		][$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
src/Data/AlphaNum.php

@@ -12,7 +12,7 @@ namespace chillerlan\QRCode\Data;
 
 
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
 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, $ % * + - . / :
  * Alphanumeric mode: 0 to 9, A to Z, space, $ % * + - . / :
@@ -118,7 +118,7 @@ final class AlphaNum extends QRDataModeAbstract{
 			}
 			}
 
 
 			$nextTwoCharsBits = $bitBuffer->read(11);
 			$nextTwoCharsBits = $bitBuffer->read(11);
-			$result           .= $toAlphaNumericChar((int)($nextTwoCharsBits / 45));
+			$result           .= $toAlphaNumericChar(intdiv($nextTwoCharsBits, 45));
 			$result           .= $toAlphaNumericChar($nextTwoCharsBits % 45);
 			$result           .= $toAlphaNumericChar($nextTwoCharsBits % 45);
 			$length           -= 2;
 			$length           -= 2;
 		}
 		}

+ 2 - 2
src/Data/Hanzi.php

@@ -13,7 +13,7 @@ namespace chillerlan\QRCode\Data;
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
 
 
 use Throwable;
 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;
 	mb_detect_order, mb_internal_encoding, mb_strlen, ord, sprintf, strlen;
 
 
 /**
 /**
@@ -188,7 +188,7 @@ final class Hanzi extends QRDataModeAbstract{
 		while($length > 0){
 		while($length > 0){
 			// Each 13 bits encodes a 2-byte character
 			// Each 13 bits encodes a 2-byte character
 			$twoBytes          = $bitBuffer->read(13);
 			$twoBytes          = $bitBuffer->read(13);
-			$assembledTwoBytes = ((((int)($twoBytes / 0x060)) << 8) | ($twoBytes % 0x060));
+			$assembledTwoBytes = ((intdiv($twoBytes, 0x060) << 8) | ($twoBytes % 0x060));
 
 
 			$assembledTwoBytes += ($assembledTwoBytes < 0x00a00) // 0x003BF
 			$assembledTwoBytes += ($assembledTwoBytes < 0x00a00) // 0x003BF
 				? 0x0a1a1  // In the 0xA1A1 to 0xAAFE range
 				? 0x0a1a1  // In the 0xA1A1 to 0xAAFE range

+ 2 - 2
src/Data/Kanji.php

@@ -13,7 +13,7 @@ namespace chillerlan\QRCode\Data;
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
 
 
 use Throwable;
 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;
 	mb_detect_order, mb_internal_encoding, mb_strlen, ord, sprintf, strlen;
 
 
 /**
 /**
@@ -174,7 +174,7 @@ final class Kanji extends QRDataModeAbstract{
 		while($length > 0){
 		while($length > 0){
 			// Each 13 bits encodes a 2-byte character
 			// Each 13 bits encodes a 2-byte character
 			$twoBytes          = $bitBuffer->read(13);
 			$twoBytes          = $bitBuffer->read(13);
-			$assembledTwoBytes = ((((int)($twoBytes / 0x0c0)) << 8) | ($twoBytes % 0x0c0));
+			$assembledTwoBytes = ((intdiv($twoBytes, 0x0c0) << 8) | ($twoBytes % 0x0c0));
 
 
 			$assembledTwoBytes += ($assembledTwoBytes < 0x01f00)
 			$assembledTwoBytes += ($assembledTwoBytes < 0x01f00)
 				? 0x08140  // In the 0x8140 to 0x9FFC range
 				? 0x08140  // In the 0x8140 to 0x9FFC range

+ 4 - 4
src/Data/Number.php

@@ -12,7 +12,7 @@ namespace chillerlan\QRCode\Data;
 
 
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
 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
  * Numeric mode: decimal digits 0 to 9
@@ -140,8 +140,8 @@ final class Number extends QRDataModeAbstract{
 				throw new QRCodeDataException('error decoding numeric value');
 				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);
 			$result .= $toNumericChar($threeDigitsBits % 10);
 
 
 			$length -= 3;
 			$length -= 3;
@@ -159,7 +159,7 @@ final class Number extends QRDataModeAbstract{
 				throw new QRCodeDataException('error decoding numeric value');
 				throw new QRCodeDataException('error decoding numeric value');
 			}
 			}
 
 
-			$result .= $toNumericChar((int)($twoDigitsBits / 10));
+			$result .= $toNumericChar(intdiv($twoDigitsBits, 10));
 			$result .= $toNumericChar($twoDigitsBits % 10);
 			$result .= $toNumericChar($twoDigitsBits % 10);
 		}
 		}
 		elseif($length === 1){
 		elseif($length === 1){

+ 2 - 2
src/Data/QRMatrix.php

@@ -11,7 +11,7 @@
 namespace chillerlan\QRCode\Data;
 namespace chillerlan\QRCode\Data;
 
 
 use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern, ReedSolomonEncoder, Version};
 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;
  * 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){
 		if($bits !== null){
 
 
 			for($i = 0; $i < 18; $i++){
 			for($i = 0; $i < 18; $i++){
-				$a = (int)($i / 3);
+				$a = intdiv($i, 3);
 				$b = (($i % 3) + ($this->moduleCount - 8 - 3));
 				$b = (($i % 3) + ($this->moduleCount - 8 - 3));
 				$v = (($bits >> $i) & 1) === 1;
 				$v = (($bits >> $i) & 1) === 1;
 
 

+ 7 - 6
src/Decoder/Binarizer.php

@@ -12,7 +12,7 @@
 namespace chillerlan\QRCode\Decoder;
 namespace chillerlan\QRCode\Decoder;
 
 
 use chillerlan\QRCode\Data\QRMatrix;
 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
  * 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
 		// 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.
 		// more robust on the blackbox tests than sampling a diagonal as we used to do.
 		$buckets = array_fill(0, self::LUMINANCE_BUCKETS, 0);
 		$buckets = array_fill(0, self::LUMINANCE_BUCKETS, 0);
+		$right   = intdiv(($width * 4), 5);
+		$x       = intdiv($width, 5);
 
 
 		for($y = 1; $y < 5; $y++){
 		for($y = 1; $y < 5; $y++){
-			$row             = (int)($height * $y / 5);
+			$row             = intdiv(($height * $y), 5);
 			$localLuminances = $this->source->getRow($row);
 			$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);
 				$pixel = ($localLuminances[$x] & 0xff);
 				$buckets[($pixel >> self::LUMINANCE_SHIFT)]++;
 				$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 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.
 					// 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){
 					if($y > 0 && $x > 0){
 						// Correct the "white background" assumption for blocks that have neighbors by comparing
 						// 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 boundaries is used for the interior.
 
 
 						// The (min < bp) is arbitrary but works better than other heuristics that were tried.
 						// 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
 							($blackPoints[($y - 1)][$x] + (2 * $blackPoints[$y][($x - 1)]) + $blackPoints[($y - 1)][($x - 1)]) / 4
 						);
 						);
 
 

+ 2 - 2
src/Detector/Detector.php

@@ -14,7 +14,7 @@ namespace chillerlan\QRCode\Detector;
 use chillerlan\QRCode\Decoder\{Binarizer, LuminanceSourceInterface};
 use chillerlan\QRCode\Decoder\{Binarizer, LuminanceSourceInterface};
 use chillerlan\QRCode\Common\Version;
 use chillerlan\QRCode\Common\Version;
 use chillerlan\QRCode\Decoder\BitMatrix;
 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;
 use const NAN;
 
 
 /**
 /**
@@ -42,7 +42,7 @@ final class Detector{
 
 
 		$moduleSize         = $this->calculateModuleSize($topLeft, $topRight, $bottomLeft);
 		$moduleSize         = $this->calculateModuleSize($topLeft, $topRight, $bottomLeft);
 		$dimension          = $this->computeDimension($topLeft, $topRight, $bottomLeft, $moduleSize);
 		$dimension          = $this->computeDimension($topLeft, $topRight, $bottomLeft, $moduleSize);
-		$provisionalVersion = new Version((int)(($dimension - 17) / 4));
+		$provisionalVersion = new Version(intdiv(($dimension - 17), 4));
 		$alignmentPattern   = null;
 		$alignmentPattern   = null;
 
 
 		// Anything above version 1 has an alignment pattern
 		// Anything above version 1 has an alignment pattern

+ 2 - 2
src/Detector/FinderPatternFinder.php

@@ -14,7 +14,7 @@
 namespace chillerlan\QRCode\Detector;
 namespace chillerlan\QRCode\Detector;
 
 
 use chillerlan\QRCode\Decoder\BitMatrix;
 use chillerlan\QRCode\Decoder\BitMatrix;
-use function abs, count, usort;
+use function abs, count, intdiv, usort;
 use const PHP_FLOAT_MAX;
 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
 		// 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
 		// 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.
 		// 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){
 		if($iSkip < self::MIN_SKIP){
 			$iSkip = self::MIN_SKIP;
 			$iSkip = self::MIN_SKIP;

+ 50 - 45
src/Detector/GridSampler.php

@@ -14,7 +14,7 @@ namespace chillerlan\QRCode\Detector;
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Decoder\BitMatrix;
 use chillerlan\QRCode\Decoder\BitMatrix;
 use Throwable;
 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
  * 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{
 final class GridSampler{
 
 
+	private array $points;
+
 	/**
 	/**
 	 * Checks a set of points that have been transformed to sample points on an image against
 	 * 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.
 	 * 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
 	 * 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.
 	 * 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
 	 * @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:
 		// Check and nudge points from start until we see some that are OK:
 		for($offset = 0; $offset < $max && $nudged; $offset += 2){
 		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){
 			if($x < -1 || $x > $dimension || $y < -1 || $y > $dimension){
 				throw new QRCodeDetectorException(sprintf('checkAndNudgePoints 1, x: %s, y: %s, d: %s', $x, $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;
 			$nudged = false;
 
 
 			if($x === -1){
 			if($x === -1){
-				$points[$offset] = 0.0;
-				$nudged          = true;
+				$this->points[$offset] = 0.0;
+				$nudged                = true;
 			}
 			}
 			elseif($x === $dimension){
 			elseif($x === $dimension){
-				$points[$offset] = ($dimension - 1);
-				$nudged          = true;
+				$this->points[$offset] = ($dimension - 1);
+				$nudged                = true;
 			}
 			}
 
 
 			if($y === -1){
 			if($y === -1){
-				$points[($offset + 1)] = 0.0;
-				$nudged                = true;
+				$this->points[($offset + 1)] = 0.0;
+				$nudged                      = true;
 			}
 			}
 			elseif($y === $dimension){
 			elseif($y === $dimension){
-				$points[($offset + 1)] = ($dimension - 1);
-				$nudged                = true;
+				$this->points[($offset + 1)] = ($dimension - 1);
+				$nudged                      = true;
 			}
 			}
 
 
 		}
 		}
+
 		// Check and nudge points from end:
 		// Check and nudge points from end:
 		$nudged = true;
 		$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){
 			if($x < -1 || $x > $dimension || $y < -1 || $y > $dimension){
 				throw new QRCodeDetectorException(sprintf('checkAndNudgePoints 2, x: %s, y: %s, d: %s', $x, $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;
 			$nudged = false;
 
 
 			if($x === -1){
 			if($x === -1){
-				$points[$offset] = 0.0;
-				$nudged          = true;
+				$this->points[$offset] = 0.0;
+				$nudged                = true;
 			}
 			}
 			elseif($x === $dimension){
 			elseif($x === $dimension){
-				$points[$offset] = ($dimension - 1);
-				$nudged          = true;
+				$this->points[$offset] = ($dimension - 1);
+				$nudged                = true;
 			}
 			}
 
 
 			if($y === -1){
 			if($y === -1){
-				$points[($offset + 1)] = 0.0;
-				$nudged                = true;
+				$this->points[($offset + 1)] = 0.0;
+				$nudged                      = true;
 			}
 			}
 			elseif($y === $dimension){
 			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');
 			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++){
 		for($y = 0; $y < $dimension; $y++){
-			$max    = count($points);
+			$max    = count($this->points);
 			$iValue = ($y + 0.5);
 			$iValue = ($y + 0.5);
 
 
 			for($x = 0; $x < $max; $x += 2){
 			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;
 			// Quick check to see if points transformed to something inside the image;
 			// sufficient to check the endpoints
 			// 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){
 				for($x = 0; $x < $max; $x += 2){
 					// Black(-ish) pixel
 					// 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
 				// 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
 				// 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
 				// 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
 				// 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
 				// that. We could check each point's coordinates but that feels duplicative. We settle for
 				// catching and wrapping ArrayIndexOutOfBoundsException.
 				// catching and wrapping ArrayIndexOutOfBoundsException.
-				throw new QRCodeDetectorException('ArrayIndexOutOfBoundsException');
-			}
-			// @codeCoverageIgnoreEnd
+#				throw new QRCodeDetectorException('ArrayIndexOutOfBoundsException');
+#			}
 
 
 		}
 		}
 
 

+ 6 - 4
src/Detector/PerspectiveTransform.php

@@ -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);
 		$max = count($xValues);
 
 
-		if($yValues !== null){
+		if($yValues !== null){ // unused
 
 
 			for($i = 0; $i < $max; $i++){
 			for($i = 0; $i < $max; $i++){
 				$x           = $xValues[$i];
 				$x           = $xValues[$i];
@@ -165,7 +165,7 @@ final class PerspectiveTransform{
 				$yValues[$i] = (($this->a12 * $x + $this->a22 * $y + $this->a32) / $denominator);
 				$yValues[$i] = (($this->a12 * $x + $this->a22 * $y + $this->a32) / $denominator);
 			}
 			}
 
 
-			return;
+			return [$xValues, $yValues];
 		}
 		}
 
 
 		for($i = 0; $i < $max; $i += 2){
 		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]       = (($this->a11 * $x + $this->a21 * $y + $this->a31) / $denominator);
 			$xValues[($i + 1)] = (($this->a12 * $x + $this->a22 * $y + $this->a32) / $denominator);
 			$xValues[($i + 1)] = (($this->a12 * $x + $this->a22 * $y + $this->a32) / $denominator);
 		}
 		}
+
+		return [$xValues, $yValues];
 	}
 	}
 
 
 }
 }

+ 3 - 3
src/Output/QRGdImage.php

@@ -16,7 +16,7 @@ use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\Settings\SettingsContainerInterface;
 use chillerlan\Settings\SettingsContainerInterface;
 use ErrorException, Throwable;
 use ErrorException, Throwable;
 use function array_values, count, extension_loaded, imagecolorallocate, imagecolortransparent, imagecreatetruecolor,
 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;
 	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)
 		$this->options->drawCircularModules && !$this->matrix->checkTypeIn($x, $y, $this->options->keepAsSquare)
 			? imagefilledellipse(
 			? imagefilledellipse(
 				$this->image,
 				$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),
 				(int)(2 * $this->options->circleRadius * $this->scale),
 				(int)(2 * $this->options->circleRadius * $this->scale),
 				$color
 				$color

+ 1 - 1
src/Output/QROutputInterface.php

@@ -132,7 +132,7 @@ interface QROutputInterface{
 	public static function moduleValueIsValid($value):bool;
 	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.
 	 * 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.
 	 * if the output module is invoked manually, it has no effect at all.