smiley 2 лет назад
Родитель
Сommit
00800ef901
44 измененных файлов с 93 добавлено и 114 удалено
  1. 3 1
      examples/authenticator.php
  2. 1 1
      examples/custom_output.php
  3. 1 2
      examples/imageWithRoundedShapes.php
  4. 1 2
      examples/imagickConvertSVGtoPNG.php
  5. 1 3
      examples/imagickImageAsBackground.php
  6. 1 2
      examples/multimode.php
  7. 1 2
      examples/qrcode-interactive.php
  8. 1 2
      examples/reflectance.php
  9. 1 3
      examples/svgConvertViaCanvas.php
  10. 1 1
      examples/svgRoundQuietzone.php
  11. 2 4
      src/Common/BitBuffer.php
  12. 0 1
      src/Common/EccLevel.php
  13. 3 3
      src/Common/GDLuminanceSource.php
  14. 0 1
      src/Common/GenericGFPoly.php
  15. 3 3
      src/Common/IMagickLuminanceSource.php
  16. 3 3
      src/Common/LuminanceSourceAbstract.php
  17. 5 2
      src/Common/LuminanceSourceInterface.php
  18. 1 1
      src/Common/MaskPattern.php
  19. 0 1
      src/Data/AlphaNum.php
  20. 0 1
      src/Data/Byte.php
  21. 1 2
      src/Data/Hanzi.php
  22. 1 2
      src/Data/Kanji.php
  23. 0 1
      src/Data/Number.php
  24. 2 4
      src/Data/QRData.php
  25. 1 5
      src/Data/QRDataModeInterface.php
  26. 3 3
      src/Data/ReedSolomonEncoder.php
  27. 0 1
      src/Decoder/BitMatrix.php
  28. 15 5
      src/Decoder/Decoder.php
  29. 2 2
      src/Decoder/DecoderResult.php
  30. 7 8
      src/Decoder/ReedSolomonDecoder.php
  31. 1 2
      src/Detector/Detector.php
  32. 1 1
      src/Output/QRFpdf.php
  33. 3 5
      src/Output/QRGdImage.php
  34. 1 3
      src/Output/QRGdImageJPEG.php
  35. 1 3
      src/Output/QRGdImagePNG.php
  36. 1 3
      src/Output/QRGdImageWEBP.php
  37. 6 8
      src/Output/QRImagick.php
  38. 1 1
      src/Output/QROutputAbstract.php
  39. 4 3
      src/Output/QROutputInterface.php
  40. 3 0
      src/Output/QRStringJSON.php
  41. 1 6
      src/Output/QRStringText.php
  42. 3 3
      src/QRCode.php
  43. 4 2
      src/QROptionsTrait.php
  44. 2 2
      tests/Output/QRStringTextTest.php

+ 3 - 1
examples/authenticator.php

@@ -10,9 +10,10 @@
 
 use chillerlan\Authenticator\{Authenticator, AuthenticatorOptionsTrait};
 use chillerlan\Authenticator\Authenticators\AuthenticatorInterface;
-use chillerlan\Settings\SettingsContainerAbstract;
 use chillerlan\QRCode\{QRCode, QROptionsTrait};
 use chillerlan\QRCode\Data\QRMatrix;
+use chillerlan\QRCode\Output\QRMarkupSVG;
+use chillerlan\Settings\SettingsContainerAbstract;
 
 require_once __DIR__.'/../vendor/autoload.php';
 
@@ -35,6 +36,7 @@ $options->algorithm            = AuthenticatorInterface::ALGO_SHA512;
  */
 $options->version              = 7;
 $options->addQuietzone         = false;
+$options->outputInterface      = QRMarkupSVG::class;
 $options->outputBase64         = false;
 $options->svgAddXmlHeader      = false;
 $options->cssClass             = 'my-qrcode';

+ 1 - 1
examples/custom_output.php

