From 04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 9 Jan 2020 10:55:03 +0100 Subject: phpmyadmin working --- .../vendor/bacon/bacon-qr-code/CHANGELOG.md | 37 ++ srcs/phpmyadmin/vendor/bacon/bacon-qr-code/LICENSE | 22 + .../vendor/bacon/bacon-qr-code/README.md | 39 ++ .../vendor/bacon/bacon-qr-code/composer.json | 32 + .../bacon/bacon-qr-code/src/Common/BitArray.php | 372 ++++++++++++ .../bacon/bacon-qr-code/src/Common/BitMatrix.php | 313 ++++++++++ .../bacon/bacon-qr-code/src/Common/BitUtils.php | 41 ++ .../bacon-qr-code/src/Common/CharacterSetEci.php | 180 ++++++ .../bacon/bacon-qr-code/src/Common/EcBlock.php | 49 ++ .../bacon/bacon-qr-code/src/Common/EcBlocks.php | 74 +++ .../src/Common/ErrorCorrectionLevel.php | 63 ++ .../bacon-qr-code/src/Common/FormatInformation.php | 203 +++++++ .../vendor/bacon/bacon-qr-code/src/Common/Mode.php | 76 +++ .../bacon-qr-code/src/Common/ReedSolomonCodec.php | 468 +++++++++++++++ .../bacon/bacon-qr-code/src/Common/Version.php | 596 +++++++++++++++++++ .../bacon/bacon-qr-code/src/Encoder/BlockPair.php | 58 ++ .../bacon/bacon-qr-code/src/Encoder/ByteMatrix.php | 150 +++++ .../bacon/bacon-qr-code/src/Encoder/Encoder.php | 652 +++++++++++++++++++++ .../bacon/bacon-qr-code/src/Encoder/MaskUtil.php | 271 +++++++++ .../bacon/bacon-qr-code/src/Encoder/MatrixUtil.php | 513 ++++++++++++++++ .../bacon/bacon-qr-code/src/Encoder/QrCode.php | 141 +++++ .../src/Exception/ExceptionInterface.php | 10 + .../src/Exception/InvalidArgumentException.php | 8 + .../src/Exception/OutOfBoundsException.php | 8 + .../src/Exception/RuntimeException.php | 8 + .../src/Exception/UnexpectedValueException.php | 8 + .../src/Exception/WriterException.php | 8 + .../bacon-qr-code/src/Renderer/Color/Alpha.php | 57 ++ .../bacon-qr-code/src/Renderer/Color/Cmyk.php | 103 ++++ .../src/Renderer/Color/ColorInterface.php | 22 + .../bacon-qr-code/src/Renderer/Color/Gray.php | 46 ++ .../bacon/bacon-qr-code/src/Renderer/Color/Rgb.php | 88 +++ .../src/Renderer/Eye/CompositeEye.php | 38 ++ .../src/Renderer/Eye/EyeInterface.php | 26 + .../bacon-qr-code/src/Renderer/Eye/ModuleEye.php | 54 ++ .../src/Renderer/Eye/SimpleCircleEye.php | 54 ++ .../bacon-qr-code/src/Renderer/Eye/SquareEye.php | 53 ++ .../src/Renderer/Image/EpsImageBackEnd.php | 376 ++++++++++++ .../src/Renderer/Image/ImageBackEndInterface.php | 87 +++ .../src/Renderer/Image/ImagickImageBackEnd.php | 339 +++++++++++ .../src/Renderer/Image/SvgImageBackEnd.php | 369 ++++++++++++ .../src/Renderer/Image/TransformationMatrix.php | 67 +++ .../bacon-qr-code/src/Renderer/ImageRenderer.php | 152 +++++ .../src/Renderer/Module/DotsModule.php | 63 ++ .../src/Renderer/Module/EdgeIterator/Edge.php | 100 ++++ .../Renderer/Module/EdgeIterator/EdgeIterator.php | 169 ++++++ .../src/Renderer/Module/ModuleInterface.php | 18 + .../src/Renderer/Module/RoundnessModule.php | 129 ++++ .../src/Renderer/Module/SquareModule.php | 47 ++ .../bacon-qr-code/src/Renderer/Path/Close.php | 29 + .../bacon-qr-code/src/Renderer/Path/Curve.php | 92 +++ .../src/Renderer/Path/EllipticArc.php | 278 +++++++++ .../bacon/bacon-qr-code/src/Renderer/Path/Line.php | 41 ++ .../bacon/bacon-qr-code/src/Renderer/Path/Move.php | 41 ++ .../src/Renderer/Path/OperationInterface.php | 12 + .../bacon/bacon-qr-code/src/Renderer/Path/Path.php | 106 ++++ .../src/Renderer/PlainTextRenderer.php | 86 +++ .../src/Renderer/RendererInterface.php | 11 + .../src/Renderer/RendererStyle/EyeFill.php | 74 +++ .../src/Renderer/RendererStyle/Fill.php | 168 ++++++ .../src/Renderer/RendererStyle/Gradient.php | 46 ++ .../src/Renderer/RendererStyle/GradientType.php | 22 + .../src/Renderer/RendererStyle/RendererStyle.php | 90 +++ .../vendor/bacon/bacon-qr-code/src/Writer.php | 68 +++ 64 files changed, 8021 insertions(+) create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/CHANGELOG.md create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/LICENSE create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/README.md create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/composer.json create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Version.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/InvalidArgumentException.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/OutOfBoundsException.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/RuntimeException.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/UnexpectedValueException.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/WriterException.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Alpha.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Gray.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/ModuleEye.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImagickImageBackEnd.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/RoundnessModule.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Curve.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Path.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/EyeFill.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/RendererStyle.php create mode 100644 srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Writer.php (limited to 'srcs/phpmyadmin/vendor/bacon') diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/CHANGELOG.md b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/CHANGELOG.md new file mode 100644 index 0000000..3409ee6 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/CHANGELOG.md @@ -0,0 +1,37 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 2.0.0 - 2018-04-25 + +### Added + +- [#25](https://github.com/Bacon/BaconQrCode/pull/25) allows for setting a more compact text output + +- CHANGELOG.md added (how meta) + +- Allows more complex shapes for modules + +- Allows setting a gradient for the foreground + +- Allows transparent backgrounds and alpha channel on all colors + +### Changed + +- Minimum PHP version changed to 7.1 + +- Imagick renderer now allows setting different output formats + +- New optimized SVG renderer + +### Deprecated + +- Nothing. + +### Removed + +- Legacy ZF module support removed + +### Fixed + +- Non-release files are excluded from composer packages diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/LICENSE b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/LICENSE new file mode 100644 index 0000000..d45a356 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2017, Ben Scholzen 'DASPRiD' +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/README.md b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/README.md new file mode 100644 index 0000000..ba006c1 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/README.md @@ -0,0 +1,39 @@ +# QR Code generator + +[![Build Status](https://api.travis-ci.org/Bacon/BaconQrCode.png?branch=master)](http://travis-ci.org/Bacon/BaconQrCode) +[![Coverage Status](https://coveralls.io/repos/github/Bacon/BaconQrCode/badge.svg?branch=master)](https://coveralls.io/github/Bacon/BaconQrCode?branch=master) +[![Latest Stable Version](https://poser.pugx.org/bacon/bacon-qr-code/v/stable)](https://packagist.org/packages/bacon/bacon-qr-code) +[![Total Downloads](https://poser.pugx.org/bacon/bacon-qr-code/downloads)](https://packagist.org/packages/bacon/bacon-qr-code) +[![License](https://poser.pugx.org/bacon/bacon-qr-code/license)](https://packagist.org/packages/bacon/bacon-qr-code) + + +## Introduction +BaconQrCode is a port of QR code portion of the ZXing library. It currently +only features the encoder part, but could later receive the decoder part as +well. + +As the Reed Solomon codec implementation of the ZXing library performs quite +slow in PHP, it was exchanged with the implementation by Phil Karn. + + +## Example usage +```php +use BaconQrCode\Renderer\ImageRenderer; +use BaconQrCode\Renderer\Image\ImagickImageBackEnd; +use BaconQrCode\Renderer\RendererStyle\RendererStyle; +use BaconQrCode\Writer; + +$renderer = new ImageRenderer( + new RendererStyle(400), + new ImagickImageBackEnd() +); +$writer = new Writer($renderer); +$writer->writeFile('Hello World!', 'qrcode.png'); +``` + +## Available image renderer back ends +BaconQrCode comes with multiple back ends for rendering images. Currently included are the following: + +- `ImagickImageBackEnd`: renders raster images using the Imagick library +- `SvgImageBackEnd`: renders SVG files using XMLWriter +- `EpsImageBackEnd`: renders EPS files diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/composer.json b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/composer.json new file mode 100644 index 0000000..d66d586 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/composer.json @@ -0,0 +1,32 @@ +{ + "name": "bacon/bacon-qr-code", + "description": "BaconQrCode is a QR code generator for PHP.", + "license" : "BSD-2-Clause", + "homepage": "https://github.com/Bacon/BaconQrCode", + "require": { + "php": "^7.1", + "ext-iconv": "*", + "dasprid/enum": "^1.0" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "http://www.dasprids.de", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "require-dev": { + "phpunit/phpunit": "^6.4", + "squizlabs/php_codesniffer": "^3.1", + "phly/keep-a-changelog": "^1.4" + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php new file mode 100644 index 0000000..158384f --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php @@ -0,0 +1,372 @@ + + */ + private $bits; + + /** + * Size of the bit array in bits. + * + * @var int + */ + private $size; + + /** + * Creates a new bit array with a given size. + */ + public function __construct(int $size = 0) + { + $this->size = $size; + $this->bits = SplFixedArray::fromArray(array_fill(0, ($this->size + 31) >> 3, 0)); + } + + /** + * Gets the size in bits. + */ + public function getSize() : int + { + return $this->size; + } + + /** + * Gets the size in bytes. + */ + public function getSizeInBytes() : int + { + return ($this->size + 7) >> 3; + } + + /** + * Ensures that the array has a minimum capacity. + */ + public function ensureCapacity(int $size) : void + { + if ($size > count($this->bits) << 5) { + $this->bits->setSize(($size + 31) >> 5); + } + } + + /** + * Gets a specific bit. + */ + public function get(int $i) : bool + { + return 0 !== ($this->bits[$i >> 5] & (1 << ($i & 0x1f))); + } + + /** + * Sets a specific bit. + */ + public function set(int $i) : void + { + $this->bits[$i >> 5] = $this->bits[$i >> 5] | 1 << ($i & 0x1f); + } + + /** + * Flips a specific bit. + */ + public function flip(int $i) : void + { + $this->bits[$i >> 5] ^= 1 << ($i & 0x1f); + } + + /** + * Gets the next set bit position from a given position. + */ + public function getNextSet(int $from) : int + { + if ($from >= $this->size) { + return $this->size; + } + + $bitsOffset = $from >> 5; + $currentBits = $this->bits[$bitsOffset]; + $bitsLength = count($this->bits); + $currentBits &= ~((1 << ($from & 0x1f)) - 1); + + while (0 === $currentBits) { + if (++$bitsOffset === $bitsLength) { + return $this->size; + } + + $currentBits = $this->bits[$bitsOffset]; + } + + $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits); + return $result > $this->size ? $this->size : $result; + } + + /** + * Gets the next unset bit position from a given position. + */ + public function getNextUnset(int $from) : int + { + if ($from >= $this->size) { + return $this->size; + } + + $bitsOffset = $from >> 5; + $currentBits = ~$this->bits[$bitsOffset]; + $bitsLength = count($this->bits); + $currentBits &= ~((1 << ($from & 0x1f)) - 1); + + while (0 === $currentBits) { + if (++$bitsOffset === $bitsLength) { + return $this->size; + } + + $currentBits = ~$this->bits[$bitsOffset]; + } + + $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits); + return $result > $this->size ? $this->size : $result; + } + + /** + * Sets a bulk of bits. + */ + public function setBulk(int $i, int $newBits) : void + { + $this->bits[$i >> 5] = $newBits; + } + + /** + * Sets a range of bits. + * + * @throws InvalidArgumentException if end is smaller than start + */ + public function setRange(int $start, int $end) : void + { + if ($end < $start) { + throw new InvalidArgumentException('End must be greater or equal to start'); + } + + if ($end === $start) { + return; + } + + --$end; + + $firstInt = $start >> 5; + $lastInt = $end >> 5; + + for ($i = $firstInt; $i <= $lastInt; ++$i) { + $firstBit = $i > $firstInt ? 0 : $start & 0x1f; + $lastBit = $i < $lastInt ? 31 : $end & 0x1f; + + if (0 === $firstBit && 31 === $lastBit) { + $mask = 0x7fffffff; + } else { + $mask = 0; + + for ($j = $firstBit; $j < $lastBit; ++$j) { + $mask |= 1 << $j; + } + } + + $this->bits[$i] = $this->bits[$i] | $mask; + } + } + + /** + * Clears the bit array, unsetting every bit. + */ + public function clear() : void + { + $bitsLength = count($this->bits); + + for ($i = 0; $i < $bitsLength; ++$i) { + $this->bits[$i] = 0; + } + } + + /** + * Checks if a range of bits is set or not set. + + * @throws InvalidArgumentException if end is smaller than start + */ + public function isRange(int $start, int $end, bool $value) : bool + { + if ($end < $start) { + throw new InvalidArgumentException('End must be greater or equal to start'); + } + + if ($end === $start) { + return true; + } + + --$end; + + $firstInt = $start >> 5; + $lastInt = $end >> 5; + + for ($i = $firstInt; $i <= $lastInt; ++$i) { + $firstBit = $i > $firstInt ? 0 : $start & 0x1f; + $lastBit = $i < $lastInt ? 31 : $end & 0x1f; + + if (0 === $firstBit && 31 === $lastBit) { + $mask = 0x7fffffff; + } else { + $mask = 0; + + for ($j = $firstBit; $j <= $lastBit; ++$j) { + $mask |= 1 << $j; + } + } + + if (($this->bits[$i] & $mask) !== ($value ? $mask : 0)) { + return false; + } + } + + return true; + } + + /** + * Appends a bit to the array. + */ + public function appendBit(bool $bit) : void + { + $this->ensureCapacity($this->size + 1); + + if ($bit) { + $this->bits[$this->size >> 5] = $this->bits[$this->size >> 5] | (1 << ($this->size & 0x1f)); + } + + ++$this->size; + } + + /** + * Appends a number of bits (up to 32) to the array. + + * @throws InvalidArgumentException if num bits is not between 0 and 32 + */ + public function appendBits(int $value, int $numBits) : void + { + if ($numBits < 0 || $numBits > 32) { + throw new InvalidArgumentException('Num bits must be between 0 and 32'); + } + + $this->ensureCapacity($this->size + $numBits); + + for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) { + $this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) === 1); + } + } + + /** + * Appends another bit array to this array. + */ + public function appendBitArray(self $other) : void + { + $otherSize = $other->getSize(); + $this->ensureCapacity($this->size + $other->getSize()); + + for ($i = 0; $i < $otherSize; ++$i) { + $this->appendBit($other->get($i)); + } + } + + /** + * Makes an exclusive-or comparision on the current bit array. + * + * @throws InvalidArgumentException if sizes don't match + */ + public function xorBits(self $other) : void + { + $bitsLength = count($this->bits); + $otherBits = $other->getBitArray(); + + if ($bitsLength !== count($otherBits)) { + throw new InvalidArgumentException('Sizes don\'t match'); + } + + for ($i = 0; $i < $bitsLength; ++$i) { + $this->bits[$i] = $this->bits[$i] ^ $otherBits[$i]; + } + } + + /** + * Converts the bit array to a byte array. + * + * @return SplFixedArray + */ + public function toBytes(int $bitOffset, int $numBytes) : SplFixedArray + { + $bytes = new SplFixedArray($numBytes); + + for ($i = 0; $i < $numBytes; ++$i) { + $byte = 0; + + for ($j = 0; $j < 8; ++$j) { + if ($this->get($bitOffset)) { + $byte |= 1 << (7 - $j); + } + + ++$bitOffset; + } + + $bytes[$i] = $byte; + } + + return $bytes; + } + + /** + * Gets the internal bit array. + * + * @return SplFixedArray + */ + public function getBitArray() : SplFixedArray + { + return $this->bits; + } + + /** + * Reverses the array. + */ + public function reverse() : void + { + $newBits = new SplFixedArray(count($this->bits)); + + for ($i = 0; $i < $this->size; ++$i) { + if ($this->get($this->size - $i - 1)) { + $newBits[$i >> 5] = $newBits[$i >> 5] | (1 << ($i & 0x1f)); + } + } + + $this->bits = $newBits; + } + + /** + * Returns a string representation of the bit array. + */ + public function __toString() : string + { + $result = ''; + + for ($i = 0; $i < $this->size; ++$i) { + if (0 === ($i & 0x07)) { + $result .= ' '; + } + + $result .= $this->get($i) ? 'X' : '.'; + } + + return $result; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php new file mode 100644 index 0000000..10bf8fe --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php @@ -0,0 +1,313 @@ + + */ + private $bits; + + /** + * @throws InvalidArgumentException if a dimension is smaller than zero + */ + public function __construct(int $width, int $height = null) + { + if (null === $height) { + $height = $width; + } + + if ($width < 1 || $height < 1) { + throw new InvalidArgumentException('Both dimensions must be greater than zero'); + } + + $this->width = $width; + $this->height = $height; + $this->rowSize = ($width + 31) >> 5; + $this->bits = SplFixedArray::fromArray(array_fill(0, $this->rowSize * $height, 0)); + } + + /** + * Gets the requested bit, where true means black. + */ + public function get(int $x, int $y) : bool + { + $offset = $y * $this->rowSize + ($x >> 5); + return 0 !== (BitUtils::unsignedRightShift($this->bits[$offset], ($x & 0x1f)) & 1); + } + + /** + * Sets the given bit to true. + */ + public function set(int $x, int $y) : void + { + $offset = $y * $this->rowSize + ($x >> 5); + $this->bits[$offset] = $this->bits[$offset] | (1 << ($x & 0x1f)); + } + + /** + * Flips the given bit. + */ + public function flip(int $x, int $y) : void + { + $offset = $y * $this->rowSize + ($x >> 5); + $this->bits[$offset] = $this->bits[$offset] ^ (1 << ($x & 0x1f)); + } + + /** + * Clears all bits (set to false). + */ + public function clear() : void + { + $max = count($this->bits); + + for ($i = 0; $i < $max; ++$i) { + $this->bits[$i] = 0; + } + } + + /** + * Sets a square region of the bit matrix to true. + * + * @throws InvalidArgumentException if left or top are negative + * @throws InvalidArgumentException if width or height are smaller than 1 + * @throws InvalidArgumentException if region does not fit into the matix + */ + public function setRegion(int $left, int $top, int $width, int $height) : void + { + if ($top < 0 || $left < 0) { + throw new InvalidArgumentException('Left and top must be non-negative'); + } + + if ($height < 1 || $width < 1) { + throw new InvalidArgumentException('Width and height must be at least 1'); + } + + $right = $left + $width; + $bottom = $top + $height; + + if ($bottom > $this->height || $right > $this->width) { + throw new InvalidArgumentException('The region must fit inside the matrix'); + } + + for ($y = $top; $y < $bottom; ++$y) { + $offset = $y * $this->rowSize; + + for ($x = $left; $x < $right; ++$x) { + $index = $offset + ($x >> 5); + $this->bits[$index] = $this->bits[$index] | (1 << ($x & 0x1f)); + } + } + } + + /** + * A fast method to retrieve one row of data from the matrix as a BitArray. + */ + public function getRow(int $y, BitArray $row = null) : BitArray + { + if (null === $row || $row->getSize() < $this->width) { + $row = new BitArray($this->width); + } + + $offset = $y * $this->rowSize; + + for ($x = 0; $x < $this->rowSize; ++$x) { + $row->setBulk($x << 5, $this->bits[$offset + $x]); + } + + return $row; + } + + /** + * Sets a row of data from a BitArray. + */ + public function setRow(int $y, BitArray $row) : void + { + $bits = $row->getBitArray(); + + for ($i = 0; $i < $this->rowSize; ++$i) { + $this->bits[$y * $this->rowSize + $i] = $bits[$i]; + } + } + + /** + * This is useful in detecting the enclosing rectangle of a 'pure' barcode. + * + * @return int[]|null + */ + public function getEnclosingRectangle() : ?array + { + $left = $this->width; + $top = $this->height; + $right = -1; + $bottom = -1; + + for ($y = 0; $y < $this->height; ++$y) { + for ($x32 = 0; $x32 < $this->rowSize; ++$x32) { + $bits = $this->bits[$y * $this->rowSize + $x32]; + + if (0 !== $bits) { + if ($y < $top) { + $top = $y; + } + + if ($y > $bottom) { + $bottom = $y; + } + + if ($x32 * 32 < $left) { + $bit = 0; + + while (($bits << (31 - $bit)) === 0) { + $bit++; + } + + if (($x32 * 32 + $bit) < $left) { + $left = $x32 * 32 + $bit; + } + } + } + + if ($x32 * 32 + 31 > $right) { + $bit = 31; + + while (0 === BitUtils::unsignedRightShift($bits, $bit)) { + --$bit; + } + + if (($x32 * 32 + $bit) > $right) { + $right = $x32 * 32 + $bit; + } + } + } + } + + $width = $right - $left; + $height = $bottom - $top; + + if ($width < 0 || $height < 0) { + return null; + } + + return [$left, $top, $width, $height]; + } + + /** + * Gets the most top left set bit. + * + * This is useful in detecting a corner of a 'pure' barcode. + * + * @return int[]|null + */ + public function getTopLeftOnBit() : ?array + { + $bitsOffset = 0; + + while ($bitsOffset < count($this->bits) && 0 === $this->bits[$bitsOffset]) { + ++$bitsOffset; + } + + if (count($this->bits) === $bitsOffset) { + return null; + } + + $x = intdiv($bitsOffset, $this->rowSize); + $y = ($bitsOffset % $this->rowSize) << 5; + + $bits = $this->bits[$bitsOffset]; + $bit = 0; + + while (0 === ($bits << (31 - $bit))) { + ++$bit; + } + + $x += $bit; + + return [$x, $y]; + } + + /** + * Gets the most bottom right set bit. + * + * This is useful in detecting a corner of a 'pure' barcode. + * + * @return int[]|null + */ + public function getBottomRightOnBit() : ?array + { + $bitsOffset = count($this->bits) - 1; + + while ($bitsOffset >= 0 && 0 === $this->bits[$bitsOffset]) { + --$bitsOffset; + } + + if ($bitsOffset < 0) { + return null; + } + + $x = intdiv($bitsOffset, $this->rowSize); + $y = ($bitsOffset % $this->rowSize) << 5; + + $bits = $this->bits[$bitsOffset]; + $bit = 0; + + while (0 === BitUtils::unsignedRightShift($bits, $bit)) { + --$bit; + } + + $x += $bit; + + return [$x, $y]; + } + + /** + * Gets the width of the matrix, + */ + public function getWidth() : int + { + return $this->width; + } + + /** + * Gets the height of the matrix. + */ + public function getHeight() : int + { + return $this->height; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php new file mode 100644 index 0000000..0c575b4 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php @@ -0,0 +1,41 @@ +>>" in other + * languages. + */ + public static function unsignedRightShift(int $a, int $b) : int + { + return ( + $a >= 0 + ? $a >> $b + : (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1)) + ); + } + + /** + * Gets the number of trailing zeros. + */ + public static function numberOfTrailingZeros(int $i) : int + { + $lastPos = strrpos(str_pad(decbin($i), 32, '0', STR_PAD_LEFT), '1'); + return $lastPos === false ? 32 : 31 - $lastPos; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php new file mode 100644 index 0000000..6dfff17 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php @@ -0,0 +1,180 @@ +|null + */ + private static $valueToEci; + + /** + * @var array|null + */ + private static $nameToEci; + + public function __construct(array $values, string ...$otherEncodingNames) + { + $this->values = $values; + $this->otherEncodingNames = $otherEncodingNames; + } + + /** + * Returns the primary value. + */ + public function getValue() : int + { + return $this->values[0]; + } + + /** + * Gets character set ECI by value. + * + * Returns the representing ECI of a given value, or null if it is legal but unsupported. + * + * @throws InvalidArgumentException if value is not between 0 and 900 + */ + public static function getCharacterSetEciByValue(int $value) : ?self + { + if ($value < 0 || $value >= 900) { + throw new InvalidArgumentException('Value must be between 0 and 900'); + } + + $valueToEci = self::valueToEci(); + + if (! array_key_exists($value, $valueToEci)) { + return null; + } + + return $valueToEci[$value]; + } + + /** + * Returns character set ECI by name. + * + * Returns the representing ECI of a given name, or null if it is legal but unsupported + */ + public static function getCharacterSetEciByName(string $name) : ?self + { + $nameToEci = self::nameToEci(); + $name = strtolower($name); + + if (! array_key_exists($name, $nameToEci)) { + return null; + } + + return $nameToEci[$name]; + } + + private static function valueToEci() : array + { + if (null !== self::$valueToEci) { + return self::$valueToEci; + } + + self::$valueToEci = []; + + foreach (self::values() as $eci) { + foreach ($eci->values as $value) { + self::$valueToEci[$value] = $eci; + } + } + + return self::$valueToEci; + } + + private static function nameToEci() : array + { + if (null !== self::$nameToEci) { + return self::$nameToEci; + } + + self::$nameToEci = []; + + foreach (self::values() as $eci) { + self::$nameToEci[strtolower($eci->name())] = $eci; + + foreach ($eci->otherEncodingNames as $name) { + self::$nameToEci[strtolower($name)] = $eci; + } + } + + return self::$nameToEci; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php new file mode 100644 index 0000000..a9a1d07 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php @@ -0,0 +1,49 @@ +count = $count; + $this->dataCodewords = $dataCodewords; + } + + /** + * Returns how many times the block is used. + */ + public function getCount() : int + { + return $this->count; + } + + /** + * Returns the number of data codewords. + */ + public function getDataCodewords() : int + { + return $this->dataCodewords; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php new file mode 100644 index 0000000..172b5f2 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php @@ -0,0 +1,74 @@ +ecCodewordsPerBlock = $ecCodewordsPerBlock; + $this->ecBlocks = $ecBlocks; + } + + /** + * Returns the number of EC codewords per block. + */ + public function getEcCodewordsPerBlock() : int + { + return $this->ecCodewordsPerBlock; + } + + /** + * Returns the total number of EC block appearances. + */ + public function getNumBlocks() : int + { + $total = 0; + + foreach ($this->ecBlocks as $ecBlock) { + $total += $ecBlock->getCount(); + } + + return $total; + } + + /** + * Returns the total count of EC codewords. + */ + public function getTotalEcCodewords() : int + { + return $this->ecCodewordsPerBlock * $this->getNumBlocks(); + } + + /** + * Returns the EC blocks included in this collection. + * + * @return EcBlock[] + */ + public function getEcBlocks() : array + { + return $this->ecBlocks; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php new file mode 100644 index 0000000..9bbf440 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php @@ -0,0 +1,63 @@ +bits = $bits; + } + + /** + * @throws OutOfBoundsException if number of bits is invalid + */ + public static function forBits(int $bits) : self + { + switch ($bits) { + case 0: + return self::M(); + + case 1: + return self::L(); + + case 2: + return self::H(); + + case 3: + return self::Q(); + } + + throw new OutOfBoundsException('Invalid number of bits'); + } + + /** + * Returns the two bits used to encode this error correction level. + */ + public function getBits() : int + { + return $this->bits; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php new file mode 100644 index 0000000..53e3541 --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php @@ -0,0 +1,203 @@ +ecLevel = ErrorCorrectionLevel::forBits(($formatInfo >> 3) & 0x3); + $this->dataMask = $formatInfo & 0x7; + } + + /** + * Checks how many bits are different between two integers. + */ + public static function numBitsDiffering(int $a, int $b) : int + { + $a ^= $b; + + return ( + self::BITS_SET_IN_HALF_BYTE[$a & 0xf] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 4) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 8) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 12) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 16) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 20) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 24) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 28) & 0xf)] + ); + } + + /** + * Decodes format information. + */ + public static function decodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self + { + $formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2); + + if (null !== $formatInfo) { + return $formatInfo; + } + + // Should return null, but, some QR codes apparently do not mask this info. Try again by actually masking the + // pattern first. + return self::doDecodeFormatInformation( + $maskedFormatInfo1 ^ self::FORMAT_INFO_MASK_QR, + $maskedFormatInfo2 ^ self::FORMAT_INFO_MASK_QR + ); + } + + /** + * Internal method for decoding format information. + */ + private static function doDecodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self + { + $bestDifference = PHP_INT_MAX; + $bestFormatInfo = 0; + + foreach (self::FORMAT_INFO_DECODE_LOOKUP as $decodeInfo) { + $targetInfo = $decodeInfo[0]; + + if ($targetInfo === $maskedFormatInfo1 || $targetInfo === $maskedFormatInfo2) { + // Found an exact match + return new self($decodeInfo[1]); + } + + $bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo); + + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + + if ($maskedFormatInfo1 !== $maskedFormatInfo2) { + // Also try the other option + $bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo); + + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + } + } + + // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match. + if ($bestDifference <= 3) { + return new self($bestFormatInfo); + } + + return null; + } + + /** + * Returns the error correction level. + */ + public function getErrorCorrectionLevel() : ErrorCorrectionLevel + { + return $this->ecLevel; + } + + /** + * Returns the data mask. + */ + public function getDataMask() : int + { + return $this->dataMask; + } + + /** + * Hashes the code of the EC level. + */ + public function hashCode() : int + { + return ($this->ecLevel->getBits() << 3) | $this->dataMask; + } + + /** + * Verifies if this instance equals another one. + */ + public function equals(self $other) : bool + { + return ( + $this->ecLevel === $other->ecLevel + && $this->dataMask === $other->dataMask + ); + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php new file mode 100644 index 0000000..51e6c9a --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php @@ -0,0 +1,76 @@ +characterCountBitsForVersions = $characterCountBitsForVersions; + $this->bits = $bits; + } + + /** + * Returns the number of bits used in a specific QR code version. + */ + public function getCharacterCountBits(Version $version) : int + { + $number = $version->getVersionNumber(); + + if ($number <= 9) { + $offset = 0; + } elseif ($number <= 26) { + $offset = 1; + } else { + $offset = 2; + } + + return $this->characterCountBitsForVersions[$offset]; + } + + /** + * Returns the four bits used to encode this mode. + */ + public function getBits() : int + { + return $this->bits; + } +} diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php new file mode 100644 index 0000000..a5aad0b --- /dev/null +++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php @@ -0,0 +1,468 @@ + 8) { + throw new InvalidArgumentException('Symbol size must be between 0 and 8'); + } + + if ($firstRoot < 0 || $firstRoot >= (1 << $symbolSize)) { + throw new InvalidArgumentException('First root must be between 0 and ' . (1 << $symbolSize)); + } + + if ($numRoots < 0 || $numRoots >= (1 << $symbolSize)) { + throw new InvalidArgumentException('Num roots must be between 0 and ' . (1 << $symbolSize)); + } + + if ($padding < 0 || $padding >= ((1 << $symbolSize) - 1 - $numRoots)) { + throw new InvalidArgumentException( + 'Padding must be between 0 and ' . ((1 << $symbolSize) - 1 - $numRoots) + ); + } + + $this->symbolSize = $symbolSize; + $this->blockSize = (1 << $symbolSize) - 1; + $this->padding = $padding; + $this->alphaTo = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false); + $this->indexOf = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false); + + // Generate galous field lookup table + $this->indexOf[0] = $this->blockSize; + $this->alphaTo[$this->blockSize] = 0; + + $sr = 1; + + for ($i = 0; $i < $this->blockSize; ++$i) { + $this->indexOf[$sr] = $i; + $this->alphaTo[$i] = $sr; + + $sr <<= 1; + + if ($sr & (1 << $symbolSize)) { + $sr ^= $gfPoly; + } + + $sr &= $this->blockSize; + } + + if (1 !== $sr) { + throw new RuntimeException('Field generator polynomial is not primitive'); + } + + // Form RS code generator polynomial from its roots + $this->generatorPoly = SplFixedArray::fromArray(array_fill(0, $numRoots + 1, 0), false); + $this->firstRoot = $firstRoot; + $this->primitive = $primitive; + $this->numRoots = $numRoots; + + // Find prim-th root of 1, used in decoding + for ($iPrimitive = 1; ($iPrimitive % $primitive) !== 0; $iPrimitive += $this->blockSize) { + } + + $this->iPrimitive = intdiv($iPrimitive, $primitive); + + $this->generatorPoly[0] = 1; + + for ($i = 0, $root = $firstRoot * $primitive; $i < $numRoots; ++$i, $root += $primitive) { + $this->generatorPoly[$i + 1] = 1; + + for ($j = $i; $j > 0; $j--) { + if ($this->generatorPoly[$j] !== 0) { + $this->generatorPoly[$j] = $this->generatorPoly[$j - 1] ^ $this->alphaTo[ + $this->modNn($this->indexOf[$this->generatorPoly[$j]] + $root) + ]; + } else { + $this->generatorPoly[$j] = $this->generatorPoly[$j - 1]; + } + } + + $this->generatorPoly[$j] = $this->alphaTo[$this->modNn($this->indexOf[$this->generatorPoly[0]] + $root)]; + } + + // Convert generator poly to index form for quicker encoding + for ($i = 0; $i <= $numRoots; ++$i) { + $this->generatorPoly[$i] = $this->indexOf[$this->generatorPoly[$i]]; + } + } + + /** + * Encodes data and writes result back into parity array. + */ + public function encode(SplFixedArray $data, SplFixedArray $parity) : void + { + for ($i = 0; $i < $this->numRoots; ++$i) { + $parity[$i] = 0; + } + + $iterations = $this->blockSize - $this->numRoots - $this->padding; + + for ($i = 0; $i < $iterations; ++$i) { + $feedback = $this->indexOf[$data[$i] ^ $parity[0]]; + + if ($feedback !== $this->blockSize) { + // Feedback term is non-zero + $feedback = $this->modNn($this->blockSize - $this->generatorPoly[$this->numRoots] + $feedback); + + for ($j = 1; $j < $this->numRoots; ++$j) { + $parity[$j] = $parity[$j] ^ $this->alphaTo[ + $this->modNn($feedback + $this->generatorPoly[$this->numRoots - $j]) + ]; + } + } + + for ($j = 0; $j < $this->numRoots - 1; ++$j) { + $parity[$j] = $parity[$j + 1]; + } + + if ($feedback !== $this->blockSize) { + $parity[$this->numRoots - 1] = $this->alphaTo[$this->modNn($feedback + $this->generatorPoly[0])]; + } else { + $parity[$this->numRoots - 1] = 0; + } + } + } + + /** + * Decodes received data. + */ + public function decode(SplFixedArray $data, SplFixedArray $erasures = null) : ?int + { + // This speeds up the initialization a bit. + $numRootsPlusOne = SplFixedArray::fromArray(array_fill(0, $this->numRoots + 1, 0), false); + $numRoots = SplFixedArray::fromArray(array_fill(0, $this->numRoots, 0), false); + + $lambda = clone $numRootsPlusOne; + $b = clone $numRootsPlusOne; + $t = clone $numRootsPlusOne; + $omega = clone $numRootsPlusOne; + $root = clone $numRoots; + $loc = clone $numRoots; + + $numErasures = (null !== $erasures ? count($erasures) : 0); + + // Form the Syndromes; i.e., evaluate data(x) at roots of g(x) + $syndromes = SplFixedArray::fromArray(array_fill(0, $this->numRoots, $data[0]), false); + + for ($i = 1; $i < $this->blockSize - $this->padding; ++$i) { + for ($j = 0; $j < $this->numRoots; ++$j) { + if ($syndromes[$j] === 0) { + $syndromes[$j] = $data[$i]; + } else { + $syndromes[$j] = $data[$i] ^ $this->alphaTo[ + $this->modNn($this->indexOf[$syndromes[$j]] + ($this->firstRoot + $j) * $this->primitive) + ]; + } + } + } + + // Convert syndromes to index form, checking for nonzero conditions + $syndromeError = 0; + + for ($i = 0; $i < $this->numRoots; ++$i) { + $syndromeError |= $syndromes[$i]; + $syndromes[$i] = $this->indexOf[$syndromes[$i]]; + } + + if (! $syndromeError) { + // If syndrome is zero, data[] is a codeword and there are no errors to correct, so return data[] + // unmodified. + return 0; + } + + $lambda[0] = 1; + + if ($numErasures > 0) { + // Init lambda to be the erasure locator polynomial + $lambda[1] = $this->alphaTo[$this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[0]))]; + + for ($i = 1; $i < $numErasures; ++$i) { + $u = $this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[$i])); + + for ($j = $i + 1; $j > 0; --$j) { + $tmp = $this->indexOf[$lambda[$j - 1]]; + + if ($tmp !== $this->blockSize) { + $lambda[$j] = $lambda[$j] ^ $this->alphaTo[$this->modNn($u + $tmp)]; + } + } + } + } + + for ($i = 0; $i <= $this->numRoots; ++$i) { + $b[$i] = $this->indexOf[$lambda[$i]]; + } + + // Begin Berlekamp-Massey algorithm to determine error+erasure locator polynomial + $r = $numErasures; + $el = $numErasures; + + while (++$r <= $this->numRoots) { + // Compute discrepancy at the r-th step in poly form + $discrepancyR = 0; + + for ($i = 0; $i < $r; ++$i) { + if ($lambda[$i] !== 0 && $syndromes[$r - $i - 1] !== $this->blockSize) { + $discrepancyR ^= $this->alphaTo[ + $this->modNn($this->indexOf[$lambda[$i]] + $syndromes[$r - $i - 1]) + ]; + } + } + + $discrepancyR = $this