💄 code style fixes

This commit is contained in:
smiley
2023-03-11 02:38:57 +01:00
parent abfd69e44a
commit 6b2a529160
74 changed files with 843 additions and 777 deletions
+32 -32
View File
@@ -83,9 +83,9 @@ final class Binarizer{
$secondPeakScore = 0;
for($x = 0; $x < $numBuckets; $x++){
$distanceToBiggest = $x - $firstPeak;
$distanceToBiggest = ($x - $firstPeak);
// Encourage more distant second peaks by multiplying by square of distance.
$score = $buckets[$x] * $distanceToBiggest * $distanceToBiggest;
$score = ($buckets[$x] * $distanceToBiggest * $distanceToBiggest);
if($score > $secondPeakScore){
$secondPeak = $x;
@@ -102,17 +102,17 @@ final class Binarizer{
// If there is too little contrast in the image to pick a meaningful black point, throw rather
// than waste time trying to decode the image, and risk false positives.
if($secondPeak - $firstPeak <= $numBuckets / 16){
if(($secondPeak - $firstPeak) <= ($numBuckets / 16)){
throw new QRCodeDecoderException('no meaningful dark point found'); // @codeCoverageIgnore
}
// Find a valley between them that is low and closer to the white peak.
$bestValley = $secondPeak - 1;
$bestValley = ($secondPeak - 1);
$bestValleyScore = -1;
for($x = $secondPeak - 1; $x > $firstPeak; $x--){
$fromFirst = $x - $firstPeak;
$score = $fromFirst * $fromFirst * ($secondPeak - $x) * ($maxBucketCount - $buckets[$x]);
for($x = ($secondPeak - 1); $x > $firstPeak; $x--){
$fromFirst = ($x - $firstPeak);
$score = ($fromFirst * $fromFirst * ($secondPeak - $x) * ($maxBucketCount - $buckets[$x]));
if($score > $bestValleyScore){
$bestValley = $x;
@@ -120,7 +120,7 @@ final class Binarizer{
}
}
return $bestValley << self::LUMINANCE_SHIFT;
return ($bestValley << self::LUMINANCE_SHIFT);
}
/**
@@ -140,13 +140,13 @@ final class Binarizer{
$height = $this->source->getHeight();
if($width >= self::MINIMUM_DIMENSION && $height >= self::MINIMUM_DIMENSION){
$subWidth = $width >> self::BLOCK_SIZE_POWER;
$subWidth = ($width >> self::BLOCK_SIZE_POWER);
if(($width & self::BLOCK_SIZE_MASK) !== 0){
$subWidth++;
}
$subHeight = $height >> self::BLOCK_SIZE_POWER;
$subHeight = ($height >> self::BLOCK_SIZE_POWER);
if(($height & self::BLOCK_SIZE_MASK) !== 0){
$subHeight++;
@@ -174,8 +174,8 @@ final class Binarizer{
$right = (int)(($width * 4) / 5);
for($x = (int)($width / 5); $x < $right; $x++){
$pixel = $localLuminances[$x] & 0xff;
$buckets[$pixel >> self::LUMINANCE_SHIFT]++;
$pixel = ($localLuminances[$x] & 0xff);
$buckets[($pixel >> self::LUMINANCE_SHIFT)]++;
}
}
@@ -187,10 +187,10 @@ final class Binarizer{
$matrix = new BitMatrix(max($width, $height));
for($y = 0; $y < $height; $y++){
$offset = $y * $width;
$offset = ($y * $width);
for($x = 0; $x < $width; $x++){
$matrix->set($x, $y, (($this->luminances[$offset + $x] & 0xff) < $blackPoint), QRMatrix::M_DATA);
$matrix->set($x, $y, (($this->luminances[($offset + $x)] & 0xff) < $blackPoint), QRMatrix::M_DATA);
}
}
@@ -212,7 +212,7 @@ final class Binarizer{
for($y = 0; $y < $subHeight; $y++){
$yoffset = ($y << self::BLOCK_SIZE_POWER);
$maxYOffset = $height - self::BLOCK_SIZE;
$maxYOffset = ($height - self::BLOCK_SIZE);
if($yoffset > $maxYOffset){
$yoffset = $maxYOffset;
@@ -220,7 +220,7 @@ final class Binarizer{
for($x = 0; $x < $subWidth; $x++){
$xoffset = ($x << self::BLOCK_SIZE_POWER);
$maxXOffset = $width - self::BLOCK_SIZE;
$maxXOffset = ($width - self::BLOCK_SIZE);
if($xoffset > $maxXOffset){
$xoffset = $maxXOffset;
@@ -230,10 +230,10 @@ final class Binarizer{
$min = 255;
$max = 0;
for($yy = 0, $offset = $yoffset * $width + $xoffset; $yy < self::BLOCK_SIZE; $yy++, $offset += $width){
for($yy = 0, $offset = ($yoffset * $width + $xoffset); $yy < self::BLOCK_SIZE; $yy++, $offset += $width){
for($xx = 0; $xx < self::BLOCK_SIZE; $xx++){
$pixel = (int)($this->luminances[(int)($offset + $xx)]) & 0xff;
$pixel = ((int)($this->luminances[(int)($offset + $xx)]) & 0xff);
$sum += $pixel;
// still looking for good contrast
if($pixel < $min){
@@ -246,20 +246,20 @@ final class Binarizer{
}
// short-circuit min/max tests once dynamic range is met
if($max - $min > self::MIN_DYNAMIC_RANGE){
if(($max - $min) > self::MIN_DYNAMIC_RANGE){
// finish the rest of the rows quickly
for($yy++, $offset += $width; $yy < self::BLOCK_SIZE; $yy++, $offset += $width){
for($xx = 0; $xx < self::BLOCK_SIZE; $xx++){
$sum += (int)($this->luminances[(int)($offset + $xx)]) & 0xff;
$sum += ((int)($this->luminances[(int)($offset + $xx)]) & 0xff);
}
}
}
}
// The default estimate is the average of the values in the block.
$average = $sum >> (self::BLOCK_SIZE_POWER * 2);
$average = ($sum >> (self::BLOCK_SIZE_POWER * 2));
if($max - $min <= self::MIN_DYNAMIC_RANGE){
if(($max - $min) <= self::MIN_DYNAMIC_RANGE){
// If variation within the block is low, assume this is a block with only light or only
// dark pixels. In that case we do not want to use the average, as it would divide this
// low contrast area into black and white pixels, essentially creating data out of noise.
@@ -277,7 +277,7 @@ final class Binarizer{
// The (min < bp) is arbitrary but works better than other heuristics that were tried.
$averageNeighborBlackPoint = (int)(
($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
);
if($min < $averageNeighborBlackPoint){
@@ -304,7 +304,7 @@ final class Binarizer{
for($y = 0; $y < $subHeight; $y++){
$yoffset = ($y << self::BLOCK_SIZE_POWER);
$maxYOffset = $height - self::BLOCK_SIZE;
$maxYOffset = ($height - self::BLOCK_SIZE);
if($yoffset > $maxYOffset){
$yoffset = $maxYOffset;
@@ -312,30 +312,30 @@ final class Binarizer{
for($x = 0; $x < $subWidth; $x++){
$xoffset = ($x << self::BLOCK_SIZE_POWER);
$maxXOffset = $width - self::BLOCK_SIZE;
$maxXOffset = ($width - self::BLOCK_SIZE);
if($xoffset > $maxXOffset){
$xoffset = $maxXOffset;
}
$left = $this->cap($x, 2, $subWidth - 3);
$top = $this->cap($y, 2, $subHeight - 3);
$left = $this->cap($x, 2, ($subWidth - 3));
$top = $this->cap($y, 2, ($subHeight - 3));
$sum = 0;
for($z = -2; $z <= 2; $z++){
$br = $blackPoints[$top + $z];
$sum += $br[$left - 2] + $br[$left - 1] + $br[$left] + $br[$left + 1] + $br[$left + 2];
$br = $blackPoints[($top + $z)];
$sum += ($br[($left - 2)] + $br[($left - 1)] + $br[$left] + $br[($left + 1)] + $br[($left + 2)]);
}
$average = (int)($sum / 25);
// Applies a single threshold to a block of pixels.
for($j = 0, $o = $yoffset * $width + $xoffset; $j < self::BLOCK_SIZE; $j++, $o += $width){
for($j = 0, $o = ($yoffset * $width + $xoffset); $j < self::BLOCK_SIZE; $j++, $o += $width){
for($i = 0; $i < self::BLOCK_SIZE; $i++){
// Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
$v = (((int)($this->luminances[$o + $i]) & 0xff) <= $average);
$v = (((int)($this->luminances[($o + $i)]) & 0xff) <= $average);
$matrix->set($xoffset + $i, $yoffset + $j, $v, QRMatrix::M_DATA);
$matrix->set(($xoffset + $i), ($yoffset + $j), $v, QRMatrix::M_DATA);
}
}
}
+16 -16
View File
@@ -94,7 +94,7 @@ final class BitMatrix extends QRMatrix{
public function mirror():self{
for($x = 0; $x < $this->moduleCount; $x++){
for($y = $x + 1; $y < $this->moduleCount; $y++){
for($y = ($x + 1); $y < $this->moduleCount; $y++){
if($this->get($x, $y) !== $this->get($y, $x)){
$this->flip($y, $x);
$this->flip($x, $y);
@@ -128,7 +128,7 @@ final class BitMatrix extends QRMatrix{
$direction = true;
// Read columns in pairs, from right to left
for($i = $this->moduleCount - 1; $i > 0; $i -= 2){
for($i = ($this->moduleCount - 1); $i > 0; $i -= 2){
// Skip whole column with vertical alignment pattern;
// saves time and makes the other code proceed more cleanly
@@ -137,10 +137,10 @@ final class BitMatrix extends QRMatrix{
}
// Read alternatingly from bottom to top then top to bottom
for($count = 0; $count < $this->moduleCount; $count++){
$y = $direction ? $this->moduleCount - 1 - $count : $count;
$y = ($direction) ? ($this->moduleCount - 1 - $count) : $count;
for($col = 0; $col < 2; $col++){
$x = $i - $col;
$x = ($i - $col);
// Ignore bits covered by the function pattern
if($fp->get($x, $y) !== $this::M_NULL){
@@ -203,13 +203,13 @@ final class BitMatrix extends QRMatrix{
// Read the top-right/bottom-left pattern too
$formatInfoBits2 = 0;
$jMin = $this->moduleCount - 7;
$jMin = ($this->moduleCount - 7);
for($j = $this->moduleCount - 1; $j >= $jMin; $j--){
for($j = ($this->moduleCount - 1); $j >= $jMin; $j--){
$formatInfoBits2 = $this->copyVersionBit(8, $j, $formatInfoBits2);
}
for($i = $this->moduleCount - 8; $i < $this->moduleCount; $i++){
for($i = ($this->moduleCount - 8); $i < $this->moduleCount; $i++){
$formatInfoBits2 = $this->copyVersionBit($i, 8, $formatInfoBits2);
}
@@ -220,8 +220,8 @@ final class BitMatrix extends QRMatrix{
// Should return null, but, some QR codes apparently do not mask this info.
// Try again by actually masking the pattern first.
$formatInfo = $this->doDecodeFormatInformation(
$formatInfoBits1 ^ $this::FORMAT_INFO_MASK_QR,
$formatInfoBits2 ^ $this::FORMAT_INFO_MASK_QR
($formatInfoBits1 ^ $this::FORMAT_INFO_MASK_QR),
($formatInfoBits2 ^ $this::FORMAT_INFO_MASK_QR)
);
// still nothing???
@@ -246,7 +246,7 @@ final class BitMatrix extends QRMatrix{
? $this->check($j, $i)
: $this->check($i, $j);
return $bit ? ($versionBits << 1) | 0x1 : $versionBits << 1;
return ($bit) ? (($versionBits << 1) | 0x1) : ($versionBits << 1);
}
/**
@@ -302,7 +302,7 @@ final class BitMatrix extends QRMatrix{
return $this;
}
$provisionalVersion = ($this->moduleCount - 17) / 4;
$provisionalVersion = (($this->moduleCount - 17) / 4);
// no version info if v < 7
if($provisionalVersion < 7){
@@ -313,10 +313,10 @@ final class BitMatrix extends QRMatrix{
// Read top-right version info: 3 wide by 6 tall
$versionBits = 0;
$ijMin = $this->moduleCount - 11;
$ijMin = ($this->moduleCount - 11);
for($y = 5; $y >= 0; $y--){
for($x = $this->moduleCount - 9; $x >= $ijMin; $x--){
for($x = ($this->moduleCount - 9); $x >= $ijMin; $x--){
$versionBits = $this->copyVersionBit($x, $y, $versionBits);
}
}
@@ -331,7 +331,7 @@ final class BitMatrix extends QRMatrix{
$versionBits = 0;
for($x = 5; $x >= 0; $x--){
for($y = $this->moduleCount - 9; $y >= $ijMin; $y--){
for($y = ($this->moduleCount - 9); $y >= $ijMin; $y--){
$versionBits = $this->copyVersionBit($x, $y, $versionBits);
}
}
@@ -390,7 +390,7 @@ final class BitMatrix extends QRMatrix{
return $a;
}
return ($a >> $b) & ~((1 << (8 * PHP_INT_SIZE - 1)) >> ($b - 1));
return (($a >> $b) & ~((1 << (8 * PHP_INT_SIZE - 1)) >> ($b - 1)));
}
/**
@@ -405,7 +405,7 @@ final class BitMatrix extends QRMatrix{
$count = 0;
for($i = 0; $i < 32; $i += 4){
$count += $BITS_SET_IN_HALF_BYTE[$this->uRShift($a, $i) & 0x0F];
$count += $BITS_SET_IN_HALF_BYTE[($this->uRShift($a, $i) & 0x0F)];
}
return $count;
+69 -56
View File
@@ -11,7 +11,7 @@
namespace chillerlan\QRCode\Decoder;
use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern, Mode, ReedSolomonDecoder, Version};
use chillerlan\QRCode\Common\{BitBuffer, EccLevel, ECICharset, MaskPattern, Mode, ReedSolomonDecoder, Version};
use chillerlan\QRCode\Data\{AlphaNum, Byte, ECI, Hanzi, Kanji, Number};
use chillerlan\QRCode\Detector\Detector;
use Throwable;
@@ -28,6 +28,8 @@ final class Decoder{
private ?Version $version = null;
private ?EccLevel $eccLevel = null;
private ?MaskPattern $maskPattern = null;
private BitBuffer $bitBuffer;
private ?ECICharset $eciCharset = null;
/**
* Decodes a QR Code represented as a BitMatrix.
@@ -89,23 +91,24 @@ final class Decoder{
* @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
*/
private function decodeBitStream(BitBuffer $bitBuffer):DecoderResult{
$versionNumber = $this->version->getVersionNumber();
$symbolSequence = -1;
$parityData = -1;
$eciCharset = null;
$fc1InEffect = false;
$result = '';
$this->bitBuffer = $bitBuffer;
$this->eciCharset = null;
$versionNumber = $this->version->getVersionNumber();
$symbolSequence = -1;
$parityData = -1;
$fc1InEffect = false;
$result = '';
// While still another segment to read...
while($bitBuffer->available() >= 4){
$datamode = $bitBuffer->read(4); // mode is encoded by 4 bits
while($this->bitBuffer->available() >= 4){
$datamode = $this->bitBuffer->read(4); // mode is encoded by 4 bits
// OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
if($datamode === Mode::TERMINATOR){
break;
}
elseif($datamode === Mode::ECI){
$eciCharset = ECI::parseValue($bitBuffer);
$this->eciCharset = ECI::parseValue($this->bitBuffer);
}
elseif($datamode === Mode::FNC1_FIRST || $datamode === Mode::FNC1_SECOND){
// We do little with FNC1 except alter the parsed result a bit according to the spec
@@ -113,64 +116,28 @@ final class Decoder{
}
elseif($datamode === Mode::STRCTURED_APPEND){
if($bitBuffer->available() < 16){
if($this->bitBuffer->available() < 16){
throw new QRCodeDecoderException('structured append: not enough bits left');
}
// sequence number and parity is added later to the result metadata
// Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
$symbolSequence = $bitBuffer->read(8);
$parityData = $bitBuffer->read(8);
$symbolSequence = $this->bitBuffer->read(8);
$parityData = $this->bitBuffer->read(8);
}
elseif($datamode === Mode::NUMBER){
$result .= Number::decodeSegment($bitBuffer, $versionNumber);
$result .= Number::decodeSegment($this->bitBuffer, $versionNumber);
}
elseif($datamode === Mode::ALPHANUM){
$str = AlphaNum::decodeSegment($bitBuffer, $versionNumber);
// See section 6.4.8.1, 6.4.8.2
if($fc1InEffect){ // ???
// We need to massage the result a bit if in an FNC1 mode:
$str = str_replace(chr(0x1d), '%', $str);
$str = str_replace('%%', '%', $str);
}
$result .= $str;
$result .= $this->decodeAlphanumSegment($versionNumber, $fc1InEffect);
}
elseif($datamode === Mode::BYTE){
$str = Byte::decodeSegment($bitBuffer, $versionNumber);
if($eciCharset !== null){
$encoding = $eciCharset->getName();
if($encoding === null){
// The spec isn't clear on this mode; see
// section 6.4.5: t does not say which encoding to assuming
// upon decoding. I have seen ISO-8859-1 used as well as
// Shift_JIS -- without anything like an ECI designator to
// give a hint.
$encoding = mb_detect_encoding($str, ['ISO-8859-1', 'Windows-1252', 'SJIS', 'UTF-8'], true);
if($encoding === false){
throw new QRCodeDecoderException('could not determine encoding in ECI mode');
}
}
$eciCharset = null;
$str = mb_convert_encoding($str, mb_internal_encoding(), $encoding);
}
$result .= $str;
$result .= $this->decodeByteSegment($versionNumber);
}
elseif($datamode === Mode::KANJI){
$result .= Kanji::decodeSegment($bitBuffer, $versionNumber);
$result .= Kanji::decodeSegment($this->bitBuffer, $versionNumber);
}
elseif($datamode === Mode::HANZI){
// Hanzi mode contains a subset indicator right after mode indicator
if($bitBuffer->read(4) !== Hanzi::GB2312_SUBSET){
throw new QRCodeDecoderException('ecpected subset indicator for Hanzi mode');
}
$result .= Hanzi::decodeSegment($bitBuffer, $versionNumber);
$result .= Hanzi::decodeSegment($this->bitBuffer, $versionNumber);
}
else{
throw new QRCodeDecoderException('invalid data mode');
@@ -179,14 +146,60 @@ final class Decoder{
}
return new DecoderResult([
'rawBytes' => $bitBuffer,
'rawBytes' => $this->bitBuffer,
'data' => $result,
'version' => $this->version,
'eccLevel' => $this->eccLevel,
'maskPattern' => $this->maskPattern,
'structuredAppendParity' => $parityData,
'structuredAppendSequence' => $symbolSequence
'structuredAppendSequence' => $symbolSequence,
]);
}
/**
*
*/
private function decodeAlphanumSegment(int $versionNumber, bool $fc1InEffect):string{
$str = AlphaNum::decodeSegment($this->bitBuffer, $versionNumber);
// See section 6.4.8.1, 6.4.8.2
if($fc1InEffect){ // ???
// We need to massage the result a bit if in an FNC1 mode:
$str = str_replace(chr(0x1d), '%', $str);
$str = str_replace('%%', '%', $str);
}
return $str;
}
/**
* @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
*/
private function decodeByteSegment(int $versionNumber):string{
$str = Byte::decodeSegment($this->bitBuffer, $versionNumber);
if($this->eciCharset === null){
return $str;
}
$encoding = $this->eciCharset->getName();
if($encoding === null){
// The spec isn't clear on this mode; see
// section 6.4.5: t does not say which encoding to assuming
// upon decoding. I have seen ISO-8859-1 used as well as
// Shift_JIS -- without anything like an ECI designator to
// give a hint.
$encoding = mb_detect_encoding($str, ['ISO-8859-1', 'Windows-1252', 'SJIS', 'UTF-8'], true);
if($encoding === false){
throw new QRCodeDecoderException('could not determine encoding in ECI mode');
}
}
$this->eciCharset = null;
return mb_convert_encoding($str, mb_internal_encoding(), $encoding);
}
}
+1 -1
View File
@@ -55,7 +55,7 @@ class IMagickLuminanceSource extends LuminanceSourceAbstract{
$count = count($pixels);
for($i = 0; $i < $count; $i += 3){
$this->setLuminancePixel($pixels[$i] & 0xff, $pixels[$i + 1] & 0xff, $pixels[$i + 2] & 0xff);
$this->setLuminancePixel(($pixels[$i] & 0xff), ($pixels[($i + 1)] & 0xff), ($pixels[($i + 2)] & 0xff));
}
}
+4 -4
View File
@@ -36,7 +36,7 @@ abstract class LuminanceSourceAbstract implements LuminanceSourceInterface{
public function __construct(int $width, int $height, SettingsContainerInterface $options = null){
$this->width = $width;
$this->height = $height;
$this->options = $options ?? new QROptions;
$this->options = ($options ?? new QROptions);
$this->luminances = [];
}
@@ -65,7 +65,7 @@ abstract class LuminanceSourceAbstract implements LuminanceSourceInterface{
$arr = [];
array_splice($arr, 0, $this->width, array_slice($this->luminances, $y * $this->width, $this->width));
array_splice($arr, 0, $this->width, array_slice($this->luminances, ($y * $this->width), $this->width));
return $arr;
}
@@ -74,11 +74,11 @@ abstract class LuminanceSourceAbstract implements LuminanceSourceInterface{
*
*/
protected function setLuminancePixel(int $r, int $g, int $b):void{
$this->luminances[] = $r === $g && $g === $b
$this->luminances[] = ($r === $g && $g === $b)
// Image is already greyscale, so pick any channel.
? $r // (($r + 128) % 256) - 128;
// Calculate luminance cheaply, favoring green.
: ($r + 2 * $g + $b) / 4; // (((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
: (($r + 2 * $g + $b) / 4); // (((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
}
/**
+6 -1
View File
@@ -12,4 +12,9 @@ namespace chillerlan\QRCode\Decoder;
use chillerlan\QRCode\QRCodeException;
final class QRCodeDecoderException extends QRCodeException{}
/**
* An exception container
*/
final class QRCodeDecoderException extends QRCodeException{
}