@@ -40,7 +40,7 @@ class MyCustomOutput extends QROutputAbstract{
 	/**
 	 * @inheritDoc
 	 */
-	protected function getDefaultModuleValue(bool $isDark){
+	protected function getDefaultModuleValue(bool $isDark):mixed{
 		// TODO: Implement getDefaultModuleValue() method. (abstract)
 		return null;
 	}

+ 1 - 2
examples/imageWithRoundedShapes.php

@@ -13,11 +13,10 @@
  * @noinspection PhpComposerExtensionStubsInspection
  */
 
+use chillerlan\QRCode\{QRCode, QROptions};
 use chillerlan\QRCode\Common\EccLevel;
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Output\QRGdImagePNG;
-use chillerlan\QRCode\QRCode;
-use chillerlan\QRCode\QROptions;
 use chillerlan\Settings\SettingsContainerInterface;
 
 require_once __DIR__ . '/../vendor/autoload.php';

+ 1 - 2
examples/imagickConvertSVGtoPNG.php

@@ -16,10 +16,9 @@
  * @license      MIT
  */
 
+use chillerlan\QRCode\{QRCode, QROptions};
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Output\QRMarkupSVG;
-use chillerlan\QRCode\QRCode;
-use chillerlan\QRCode\QROptions;
 
 require_once __DIR__.'/../vendor/autoload.php';
 

+ 1 - 3
examples/imagickImageAsBackground.php

@@ -8,11 +8,9 @@
  * @license      MIT
  */
 
+use chillerlan\QRCode\{QRCode, QRCodeException, QROptions};
 use chillerlan\QRCode\Common\EccLevel;
 use chillerlan\QRCode\Output\QRImagick;
-use chillerlan\QRCode\QRCode;
-use chillerlan\QRCode\QRCodeException;
-use chillerlan\QRCode\QROptions;
 
 require_once __DIR__.'/../vendor/autoload.php';
 

+ 1 - 2
examples/multimode.php

@@ -8,8 +8,7 @@
  * @license      MIT
  */
 
-use chillerlan\QRCode\QRCode;
-use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\{QRCode, QROptions};
 
 require_once __DIR__.'/../vendor/autoload.php';
 

+ 1 - 2
examples/qrcode-interactive.php

@@ -8,9 +8,8 @@
  * @noinspection PhpComposerExtensionStubsInspection
  */
 
+use chillerlan\QRCode\{QRCode, QROptions};
 use chillerlan\QRCode\Data\QRMatrix;
-use chillerlan\QRCode\QRCode;
-use chillerlan\QRCode\QROptions;
 
 require_once '../vendor/autoload.php';
 

+ 1 - 2
examples/reflectance.php

@@ -8,11 +8,10 @@
  * @license      MIT
  */
 
+use chillerlan\QRCode\{QRCode, QROptions};
 use chillerlan\QRCode\Common\EccLevel;
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Output\QRMarkupSVG;
-use chillerlan\QRCode\QRCode;
-use chillerlan\QRCode\QROptions;
 
 require_once __DIR__.'/../vendor/autoload.php';
 

+ 1 - 3
examples/svgConvertViaCanvas.php

@@ -8,11 +8,9 @@
  * @license      MIT
  */
 
-
+use chillerlan\QRCode\{QRCode, QROptions};
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Output\QRMarkupSVG;
-use chillerlan\QRCode\QRCode;
-use chillerlan\QRCode\QROptions;
 
 require_once __DIR__.'/../vendor/autoload.php';
 

+ 1 - 1
examples/svgRoundQuietzone.php

@@ -12,10 +12,10 @@
  * @noinspection PhpIllegalPsrClassPathInspection
  */
 
+use chillerlan\QRCode\{QRCode, QRCodeException, QROptions};
 use chillerlan\QRCode\Common\EccLevel;
 use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Output\QRMarkupSVG;
-use chillerlan\QRCode\{QRCode, QRCodeException, QROptions};
 
 require_once __DIR__.'/../vendor/autoload.php';
 

+ 2 - 4
src/Common/BitBuffer.php

@@ -42,11 +42,9 @@ final class BitBuffer{
 
 	/**
 	 * BitBuffer constructor.
-	 *
-	 * @param int[]|null $bytes
 	 */
-	public function __construct(array $bytes = null){
-		$this->buffer = ($bytes ?? []);
+	public function __construct(array $bytes = []){
+		$this->buffer = $bytes;
 		$this->length = count($this->buffer);
 	}
 

+ 0 - 1
src/Common/EccLevel.php

@@ -11,7 +11,6 @@
 namespace chillerlan\QRCode\Common;
 
 use chillerlan\QRCode\QRCodeException;
-
 use function array_column;
 
 /**

+ 3 - 3
src/Common/GDLuminanceSource.php

@@ -33,7 +33,7 @@ final class GDLuminanceSource extends LuminanceSourceAbstract{
 	 *
 	 * @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
 	 */
-	public function __construct(GdImage $gdImage, SettingsContainerInterface|QROptions $options = null){
+	public function __construct(GdImage $gdImage, SettingsContainerInterface|QROptions $options = new QROptions){
 		parent::__construct(imagesx($gdImage), imagesy($gdImage), $options);
 
 		$this->gdImage = $gdImage;
@@ -71,12 +71,12 @@ final class GDLuminanceSource extends LuminanceSourceAbstract{
 	}
 
 	/** @inheritDoc */
-	public static function fromFile(string $path, SettingsContainerInterface $options = null):static{
+	public static function fromFile(string $path, SettingsContainerInterface|QROptions $options = new QROptions):static{
 		return new self(imagecreatefromstring(file_get_contents(self::checkFile($path))), $options);
 	}
 
 	/** @inheritDoc */
-	public static function fromBlob(string $blob, SettingsContainerInterface $options = null):static{
+	public static function fromBlob(string $blob, SettingsContainerInterface|QROptions $options = new QROptions):static{
 		return new self(imagecreatefromstring($blob), $options);
 	}
 

+ 0 - 1
src/Common/GenericGFPoly.php

@@ -12,7 +12,6 @@
 namespace chillerlan\QRCode\Common;
 
 use chillerlan\QRCode\QRCodeException;
-
 use function array_fill, array_slice, array_splice, count;
 
 /**

+ 3 - 3
src/Common/IMagickLuminanceSource.php

@@ -29,7 +29,7 @@ final class IMagickLuminanceSource extends LuminanceSourceAbstract{
 	/**
 	 * IMagickLuminanceSource constructor.
 	 */
-	public function __construct(Imagick $imagick, SettingsContainerInterface|QROptions $options = null){
+	public function __construct(Imagick $imagick, SettingsContainerInterface|QROptions $options = new QROptions){
 		parent::__construct($imagick->getImageWidth(), $imagick->getImageHeight(), $options);
 
 		$this->imagick = $imagick;
@@ -64,12 +64,12 @@ final class IMagickLuminanceSource extends LuminanceSourceAbstract{
 	}
 
 	/** @inheritDoc */
-	public static function fromFile(string $path, SettingsContainerInterface $options = null):static{
+	public static function fromFile(string $path, SettingsContainerInterface|QROptions $options = new QROptions):static{
 		return new self(new Imagick(self::checkFile($path)), $options);
 	}
 
 	/** @inheritDoc */
-	public static function fromBlob(string $blob, SettingsContainerInterface $options = null):static{
+	public static function fromBlob(string $blob, SettingsContainerInterface|QROptions $options = new QROptions):static{
 		$im = new Imagick;
 		$im->readImageBlob($blob);
 

+ 3 - 3
src/Common/LuminanceSourceAbstract.php

@@ -12,8 +12,8 @@
 
 namespace chillerlan\QRCode\Common;
 
-use chillerlan\QRCode\Decoder\QRCodeDecoderException;
 use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Decoder\QRCodeDecoderException;
 use chillerlan\Settings\SettingsContainerInterface;
 use function array_slice, array_splice, file_exists, is_file, is_readable, realpath;
 
@@ -33,10 +33,10 @@ abstract class LuminanceSourceAbstract implements LuminanceSourceInterface{
 	/**
 	 *
 	 */
-	public function __construct(int $width, int $height, SettingsContainerInterface|QROptions $options = null){
+	public function __construct(int $width, int $height, SettingsContainerInterface|QROptions $options = new QROptions){
 		$this->width   = $width;
 		$this->height  = $height;
-		$this->options = ($options ?? new QROptions);
+		$this->options = $options;
 
 		$this->luminances = [];
 	}

+ 5 - 2
src/Common/LuminanceSourceInterface.php

@@ -10,6 +10,9 @@
 
 namespace chillerlan\QRCode\Common;
 
+use chillerlan\QRCode\QROptions;
+use chillerlan\Settings\SettingsContainerInterface;
+
 /**
  */
 interface LuminanceSourceInterface{
@@ -51,11 +54,11 @@ interface LuminanceSourceInterface{
 	/**
 	 * Creates a LuminanceSource instance from the given file
 	 */
-	public static function fromFile(string $path):static;
+	public static function fromFile(string $path, SettingsContainerInterface|QROptions $options = new QROptions):static;
 
 	/**
 	 * Creates a LuminanceSource instance from the given data blob
 	 */
-	public static function fromBlob(string $blob):static;
+	public static function fromBlob(string $blob, SettingsContainerInterface|QROptions $options = new QROptions):static;
 
 }

+ 1 - 1
src/Common/MaskPattern.php

@@ -11,8 +11,8 @@
 
 namespace chillerlan\QRCode\Common;
 
-use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\QRCodeException;
+use chillerlan\QRCode\Data\QRMatrix;
 use Closure;
 use function abs, array_column, array_search, intdiv, min;
 

+ 0 - 1
src/Data/AlphaNum.php

@@ -11,7 +11,6 @@
 namespace chillerlan\QRCode\Data;
 
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
-
 use function array_flip, ceil, intdiv, str_split;
 
 /**

+ 0 - 1
src/Data/Byte.php

@@ -11,7 +11,6 @@
 namespace chillerlan\QRCode\Data;
 
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
-
 use function chr, ord;
 
 /**

+ 1 - 2
src/Data/Hanzi.php

@@ -11,7 +11,6 @@
 namespace chillerlan\QRCode\Data;
 
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
-
 use Throwable;
 use function chr, implode, intdiv, is_string, mb_convert_encoding, mb_detect_encoding,
 	mb_detect_order, mb_internal_encoding, mb_strlen, ord, sprintf, strlen;
@@ -96,7 +95,7 @@ final class Hanzi extends QRDataModeAbstract{
 		try{
 			$string = self::convertEncoding($string);
 		}
-		catch(Throwable $e){
+		catch(Throwable){
 			return false;
 		}
 

+ 1 - 2
src/Data/Kanji.php

@@ -11,7 +11,6 @@
 namespace chillerlan\QRCode\Data;
 
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
-
 use Throwable;
 use function chr, implode, intdiv, is_string, mb_convert_encoding, mb_detect_encoding,
 	mb_detect_order, mb_internal_encoding, mb_strlen, ord, sprintf, strlen;
@@ -89,7 +88,7 @@ final class Kanji extends QRDataModeAbstract{
 		try{
 			$string = self::convertEncoding($string);
 		}
-		catch(Throwable $e){
+		catch(Throwable){
 			return false;
 		}
 

+ 0 - 1
src/Data/Number.php

@@ -11,7 +11,6 @@
 namespace chillerlan\QRCode\Data;
 
 use chillerlan\QRCode\Common\{BitBuffer, Mode};
-
 use function array_flip, ceil, intdiv, str_split, substr, unpack;
 
 /**

+ 2 - 4
src/Data/QRData.php

@@ -10,12 +10,10 @@
 
 namespace chillerlan\QRCode\Data;
 
-use chillerlan\QRCode\Common\{BitBuffer, EccLevel, Mode, Version};
 use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Common\{BitBuffer, EccLevel, Mode, Version};
 use chillerlan\Settings\SettingsContainerInterface;
-
-use function count;
-use function sprintf;
+use function count, sprintf;
 
 /**
  * Processes the binary data and maps it on a QRMatrix which is then being returned

+ 1 - 5
src/Data/QRDataModeInterface.php

@@ -20,14 +20,10 @@ interface QRDataModeInterface{
 	/**
 	 * the current data mode: Number, Alphanum, Kanji, Hanzi, Byte, ECI
 	 *
-	 * tbh I hate this constant here, but it's part of the interface, so I can't just declare it in the abstract class.
-	 * (phan will complain about a PhanAccessOverridesFinalConstant)
-	 *
-	 * @see https://wiki.php.net/rfc/final_class_const
+	 * Note: do not call this constant from the interface, but rather from one of the child classes
 	 *
 	 * @var int
 	 * @see \chillerlan\QRCode\Common\Mode
-	 * @internal do not call this constant from the interface, but rather from one of the child classes
 	 */
 	public const DATAMODE = -1;
 

+ 3 - 3
src/Data/ReedSolomonEncoder.php

@@ -23,8 +23,8 @@ final class ReedSolomonEncoder{
 	private Version  $version;
 	private EccLevel $eccLevel;
 
-	private array $interleavedData;
-	private int   $interleavedDataIndex;
+	private array    $interleavedData;
+	private int      $interleavedDataIndex;
 
 	/**
 	 * ReedSolomonDecoder constructor
@@ -35,7 +35,7 @@ final class ReedSolomonEncoder{
 	}
 
 	/**
-	 * ECC interleaving
+	 * ECC encoding and interleaving
 	 *
 	 * @throws \chillerlan\QRCode\QRCodeException
 	 */

+ 0 - 1
src/Decoder/BitMatrix.php

@@ -97,7 +97,6 @@ final class BitMatrix extends QRMatrix{
 		// mirror vertically
 		$this->matrix = array_reverse($this->matrix);
 		// rotate by 90 degrees clockwise
-		/** @phan-suppress-next-line PhanTypeMismatchReturnSuperType */
 		return $this->rotate90();
 	}
 

+ 15 - 5
src/Decoder/Decoder.php

@@ -11,9 +11,11 @@
 
 namespace chillerlan\QRCode\Decoder;
 
+use chillerlan\QRCode\QROptions;
 use chillerlan\QRCode\Common\{BitBuffer, EccLevel, LuminanceSourceInterface, MaskPattern, Mode, Version};
 use chillerlan\QRCode\Data\{AlphaNum, Byte, ECI, Hanzi, Kanji, Number};
 use chillerlan\QRCode\Detector\Detector;
+use chillerlan\Settings\SettingsContainerInterface;
 use Throwable;
 use function chr, str_replace;
 
@@ -25,10 +27,18 @@ use function chr, str_replace;
  */
 final class Decoder{
 
-	private ?Version     $version = null;
-	private ?EccLevel    $eccLevel = null;
-	private ?MaskPattern $maskPattern = null;
-	private BitBuffer    $bitBuffer;
+	/**
+	 * @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface
+	 */
+	private SettingsContainerInterface|QROptions   $options;
+	private ?Version                               $version     = null;
+	private ?EccLevel                              $eccLevel    = null;
+	private ?MaskPattern                           $maskPattern = null;
+	private BitBuffer                              $bitBuffer;
+
+	public function __construct(SettingsContainerInterface|QROptions $options = new QROptions){
+		$this->options = $options;
+	}
 
 	/**
 	 * Decodes a QR Code represented as a BitMatrix.
@@ -56,7 +66,7 @@ final class Decoder{
 				 */
 				return $this->decodeMatrix($matrix->resetVersionInfo()->mirrorDiagonal());
 			}
-			catch(Throwable $f){
+			catch(Throwable){
 				// Throw the exception from the original reading
 				throw $e;
 			}

+ 2 - 2
src/Decoder/DecoderResult.php

@@ -11,8 +11,8 @@
 
 namespace chillerlan\QRCode\Decoder;
 
-use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\Common\{BitBuffer, EccLevel, MaskPattern, Version};
+use chillerlan\QRCode\Data\QRMatrix;
 use function property_exists;
 
 /**
@@ -85,7 +85,7 @@ final class DecoderResult{
 	}
 
 	/**
-	 * Returns a QRMatrix instance with thesettings and data of the reader result
+	 * Returns a QRMatrix instance with the settings and data of the reader result
 	 */
 	public function getQRMatrix():QRMatrix{
 		return (new QRMatrix($this->version, $this->eccLevel))

+ 7 - 8
src/Decoder/ReedSolomonDecoder.php

@@ -12,7 +12,6 @@
 namespace chillerlan\QRCode\Decoder;
 
 use chillerlan\QRCode\Common\{BitBuffer, EccLevel, GenericGFPoly, GF256, Version};
-use chillerlan\QRCode\QRCodeException;
 use function array_fill, array_reverse, count;
 
 /**
@@ -167,7 +166,7 @@ final class ReedSolomonDecoder{
 	 * @param int   $numEccCodewords number of error-correction codewords available
 	 *
 	 * @return int[]
-	 * @throws \chillerlan\QRCode\QRCodeException if decoding fails for any reason
+	 * @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException if decoding fails for any reason
 	 */
 	private function decodeWords(array $received, int $numEccCodewords):array{
 		$poly                 = new GenericGFPoly($received);
@@ -201,7 +200,7 @@ final class ReedSolomonDecoder{
 			$position = ($receivedCount - 1 - GF256::log($errorLocations[$i]));
 
 			if($position < 0){
-				throw new QRCodeException('Bad error location');
+				throw new QRCodeDecoderException('Bad error location');
 			}
 
 			$received[$position] ^= $errorMagnitudes[$i];
@@ -212,7 +211,7 @@ final class ReedSolomonDecoder{
 
 	/**
 	 * @return \chillerlan\QRCode\Common\GenericGFPoly[] [sigma, omega]
-	 * @throws \chillerlan\QRCode\QRCodeException
+	 * @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
 	 */
 	private function runEuclideanAlgorithm(GenericGFPoly $a, GenericGFPoly $b, int $z):array{
 		// Assume a's degree is >= b's
@@ -240,14 +239,14 @@ final class ReedSolomonDecoder{
 			$t = $q->multiply($tLast)->addOrSubtract($tLastLast);
 
 			if($r->getDegree() >= $rLast->getDegree()){
-				throw new QRCodeException('Division algorithm failed to reduce polynomial?');
+				throw new QRCodeDecoderException('Division algorithm failed to reduce polynomial?');
 			}
 		}
 
 		$sigmaTildeAtZero = $t->getCoefficient(0);
 
 		if($sigmaTildeAtZero === 0){
-			throw new QRCodeException('sigmaTilde(0) was zero');
+			throw new QRCodeDecoderException('sigmaTilde(0) was zero');
 		}
 
 		$inverse = GF256::inverse($sigmaTildeAtZero);
@@ -256,7 +255,7 @@ final class ReedSolomonDecoder{
 	}
 
 	/**
-	 * @throws \chillerlan\QRCode\QRCodeException
+	 * @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException
 	 */
 	private function findErrorLocations(GenericGFPoly $errorLocator):array{
 		// This is a direct application of Chien's search
@@ -277,7 +276,7 @@ final class ReedSolomonDecoder{
 		}
 
 		if($e !== $numErrors){
-			throw new QRCodeException('Error locator degree does not match number of roots');
+			throw new QRCodeDecoderException('Error locator degree does not match number of roots');
 		}
 
 		return $result;

+ 1 - 2
src/Detector/Detector.php

@@ -11,9 +11,8 @@
 
 namespace chillerlan\QRCode\Detector;
 
-use chillerlan\QRCode\Decoder\Binarizer;
 use chillerlan\QRCode\Common\{LuminanceSourceInterface, Version};
-use chillerlan\QRCode\Decoder\BitMatrix;
+use chillerlan\QRCode\Decoder\{Binarizer, BitMatrix};
 use function abs, intdiv, is_nan, max, min, round;
 use const NAN;
 

+ 1 - 1
src/Output/QRFpdf.php

@@ -11,8 +11,8 @@
 
 namespace chillerlan\QRCode\Output;
 
-use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\Settings\SettingsContainerInterface;
 use FPDF;
 

+ 3 - 5
src/Output/QRGdImage.php

@@ -12,8 +12,8 @@
 
 namespace chillerlan\QRCode\Output;
 
-use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\Settings\SettingsContainerInterface;
 use ErrorException, GdImage, Throwable;
 use function array_values, count, extension_loaded, gd_info, imagecolorallocate, imagecolortransparent,
@@ -90,7 +90,7 @@ abstract class QRGdImage extends QROutputAbstract{
 			QRGdImageWEBP::class => 'WebP Support',
 		];
 
-		// likely using default or custom output
+		// likely using custom output
 		if(!isset($modes[$this->options->outputInterface])){
 			return;
 		}
@@ -217,10 +217,8 @@ abstract class QRGdImage extends QROutputAbstract{
 	 * we're scaling the image up in order to draw crisp round circles, otherwise they appear square-y on small scales
 	 *
 	 * @see https://github.com/chillerlan/php-qrcode/issues/23
-	 *
-	 * @return \GdImage|resource
 	 */
-	protected function createImage(){
+	protected function createImage():GdImage{
 
 		if($this->drawCircularModules && $this->options->gdImageUseUpscale && $this->options->scale < 20){
 			// increase the initial image size by 10

+ 1 - 3
src/Output/QRGdImageJPEG.php

@@ -12,9 +12,7 @@
 
 namespace chillerlan\QRCode\Output;
 
-use function imagejpeg;
-use function max;
-use function min;
+use function imagejpeg, max, min;
 
 /**
  * GdImage jpeg output

+ 1 - 3
src/Output/QRGdImagePNG.php

@@ -12,9 +12,7 @@
 
 namespace chillerlan\QRCode\Output;
 
-use function imagepng;
-use function max;
-use function min;
+use function imagepng, max, min;
 
 /**
  * GdImage png output

+ 1 - 3
src/Output/QRGdImageWEBP.php

@@ -12,9 +12,7 @@
 
 namespace chillerlan\QRCode\Output;
 
-use function imagewebp;
-use function max;
-use function min;
+use function imagewebp, max, min;
 
 /**
  * GdImage webp output

+ 6 - 8
src/Output/QRImagick.php

@@ -12,11 +12,11 @@
 
 namespace chillerlan\QRCode\Output;
 
-use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\Settings\SettingsContainerInterface;
 use finfo, Imagick, ImagickDraw, ImagickPixel;
-use function extension_loaded, in_array, is_string, max, min, preg_match, strlen;
+use function extension_loaded, in_array, is_string, max, min, preg_match, sprintf, strlen;
 use const FILEINFO_MIME_TYPE;
 
 /**
@@ -49,12 +49,10 @@ class QRImagick extends QROutputAbstract{
 	 */
 	public function __construct(SettingsContainerInterface|QROptions $options, QRMatrix $matrix){
 
-		if(!extension_loaded('imagick')){
-			throw new QRCodeOutputException('ext-imagick not loaded'); // @codeCoverageIgnore
-		}
-
-		if(!extension_loaded('fileinfo')){
-			throw new QRCodeOutputException('ext-fileinfo not loaded'); // @codeCoverageIgnore
+		foreach(['fileinfo', 'imagick'] as $ext){
+			if(!extension_loaded($ext)){
+				throw new QRCodeOutputException(sprintf('ext-%s not loaded', $ext)); // @codeCoverageIgnore
+			}
 		}
 
 		parent::__construct($options, $matrix);

+ 1 - 1
src/Output/QROutputAbstract.php

@@ -10,8 +10,8 @@
 
 namespace chillerlan\QRCode\Output;
 
-use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Data\QRMatrix;
 use chillerlan\Settings\SettingsContainerInterface;
 use Closure;
 use function base64_encode, dirname, file_put_contents, is_writable, ksort, sprintf;

+ 4 - 3
src/Output/QROutputInterface.php

@@ -105,9 +105,10 @@ interface QROutputInterface{
 	];
 
 	/**
-	 * @var      string
-	 * @see      \chillerlan\QRCode\Output\QROutputAbstract::toBase64DataURI()
-	 * @internal do not call this constant from the interface, but rather from one of the child classes
+	 * Note: do not call this constant from the interface, but rather from one of the child classes
+	 *
+	 * @var string
+	 * @see \chillerlan\QRCode\Output\QROutputAbstract::toBase64DataURI()
 	 */
 	public const MIME_TYPE = '';
 

+ 3 - 0
src/Output/QRStringJSON.php

@@ -38,6 +38,7 @@ class QRStringJSON extends QROutputAbstract{
 	 * unused - required by interface
 	 *
 	 * @inheritDoc
+	 * @codeCoverageIgnore
 	 */
 	protected function prepareModuleValue(mixed $value):string{
 		return '';
@@ -47,6 +48,7 @@ class QRStringJSON extends QROutputAbstract{
 	 * unused - required by interface
 	 *
 	 * @inheritDoc
+	 * @codeCoverageIgnore
 	 */
 	protected function getDefaultModuleValue(bool $isDark):string{
 		return '';
@@ -56,6 +58,7 @@ class QRStringJSON extends QROutputAbstract{
 	 * unused - required by interface
 	 *
 	 * @inheritDoc
+	 * @codeCoverageIgnore
 	 */
 	public static function moduleValueIsValid(mixed $value):bool{
 		return true;

+ 1 - 6
src/Output/QRStringText.php

@@ -10,12 +10,7 @@
 
 namespace chillerlan\QRCode\Output;
 
-use function array_map;
-use function implode;
-use function is_string;
-use function max;
-use function min;
-use function sprintf;
+use function array_map, implode, is_string, max, min, sprintf;
 
 /**
  *

+ 3 - 3
src/QRCode.php

@@ -54,8 +54,8 @@ class QRCode{
 	 *
 	 * PHP8: accept iterable
 	 */
-	public function __construct(SettingsContainerInterface|QROptions $options = null){
-		$this->setOptions(($options ?? new QROptions));
+	public function __construct(SettingsContainerInterface|QROptions $options = new QROptions){
+		$this->setOptions($options);
 	}
 
 	/**
@@ -292,7 +292,7 @@ class QRCode{
 	 * Reads a QR Code from the given luminance source
 	 */
 	public function readFromSource(LuminanceSourceInterface $source):DecoderResult{
-		return (new Decoder)->decode($source);
+		return (new Decoder($this->options))->decode($source);
 	}
 
 }

+ 4 - 2
src/QROptionsTrait.php

@@ -14,8 +14,8 @@
 
 namespace chillerlan\QRCode;
 
-use chillerlan\QRCode\Output\QRMarkupSVG;
 use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Version};
+use chillerlan\QRCode\Output\QRMarkupSVG;
 use function constant, extension_loaded, in_array, is_string, max, min, sprintf, strtolower, strtoupper, trim;
 use const JSON_THROW_ON_ERROR, PHP_EOL;
 
@@ -54,13 +54,15 @@ trait QROptionsTrait{
 	/**
 	 * Error correct level
 	 *
-	 * `EccLevel::X` where `X` is:
+	 * the constant `EccLevel::X` where `X` is:
 	 *
 	 * - `L` =>  7% (default)
 	 * - `M` => 15%
 	 * - `Q` => 25%
 	 * - `H` => 30%
 	 *
+	 * alternatively you can just pass the letters L/M/Q/H (case-insensitive) to the magic setter
+	 *
 	 * @see \chillerlan\QRCode\Common\EccLevel
 	 * @see https://github.com/chillerlan/php-qrcode/discussions/160
 	 */

+ 2 - 2
tests/Output/QRStringTEXTTest.php → tests/Output/QRStringTextTest.php

@@ -1,6 +1,6 @@
 <?php
 /**
- * Class QRStringTEXTTest
+ * Class QRStringTextTest
  *
  * @created      11.12.2021
  * @author       smiley <smiley@chillerlan.net>
@@ -18,7 +18,7 @@ use chillerlan\Settings\SettingsContainerInterface;
 /**
  *
  */
-final class QRStringTEXTTest extends QROutputTestAbstract{
+final class QRStringTextTest extends QROutputTestAbstract{
 
 	protected function getOutputInterface(
 		SettingsContainerInterface|QROptions $options,