添加网站文件
This commit is contained in:
95
vendor/khanamiryan/qrcode-detector-decoder/lib/common/AbstractEnum.php
vendored
Normal file
95
vendor/khanamiryan/qrcode-detector-decoder/lib/common/AbstractEnum.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Zxing\Common\CharacterSetEci\AbstractEnum;
|
||||
|
||||
use \Zxing\NotFoundException;
|
||||
use ReflectionClass;
|
||||
/**
|
||||
* A general enum implementation until we got SplEnum.
|
||||
*/
|
||||
final class AbstractEnum
|
||||
{
|
||||
/**
|
||||
* Default value.
|
||||
*/
|
||||
const __default = null;
|
||||
/**
|
||||
* Current value.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $value;
|
||||
/**
|
||||
* Cache of constants.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $constants;
|
||||
/**
|
||||
* Whether to handle values strict or not.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $strict;
|
||||
/**
|
||||
* Creates a new enum.
|
||||
*
|
||||
* @param mixed $initialValue
|
||||
* @param boolean $strict
|
||||
*/
|
||||
public function __construct($initialValue = null, $strict = false)
|
||||
{
|
||||
$this->strict = $strict;
|
||||
$this->change($initialValue);
|
||||
}
|
||||
/**
|
||||
* Changes the value of the enum.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function change($value)
|
||||
{
|
||||
if (!in_array($value, $this->getConstList(), $this->strict)) {
|
||||
throw new Exception\UnexpectedValueException('Value not a const in enum ' . get_class($this));
|
||||
}
|
||||
$this->value = $value;
|
||||
}
|
||||
/**
|
||||
* Gets current value.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
/**
|
||||
* Gets all constants (possible values) as an array.
|
||||
*
|
||||
* @param boolean $includeDefault
|
||||
* @return array
|
||||
*/
|
||||
public function getConstList($includeDefault = true)
|
||||
{
|
||||
if ($this->constants === null) {
|
||||
$reflection = new ReflectionClass($this);
|
||||
$this->constants = $reflection->getConstants();
|
||||
}
|
||||
if ($includeDefault) {
|
||||
return $this->constants;
|
||||
}
|
||||
$constants = $this->constants;
|
||||
unset($constants['__default']);
|
||||
return $constants;
|
||||
}
|
||||
/**
|
||||
* Gets the name of the enum.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return array_search($this->value, $this->getConstList());
|
||||
}
|
||||
}
|
||||
394
vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitArray.php
vendored
Normal file
394
vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitArray.php
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Ashot
|
||||
* Date: 3/25/15
|
||||
* Time: 11:51
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
/**
|
||||
* <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
final class BitArray {
|
||||
|
||||
private $bits;
|
||||
private $size;
|
||||
|
||||
|
||||
|
||||
public function __construct($bits=array(),$size=0) {
|
||||
|
||||
if(!$bits&&!$size){
|
||||
$this->$size = 0;
|
||||
$this->bits = array();
|
||||
}elseif($bits&&!$size){
|
||||
$this->size = $bits;
|
||||
$this->bits = $this->makeArray($bits);
|
||||
}else{
|
||||
$this->bits = $bits;
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function getSize() {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function getSizeInBytes() {
|
||||
return ($this->size + 7) / 8;
|
||||
}
|
||||
|
||||
private function ensureCapacity($size) {
|
||||
if ($size > count($this->bits) * 32) {
|
||||
$newBits = $this->makeArray($size);
|
||||
$newBits = arraycopy($this->bits, 0, $newBits, 0, count($this->bits));
|
||||
$this->bits = $newBits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $i; bit to get
|
||||
* @return true iff bit i is set
|
||||
*/
|
||||
public function get($i) {
|
||||
$key = intval($i / 32);
|
||||
return intval32bits($this->bits[$key] & (1 << ($i & 0x1F))) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bit i.
|
||||
*
|
||||
* @param i bit to set
|
||||
*/
|
||||
public function set($i) {
|
||||
$this->bits[intval($i / 32)] |= 1 << ($i & 0x1F);
|
||||
$this->bits[intval($i / 32)] = overflow($this->bits[intval($i / 32)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips bit i.
|
||||
*
|
||||
* @param i bit to set
|
||||
*/
|
||||
public function flip($i) {
|
||||
$this->bits[intval($i / 32)] ^= 1 << ($i & 0x1F);
|
||||
$this->bits[intval($i / 32)] = overflow32($this->bits[intval($i / 32)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param from first bit to check
|
||||
* @return index of first bit that is set, starting from the given index, or size if none are set
|
||||
* at or beyond this given index
|
||||
* @see #getNextUnset(int)
|
||||
*/
|
||||
public function getNextSet($from) {
|
||||
if ($from >= $this->size) {
|
||||
return $this->size;
|
||||
}
|
||||
$bitsOffset = intval($from / 32);
|
||||
$currentBits = (int)$this->bits[$bitsOffset];
|
||||
// mask off lesser bits first
|
||||
$currentBits &= ~((1 << ($from & 0x1F)) - 1);
|
||||
while ($currentBits == 0) {
|
||||
if (++$bitsOffset == count($this->bits)) {
|
||||
return $this->size;
|
||||
}
|
||||
$currentBits = $this->bits[$bitsOffset];
|
||||
}
|
||||
$result = ($bitsOffset * 32) + numberOfTrailingZeros($currentBits); //numberOfTrailingZeros
|
||||
return $result > $this->size ? $this->size : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param from index to start looking for unset bit
|
||||
* @return index of next unset bit, or {@code size} if none are unset until the end
|
||||
* @see #getNextSet(int)
|
||||
*/
|
||||
public function getNextUnset($from) {
|
||||
if ($from >= $this->size) {
|
||||
return $this->size;
|
||||
}
|
||||
$bitsOffset = intval($from / 32);
|
||||
$currentBits = ~$this->bits[$bitsOffset];
|
||||
// mask off lesser bits first
|
||||
$currentBits &= ~((1 << ($from & 0x1F)) - 1);
|
||||
while ($currentBits == 0) {
|
||||
if (++$bitsOffset == count($this->bits)) {
|
||||
return $this->size;
|
||||
}
|
||||
$currentBits = overflow32(~$this->bits[$bitsOffset]);
|
||||
}
|
||||
$result = ($bitsOffset * 32) + numberOfTrailingZeros($currentBits);
|
||||
return $result > $this->size ? $this->size : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a block of 32 bits, starting at bit i.
|
||||
*
|
||||
* @param i first bit to set
|
||||
* @param newBits the new value of the next 32 bits. Note again that the least-significant bit
|
||||
* corresponds to bit i, the next-least-significant to i+1, and so on.
|
||||
*/
|
||||
public function setBulk($i, $newBits) {
|
||||
$this->bits[intval($i / 32)] = $newBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a range of bits.
|
||||
*
|
||||
* @param start start of range, inclusive.
|
||||
* @param end end of range, exclusive
|
||||
*/
|
||||
public function setRange($start, $end) {
|
||||
if ($end < $start) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
if ($end == $start) {
|
||||
return;
|
||||
}
|
||||
$end--; // will be easier to treat this as the last actually set bit -- inclusive
|
||||
$firstInt = intval($start / 32);
|
||||
$lastInt = intval($end / 32);
|
||||
for ($i = $firstInt; $i <= $lastInt; $i++) {
|
||||
$firstBit = $i > $firstInt ? 0 : $start & 0x1F;
|
||||
$lastBit = $i < $lastInt ? 31 : $end & 0x1F;
|
||||
$mask = 0;
|
||||
if ($firstBit == 0 && $lastBit == 31) {
|
||||
$mask = -1;
|
||||
} else {
|
||||
$mask = 0;
|
||||
for ($j = $firstBit; $j <= $lastBit; $j++) {
|
||||
$mask |= 1 << $j;
|
||||
}
|
||||
}
|
||||
$this->bits[$i] = overflow32($this->bits[$i]|$mask);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all bits (sets to false).
|
||||
*/
|
||||
public function clear() {
|
||||
$max = count($this->bits);
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
$this->bits[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Efficient method to check if a range of bits is set, or not set.
|
||||
*
|
||||
* @param start start of range, inclusive.
|
||||
* @param end end of range, exclusive
|
||||
* @param value if true, checks that bits in range are set, otherwise checks that they are not set
|
||||
* @return true iff all bits are set or not set in range, according to value argument
|
||||
* @throws InvalidArgumentException if end is less than or equal to start
|
||||
*/
|
||||
public function isRange($start, $end, $value) {
|
||||
if ($end < $start) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
if ($end == $start) {
|
||||
return true; // empty range matches
|
||||
}
|
||||
$end--; // will be easier to treat this as the last actually set bit -- inclusive
|
||||
$firstInt = intval($start / 32);
|
||||
$lastInt = intval($end / 32);
|
||||
for ($i = $firstInt; $i <= $lastInt; $i++) {
|
||||
$firstBit = $i > $firstInt ? 0 : $start & 0x1F;
|
||||
$lastBit = $i < $lastInt ? 31 :$end & 0x1F;
|
||||
$mask = 0;
|
||||
if ($firstBit == 0 && $lastBit == 31) {
|
||||
$mask = -1;
|
||||
} else {
|
||||
$mask = 0;
|
||||
for ($j = $firstBit; $j <= $lastBit; $j++) {
|
||||
$mask = overflow32($mask|(1 << $j));
|
||||
}
|
||||
}
|
||||
|
||||
// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
|
||||
// equals the mask, or we're looking for 0s and the masked portion is not all 0s
|
||||
if (($this->bits[$i] & $mask) != ($value ? $mask : 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function appendBit($bit) {
|
||||
$this->ensureCapacity($this->size + 1);
|
||||
if ($bit) {
|
||||
$this->bits[intval($this->size / 32)] |= 1 << ($this->size & 0x1F);
|
||||
}
|
||||
$this->size++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the least-significant bits, from value, in order from most-significant to
|
||||
* least-significant. For example, appending 6 bits from 0x000001E will append the bits
|
||||
* 0, 1, 1, 1, 1, 0 in that order.
|
||||
*
|
||||
* @param value {@code int} containing bits to append
|
||||
* @param numBits bits from value to append
|
||||
*/
|
||||
public function appendBits($value, $numBits) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public function appendBitArray($other) {
|
||||
$otherSize = $other->size;
|
||||
$this->ensureCapacity($this->size + $otherSize);
|
||||
for ($i = 0; $i < $otherSize; $i++) {
|
||||
$this->appendBit($other->get($i));
|
||||
}
|
||||
}
|
||||
|
||||
public function _xor($other) {
|
||||
if (count($this->bits) != count($other->bits)) {
|
||||
throw new \InvalidArgumentException("Sizes don't match");
|
||||
}
|
||||
for ($i = 0; $i < count($this->bits); $i++) {
|
||||
// The last byte could be incomplete (i.e. not have 8 bits in
|
||||
// it) but there is no problem since 0 XOR 0 == 0.
|
||||
$this->bits[$i] ^= $other->bits[$i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bitOffset first bit to start writing
|
||||
* @param array array to write into. Bytes are written most-significant byte first. This is the opposite
|
||||
* of the internal representation, which is exposed by {@link #getBitArray()}
|
||||
* @param offset position in array to start writing
|
||||
* @param numBytes how many bytes to write
|
||||
*/
|
||||
public function toBytes($bitOffset, &$array, $offset, $numBytes) {
|
||||
for ($i = 0; $i < $numBytes; $i++) {
|
||||
$theByte = 0;
|
||||
for ($j = 0; $j < 8; $j++) {
|
||||
if ($this->get($bitOffset)) {
|
||||
$theByte |= 1 << (7 - $j);
|
||||
}
|
||||
$bitOffset++;
|
||||
}
|
||||
$array[(int)($offset + $i)] = $theByte;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return underlying array of ints. The first element holds the first 32 bits, and the least
|
||||
* significant bit is bit 0.
|
||||
*/
|
||||
public function getBitArray() {
|
||||
return $this->bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses all bits in the array.
|
||||
*/
|
||||
public function reverse() {
|
||||
$newBits = array();
|
||||
// reverse all int's first
|
||||
$len = (($this->size-1) / 32);
|
||||
$oldBitsLen = $len + 1;
|
||||
for ($i = 0; $i < $oldBitsLen; $i++) {
|
||||
$x = $this->bits[$i];/*
|
||||
$x = (($x >> 1) & 0x55555555L) | (($x & 0x55555555L) << 1);
|
||||
$x = (($x >> 2) & 0x33333333L) | (($x & 0x33333333L) << 2);
|
||||
$x = (($x >> 4) & 0x0f0f0f0fL) | (($x & 0x0f0f0f0fL) << 4);
|
||||
$x = (($x >> 8) & 0x00ff00ffL) | (($x & 0x00ff00ffL) << 8);
|
||||
$x = (($x >> 16) & 0x0000ffffL) | (($x & 0x0000ffffL) << 16);*/
|
||||
$x = (($x >> 1) & 0x55555555) | (($x & 0x55555555) << 1);
|
||||
$x = (($x >> 2) & 0x33333333) | (($x & 0x33333333) << 2);
|
||||
$x = (($x >> 4) & 0x0f0f0f0f) | (($x & 0x0f0f0f0f) << 4);
|
||||
$x = (($x >> 8) & 0x00ff00ff) | (($x & 0x00ff00ff) << 8);
|
||||
$x = (($x >> 16) & 0x0000ffff) | (($x & 0x0000ffff) << 16);
|
||||
$newBits[(int)$len - $i] = (int) $x;
|
||||
}
|
||||
// now correct the int's if the bit size isn't a multiple of 32
|
||||
if ($this->size != $oldBitsLen * 32) {
|
||||
$leftOffset = $oldBitsLen * 32 - $this->size;
|
||||
$mask = 1;
|
||||
for ($i = 0; $i < 31 - $leftOffset; $i++) {
|
||||
$mask = ($mask << 1) | 1;
|
||||
}
|
||||
$currentInt = ($newBits[0] >> $leftOffset) & $mask;
|
||||
for ($i = 1; $i < $oldBitsLen; $i++) {
|
||||
$nextInt = $newBits[$i];
|
||||
$currentInt |= $nextInt << (32 - $leftOffset);
|
||||
$newBits[intval($i) - 1] = $currentInt;
|
||||
$currentInt = ($nextInt >> $leftOffset) & $mask;
|
||||
}
|
||||
$newBits[intval($oldBitsLen) - 1] = $currentInt;
|
||||
}
|
||||
$bits = $newBits;
|
||||
}
|
||||
|
||||
private static function makeArray($size) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// @Override
|
||||
public function equals($o) {
|
||||
if (!($o instanceof BitArray)) {
|
||||
return false;
|
||||
}
|
||||
$other = $o;
|
||||
return $this->size == $other->size && $this->bits===$other->bits;
|
||||
}
|
||||
|
||||
//@Override
|
||||
public function hashCode() {
|
||||
return 31 * $this->size +hashCode($this->bits);
|
||||
}
|
||||
|
||||
// @Override
|
||||
public function toString() {
|
||||
$result = '';
|
||||
for ($i = 0; $i < $this->size; $i++) {
|
||||
if (($i & 0x07) == 0) {
|
||||
$result.=' ';
|
||||
}
|
||||
$result.= ($this->get($i) ? 'X' : '.');
|
||||
}
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public function _clone() {
|
||||
return new BitArray($this->bits, $this->size);
|
||||
}
|
||||
|
||||
}
|
||||
424
vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitMatrix.php
vendored
Normal file
424
vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitMatrix.php
vendored
Normal file
File diff suppressed because one or more lines are too long
112
vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php
vendored
Normal file
112
vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
/**
|
||||
* <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the
|
||||
* number of bits read is not often a multiple of 8.</p>
|
||||
*
|
||||
* <p>This class is thread-safe but not reentrant -- unless the caller modifies the bytes array
|
||||
* it passed in, in which case all bets are off.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class BitSource {
|
||||
|
||||
private $bytes;
|
||||
private $byteOffset = 0;
|
||||
private $bitOffset = 0;
|
||||
|
||||
/**
|
||||
* @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
|
||||
* Bits are read within a byte from most-significant to least-significant bit.
|
||||
*/
|
||||
public function __construct($bytes) {
|
||||
$this->bytes = $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}.
|
||||
*/
|
||||
public function getBitOffset() {
|
||||
return $this->bitOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}.
|
||||
*/
|
||||
public function getByteOffset() {
|
||||
return $this->byteOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numBits number of bits to read
|
||||
* @return int representing the bits read. The bits will appear as the least-significant
|
||||
* bits of the int
|
||||
* @throws IllegalArgumentException if numBits isn't in [1,32] or more than is available
|
||||
*/
|
||||
public function readBits($numBits) {
|
||||
if ($numBits < 1 || $numBits > 32 || $numBits > $this->available()) {
|
||||
throw new \InvalidArgumentException(strval($numBits));
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
|
||||
// First, read remainder from current byte
|
||||
if ($this->bitOffset > 0) {
|
||||
$bitsLeft = 8 - $this->bitOffset;
|
||||
$toRead = $numBits < $bitsLeft ? $numBits : $bitsLeft;
|
||||
$bitsToNotRead = $bitsLeft - $toRead;
|
||||
$mask = (0xFF >> (8 - $toRead)) << $bitsToNotRead;
|
||||
$result = ($this->bytes[$this->byteOffset] & $mask) >> $bitsToNotRead;
|
||||
$numBits -= $toRead;
|
||||
$this->bitOffset += $toRead;
|
||||
if ($this->bitOffset == 8) {
|
||||
$this->bitOffset = 0;
|
||||
$this->byteOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
// Next read whole bytes
|
||||
if ($numBits > 0) {
|
||||
while ($numBits >= 8) {
|
||||
$result = ($result << 8) | ($this->bytes[$this->byteOffset] & 0xFF);
|
||||
$this->byteOffset++;
|
||||
$numBits -= 8;
|
||||
}
|
||||
|
||||
// Finally read a partial byte
|
||||
if ($numBits > 0) {
|
||||
$bitsToNotRead = 8 - $numBits;
|
||||
$mask = (0xFF >> $bitsToNotRead) << $bitsToNotRead;
|
||||
$result = ($result << $numBits) | (($this->bytes[$this->byteOffset] & $mask) >> $bitsToNotRead);
|
||||
$this->bitOffset += $numBits;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of bits that can be read successfully
|
||||
*/
|
||||
public function available() {
|
||||
return 8 * (count($this->bytes) - $this->byteOffset) - $this->bitOffset;
|
||||
}
|
||||
|
||||
}
|
||||
154
vendor/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php
vendored
Normal file
154
vendor/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Zxing\Common;
|
||||
use Zxing\Common\AbstractEnum;
|
||||
/**
|
||||
* Encapsulates a Character Set ECI, according to "Extended Channel
|
||||
* Interpretations" 5.3.1.1 of ISO 18004.
|
||||
*/
|
||||
final class CharacterSetECI
|
||||
{
|
||||
private static $name = null;
|
||||
/**#@+
|
||||
* Character set constants.
|
||||
*/
|
||||
const CP437 = 0;
|
||||
const ISO8859_1 = 1;
|
||||
const ISO8859_2 = 4;
|
||||
const ISO8859_3 = 5;
|
||||
const ISO8859_4 = 6;
|
||||
const ISO8859_5 = 7;
|
||||
const ISO8859_6 = 8;
|
||||
const ISO8859_7 = 9;
|
||||
const ISO8859_8 = 10;
|
||||
const ISO8859_9 = 11;
|
||||
const ISO8859_10 = 12;
|
||||
const ISO8859_11 = 13;
|
||||
const ISO8859_12 = 14;
|
||||
const ISO8859_13 = 15;
|
||||
const ISO8859_14 = 16;
|
||||
const ISO8859_15 = 17;
|
||||
const ISO8859_16 = 18;
|
||||
const SJIS = 20;
|
||||
const CP1250 = 21;
|
||||
const CP1251 = 22;
|
||||
const CP1252 = 23;
|
||||
const CP1256 = 24;
|
||||
const UNICODE_BIG_UNMARKED = 25;
|
||||
const UTF8 = 26;
|
||||
const ASCII = 27;
|
||||
const BIG5 = 28;
|
||||
const GB18030 = 29;
|
||||
const EUC_KR = 30;
|
||||
/**#@-*/
|
||||
/**
|
||||
* Map between character names and their ECI values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $nameToEci = array(
|
||||
'ISO-8859-1' => self::ISO8859_1,
|
||||
'ISO-8859-2' => self::ISO8859_2,
|
||||
'ISO-8859-3' => self::ISO8859_3,
|
||||
'ISO-8859-4' => self::ISO8859_4,
|
||||
'ISO-8859-5' => self::ISO8859_5,
|
||||
'ISO-8859-6' => self::ISO8859_6,
|
||||
'ISO-8859-7' => self::ISO8859_7,
|
||||
'ISO-8859-8' => self::ISO8859_8,
|
||||
'ISO-8859-9' => self::ISO8859_9,
|
||||
'ISO-8859-10' => self::ISO8859_10,
|
||||
'ISO-8859-11' => self::ISO8859_11,
|
||||
'ISO-8859-12' => self::ISO8859_12,
|
||||
'ISO-8859-13' => self::ISO8859_13,
|
||||
'ISO-8859-14' => self::ISO8859_14,
|
||||
'ISO-8859-15' => self::ISO8859_15,
|
||||
'ISO-8859-16' => self::ISO8859_16,
|
||||
'SHIFT-JIS' => self::SJIS,
|
||||
'WINDOWS-1250' => self::CP1250,
|
||||
'WINDOWS-1251' => self::CP1251,
|
||||
'WINDOWS-1252' => self::CP1252,
|
||||
'WINDOWS-1256' => self::CP1256,
|
||||
'UTF-16BE' => self::UNICODE_BIG_UNMARKED,
|
||||
'UTF-8' => self::UTF8,
|
||||
'ASCII' => self::ASCII,
|
||||
'GBK' => self::GB18030,
|
||||
'EUC-KR' => self::EUC_KR,
|
||||
);
|
||||
/**
|
||||
* Additional possible values for character sets.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $additionalValues = array(
|
||||
self::CP437 => 2,
|
||||
self::ASCII => 170,
|
||||
);
|
||||
/**
|
||||
* Gets character set ECI by value.
|
||||
*
|
||||
* @param string $name
|
||||
* @return CharacterSetEci|null
|
||||
*/
|
||||
public static function getCharacterSetECIByValue($value)
|
||||
{
|
||||
if ($value < 0 || $value >= 900) {
|
||||
throw new Exception\InvalidArgumentException('Value must be between 0 and 900');
|
||||
}
|
||||
if (false !== ($key = array_search($value, self::$additionalValues))) {
|
||||
$value = $key;
|
||||
}
|
||||
array_search($value, self::$nameToEci);
|
||||
try
|
||||
{
|
||||
self::setName($value);
|
||||
return new self($value);
|
||||
} catch (Exception\UnexpectedValueException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static function setName($value)
|
||||
{
|
||||
foreach (self::$nameToEci as $name => $key) {
|
||||
if($key == $value)
|
||||
{
|
||||
self::$name = $name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(self::$name == null)
|
||||
{
|
||||
foreach (self::$additionalValues as $name => $key) {
|
||||
if($key == $value)
|
||||
{
|
||||
self::$name = $name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets character set ECI name.
|
||||
*
|
||||
* @return character set ECI name|null
|
||||
*/
|
||||
public static function name()
|
||||
{
|
||||
return self::$name;
|
||||
}
|
||||
/**
|
||||
* Gets character set ECI by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return CharacterSetEci|null
|
||||
*/
|
||||
public static function getCharacterSetECIByName($name)
|
||||
{
|
||||
$name = strtoupper($name);
|
||||
if (isset(self::$nameToEci[$name])) {
|
||||
return new self(self::$nameToEci[$name]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
109
vendor/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php
vendored
Normal file
109
vendor/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Encapsulates the result of decoding a matrix of bits. This typically
|
||||
* applies to 2D barcode formats. For now it contains the raw bytes obtained,
|
||||
* as well as a String interpretation of those bytes, if applicable.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class DecoderResult {
|
||||
|
||||
private $rawBytes;
|
||||
private $text;
|
||||
private $byteSegments;
|
||||
private $ecLevel;
|
||||
private $errorsCorrected;
|
||||
private $erasures;
|
||||
private $other;
|
||||
private $structuredAppendParity;
|
||||
private $structuredAppendSequenceNumber;
|
||||
|
||||
|
||||
|
||||
public function __construct($rawBytes,
|
||||
$text,
|
||||
$byteSegments,
|
||||
$ecLevel,
|
||||
$saSequence = -1,
|
||||
$saParity = -1) {
|
||||
$this->rawBytes = $rawBytes;
|
||||
$this->text = $text;
|
||||
$this->byteSegments = $byteSegments;
|
||||
$this->ecLevel = $ecLevel;
|
||||
$this->structuredAppendParity = $saParity;
|
||||
$this->structuredAppendSequenceNumber = $saSequence;
|
||||
}
|
||||
|
||||
public function getRawBytes() {
|
||||
return $this->rawBytes;
|
||||
}
|
||||
|
||||
public function getText() {
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
public function getByteSegments() {
|
||||
return $this->byteSegments;
|
||||
}
|
||||
|
||||
public function getECLevel() {
|
||||
return $this->ecLevel;
|
||||
}
|
||||
|
||||
public function getErrorsCorrected() {
|
||||
return $this->errorsCorrected;
|
||||
}
|
||||
|
||||
public function setErrorsCorrected($errorsCorrected) {
|
||||
$this->errorsCorrected = $errorsCorrected;
|
||||
}
|
||||
|
||||
public function getErasures() {
|
||||
return $this->erasures;
|
||||
}
|
||||
|
||||
public function setErasures($erasures) {
|
||||
$this->erasures = $erasures;
|
||||
}
|
||||
|
||||
public function getOther() {
|
||||
return $this->other;
|
||||
}
|
||||
|
||||
public function setOther($other) {
|
||||
$this->other = $other;
|
||||
}
|
||||
|
||||
public function hasStructuredAppend() {
|
||||
return $this->structuredAppendParity >= 0 && $this->structuredAppendSequenceNumber >= 0;
|
||||
}
|
||||
|
||||
public function getStructuredAppendParity() {
|
||||
return $this->structuredAppendParity;
|
||||
}
|
||||
|
||||
public function getStructuredAppendSequenceNumber() {
|
||||
return $this->structuredAppendSequenceNumber;
|
||||
}
|
||||
|
||||
}
|
||||
89
vendor/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php
vendored
Normal file
89
vendor/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
use Zxing\NotFoundException;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class DefaultGridSampler extends GridSampler {
|
||||
|
||||
//@Override
|
||||
public function sampleGrid($image,
|
||||
$dimensionX,
|
||||
$dimensionY,
|
||||
$p1ToX, $p1ToY,
|
||||
$p2ToX, $p2ToY,
|
||||
$p3ToX, $p3ToY,
|
||||
$p4ToX, $p4ToY,
|
||||
$p1FromX, $p1FromY,
|
||||
$p2FromX, $p2FromY,
|
||||
$p3FromX, $p3FromY,
|
||||
$p4FromX, $p4FromY) {
|
||||
|
||||
$transform = PerspectiveTransform::quadrilateralToQuadrilateral(
|
||||
$p1ToX, $p1ToY, $p2ToX, $p2ToY, $p3ToX, $p3ToY, $p4ToX, $p4ToY,
|
||||
$p1FromX, $p1FromY, $p2FromX, $p2FromY, $p3FromX, $p3FromY, $p4FromX, $p4FromY);
|
||||
|
||||
return $this->sampleGrid_($image, $dimensionX, $dimensionY, $transform);
|
||||
}
|
||||
|
||||
//@Override
|
||||
public function sampleGrid_($image,
|
||||
$dimensionX,
|
||||
$dimensionY,
|
||||
$transform) {
|
||||
if ($dimensionX <= 0 || $dimensionY <= 0) {
|
||||
throw NotFoundException::getNotFoundInstance();
|
||||
}
|
||||
$bits = new BitMatrix($dimensionX, $dimensionY);
|
||||
$points = fill_array(0,2 * $dimensionX,0.0);
|
||||
for ($y = 0; $y < $dimensionY; $y++) {
|
||||
$max = count($points);
|
||||
$iValue = (float) $y + 0.5;
|
||||
for ($x = 0; $x < $max; $x += 2) {
|
||||
$points[$x] = (float) ($x / 2) + 0.5;
|
||||
$points[$x + 1] = $iValue;
|
||||
}
|
||||
$transform->transformPoints($points);
|
||||
// Quick check to see if points transformed to something inside the image;
|
||||
// sufficient to check the endpoints
|
||||
$this->checkAndNudgePoints($image, $points);
|
||||
try {
|
||||
for ($x = 0; $x < $max; $x += 2) {
|
||||
if ($image->get((int) $points[$x], (int) $points[$x + 1])) {
|
||||
// Black(-ish) pixel
|
||||
$bits->set($x / 2, $y);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $aioobe) {//ArrayIndexOutOfBoundsException
|
||||
// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
|
||||
// transform gets "twisted" such that it maps a straight line of points to a set of points
|
||||
// whose endpoints are in bounds, but others are not. There is probably some mathematical
|
||||
// way to detect this about the transformation that I don't know yet.
|
||||
// This results in an ugly runtime exception despite our clever checks above -- can't have
|
||||
// that. We could check each point's coordinates but that feels duplicative. We settle for
|
||||
// catching and wrapping ArrayIndexOutOfBoundsException.
|
||||
throw NotFoundException::getNotFoundInstance();
|
||||
}
|
||||
}
|
||||
return $bits;
|
||||
}
|
||||
|
||||
}
|
||||
47
vendor/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php
vendored
Normal file
47
vendor/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
use Zxing\ResultPoint;
|
||||
|
||||
/**
|
||||
* <p>Encapsulates the result of detecting a barcode in an image. This includes the raw
|
||||
* matrix of black/white pixels corresponding to the barcode, and possibly points of interest
|
||||
* in the image, like the location of finder patterns or corners of the barcode in the image.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
class DetectorResult {
|
||||
|
||||
private $bits;
|
||||
private $points;
|
||||
|
||||
public function __construct($bits, $points) {
|
||||
$this->bits = $bits;
|
||||
$this->points = $points;
|
||||
}
|
||||
|
||||
public final function getBits() {
|
||||
return $this->bits;
|
||||
}
|
||||
|
||||
public final function getPoints() {
|
||||
return $this->points;
|
||||
}
|
||||
|
||||
}
|
||||
206
vendor/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php
vendored
Normal file
206
vendor/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
use Zxing\Binarizer;
|
||||
use Zxing\LuminanceSource;
|
||||
use Zxing\NotFoundException;
|
||||
|
||||
/**
|
||||
* This Binarizer implementation uses the old ZXing global histogram approach. It is suitable
|
||||
* for low-end mobile devices which don't have enough CPU or memory to use a local thresholding
|
||||
* algorithm. However, because it picks a global black point, it cannot handle difficult shadows
|
||||
* and gradients.
|
||||
*
|
||||
* Faster mobile devices and all desktop applications should probably use HybridBinarizer instead.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
class GlobalHistogramBinarizer extends Binarizer {
|
||||
|
||||
private static $LUMINANCE_BITS = 5;
|
||||
private static $LUMINANCE_SHIFT=3;
|
||||
private static $LUMINANCE_BUCKETS = 32;
|
||||
|
||||
private static $EMPTY = array();
|
||||
|
||||
private $luminances=array();
|
||||
private $buckets = array();
|
||||
private $source = array();
|
||||
|
||||
public function __construct($source) {
|
||||
|
||||
self::$LUMINANCE_SHIFT = 8 - self::$LUMINANCE_BITS;
|
||||
self::$LUMINANCE_BUCKETS = 1 << self::$LUMINANCE_BITS;
|
||||
|
||||
parent::__construct($source);
|
||||
|
||||
$this->luminances = self::$EMPTY;
|
||||
$this->buckets = fill_array(0, self::$LUMINANCE_BUCKETS,0);
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
// Applies simple sharpening to the row data to improve performance of the 1D Readers.
|
||||
//@Override
|
||||
public function getBlackRow($y, $row=null) {
|
||||
$this->source = $this->getLuminanceSource();
|
||||
$width = $this->source->getWidth();
|
||||
if ($row == null || $row->getSize() < $width) {
|
||||
$row = new BitArray($width);
|
||||
} else {
|
||||
$row->clear();
|
||||
}
|
||||
|
||||
$this->initArrays($width);
|
||||
$localLuminances = $this->source->getRow($y, $this->luminances);
|
||||
$localBuckets = $this->buckets;
|
||||
for ($x = 0; $x < $width; $x++) {
|
||||
$pixel = $localLuminances[$x] & 0xff;
|
||||
$localBuckets[$pixel >> self::$LUMINANCE_SHIFT]++;
|
||||
}
|
||||
$blackPoint = $this->estimateBlackPoint($localBuckets);
|
||||
|
||||
$left = $localLuminances[0] & 0xff;
|
||||
$center = $localLuminances[1] & 0xff;
|
||||
for ($x = 1; $x < $width - 1; $x++) {
|
||||
$right = $localLuminances[$x + 1] & 0xff;
|
||||
// A simple -1 4 -1 box filter with a weight of 2.
|
||||
$luminance = (($center * 4) - $left - $right) / 2;
|
||||
if ($luminance < $blackPoint) {
|
||||
$row->set($x);
|
||||
}
|
||||
$left = $center;
|
||||
$center = $right;
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
|
||||
// Does not sharpen the data, as this call is intended to only be used by 2D Readers.
|
||||
//@Override
|
||||
public function getBlackMatrix(){
|
||||
$source = $this->getLuminanceSource();
|
||||
$width = $source->getWidth();
|
||||
$height = $source->getHeight();
|
||||
$matrix = new BitMatrix($width, $height);
|
||||
|
||||
// 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.
|
||||
$this->initArrays($width);
|
||||
$localBuckets = $this->buckets;
|
||||
for ($y = 1; $y < 5; $y++) {
|
||||
$row = intval($height * $y / 5);
|
||||
$localLuminances = $source->getRow($row, $this->luminances);
|
||||
$right = intval(($width * 4) / 5);
|
||||
for ($x = intval($width / 5); $x < $right; $x++) {
|
||||
$pixel = intval32bits($localLuminances[intval($x)] & 0xff);
|
||||
$localBuckets[intval32bits($pixel >> self::$LUMINANCE_SHIFT)]++;
|
||||
}
|
||||
}
|
||||
$blackPoint = $this->estimateBlackPoint($localBuckets);
|
||||
|
||||
// We delay reading the entire image luminance until the black point estimation succeeds.
|
||||
// Although we end up reading four rows twice, it is consistent with our motto of
|
||||
// "fail quickly" which is necessary for continuous scanning.
|
||||
$localLuminances = $source->getMatrix();
|
||||
for ($y = 0; $y < $height; $y++) {
|
||||
$offset = $y * $width;
|
||||
for ($x = 0; $x< $width; $x++) {
|
||||
$pixel = intval($localLuminances[$offset + $x] & 0xff);
|
||||
if ($pixel < $blackPoint) {
|
||||
$matrix->set($x, $y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
//@Override
|
||||
public function createBinarizer($source) {
|
||||
return new GlobalHistogramBinarizer($source);
|
||||
}
|
||||
|
||||
private function initArrays($luminanceSize) {
|
||||
if (count($this->luminances) < $luminanceSize) {
|
||||
$this->luminances = array();
|
||||
}
|
||||
for ($x = 0; $x < self::$LUMINANCE_BUCKETS; $x++) {
|
||||
$this->buckets[$x] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static function estimateBlackPoint($buckets){
|
||||
// Find the tallest peak in the histogram.
|
||||
$numBuckets = count($buckets);
|
||||
$maxBucketCount = 0;
|
||||
$firstPeak = 0;
|
||||
$firstPeakSize = 0;
|
||||
for ($x = 0; $x < $numBuckets; $x++) {
|
||||
if ($buckets[$x] > $firstPeakSize) {
|
||||
$firstPeak = $x;
|
||||
$firstPeakSize = $buckets[$x];
|
||||
}
|
||||
if ($buckets[$x] > $maxBucketCount) {
|
||||
$maxBucketCount = $buckets[$x];
|
||||
}
|
||||
}
|
||||
|
||||
// Find the second-tallest peak which is somewhat far from the tallest peak.
|
||||
$secondPeak = 0;
|
||||
$secondPeakScore = 0;
|
||||
for ($x = 0; $x < $numBuckets; $x++) {
|
||||
$distanceToBiggest = $x - $firstPeak;
|
||||
// Encourage more distant second peaks by multiplying by square of distance.
|
||||
$score = $buckets[$x] * $distanceToBiggest * $distanceToBiggest;
|
||||
if ($score > $secondPeakScore) {
|
||||
$secondPeak = $x;
|
||||
$secondPeakScore = $score;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure firstPeak corresponds to the black peak.
|
||||
if ($firstPeak > $secondPeak) {
|
||||
$temp = $firstPeak;
|
||||
$firstPeak = $secondPeak;
|
||||
$secondPeak = $temp;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
throw NotFoundException::getNotFoundInstance();
|
||||
}
|
||||
|
||||
// Find a valley between them that is low and closer to the white peak.
|
||||
$bestValley = $secondPeak - 1;
|
||||
$bestValleyScore = -1;
|
||||
for ($x = $secondPeak - 1; $x > $firstPeak; $x--) {
|
||||
$fromFirst = $x - $firstPeak;
|
||||
$score = $fromFirst * $fromFirst * ($secondPeak - $x) * ($maxBucketCount - $buckets[$x]);
|
||||
if ($score > $bestValleyScore) {
|
||||
$bestValley = $x;
|
||||
$bestValleyScore = $score;
|
||||
}
|
||||
}
|
||||
|
||||
return intval32bits($bestValley << self::$LUMINANCE_SHIFT);
|
||||
}
|
||||
|
||||
}
|
||||
177
vendor/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php
vendored
Normal file
177
vendor/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
use Zxing\NotFoundException;
|
||||
|
||||
/**
|
||||
* Implementations of this class can, given locations of finder patterns for a QR code in an
|
||||
* image, sample the right points in the image to reconstruct the QR code, accounting for
|
||||
* perspective distortion. It is abstracted since it is relatively expensive and should be allowed
|
||||
* to take advantage of platform-specific optimized implementations, like Sun's Java Advanced
|
||||
* Imaging library, but which may not be available in other environments such as J2ME, and vice
|
||||
* versa.
|
||||
*
|
||||
* The implementation used can be controlled by calling {@link #setGridSampler(GridSampler)}
|
||||
* with an instance of a class which implements this interface.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
abstract class GridSampler {
|
||||
|
||||
private static $gridSampler;
|
||||
|
||||
/**
|
||||
* Sets the implementation of GridSampler used by the library. One global
|
||||
* instance is stored, which may sound problematic. But, the implementation provided
|
||||
* ought to be appropriate for the entire platform, and all uses of this library
|
||||
* in the whole lifetime of the JVM. For instance, an Android activity can swap in
|
||||
* an implementation that takes advantage of native platform libraries.
|
||||
*
|
||||
* @param newGridSampler The platform-specific object to install.
|
||||
*/
|
||||
public static function setGridSampler($newGridSampler) {
|
||||
self::$gridSampler = $newGridSampler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current implementation of GridSampler
|
||||
*/
|
||||
public static function getInstance() {
|
||||
if(!self::$gridSampler){
|
||||
self::$gridSampler = new DefaultGridSampler();
|
||||
}
|
||||
return self::$gridSampler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Samples an image for a rectangular matrix of bits of the given dimension. The sampling
|
||||
* transformation is determined by the coordinates of 4 points, in the original and transformed
|
||||
* image space.
|
||||
*
|
||||
* @param image image to sample
|
||||
* @param dimensionX width of {@link BitMatrix} to sample from image
|
||||
* @param dimensionY height of {@link BitMatrix} to sample from image
|
||||
* @param p1ToX point 1 preimage X
|
||||
* @param p1ToY point 1 preimage Y
|
||||
* @param p2ToX point 2 preimage X
|
||||
* @param p2ToY point 2 preimage Y
|
||||
* @param p3ToX point 3 preimage X
|
||||
* @param p3ToY point 3 preimage Y
|
||||
* @param p4ToX point 4 preimage X
|
||||
* @param p4ToY point 4 preimage Y
|
||||
* @param p1FromX point 1 image X
|
||||
* @param p1FromY point 1 image Y
|
||||
* @param p2FromX point 2 image X
|
||||
* @param p2FromY point 2 image Y
|
||||
* @param p3FromX point 3 image X
|
||||
* @param p3FromY point 3 image Y
|
||||
* @param p4FromX point 4 image X
|
||||
* @param p4FromY point 4 image Y
|
||||
* @return {@link BitMatrix} representing a grid of points sampled from the image within a region
|
||||
* defined by the "from" parameters
|
||||
* @throws NotFoundException if image can't be sampled, for example, if the transformation defined
|
||||
* by the given points is invalid or results in sampling outside the image boundaries
|
||||
*/
|
||||
public abstract function sampleGrid($image,
|
||||
$dimensionX,
|
||||
$dimensionY,
|
||||
$p1ToX, $p1ToY,
|
||||
$p2ToX, $p2ToY,
|
||||
$p3ToX, $p3ToY,
|
||||
$p4ToX, $p4ToY,
|
||||
$p1FromX, $p1FromY,
|
||||
$p2FromX, $p2FromY,
|
||||
$p3FromX, $p3FromY,
|
||||
$p4FromX, $p4FromY);
|
||||
|
||||
public abstract function sampleGrid_($image,
|
||||
$dimensionX,
|
||||
$dimensionY,
|
||||
$transform);
|
||||
|
||||
/**
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>This method will actually "nudge" the endpoints back onto the image if they are found to be
|
||||
* barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder
|
||||
* patterns in an image where the QR Code runs all the way to the image border.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @param image image into which the points should map
|
||||
* @param points actual points in x1,y1,...,xn,yn form
|
||||
* @throws NotFoundException if an endpoint is lies outside the image boundaries
|
||||
*/
|
||||
protected static function checkAndNudgePoints($image,
|
||||
$points) {
|
||||
$width = $image->getWidth();
|
||||
$height = $image->getHeight();
|
||||
// Check and nudge points from start until we see some that are OK:
|
||||
$nudged = true;
|
||||
for ($offset = 0; $offset < count($points) && $nudged; $offset += 2) {
|
||||
$x = (int) $points[$offset];
|
||||
$y = (int) $points[$offset + 1];
|
||||
if ($x < -1 || $x > $width || $y < -1 || $y > $height) {
|
||||
throw NotFoundException::getNotFoundInstance();
|
||||
}
|
||||
$nudged = false;
|
||||
if ($x == -1) {
|
||||
$points[$offset] = 0.0;
|
||||
$nudged = true;
|
||||
} else if ($x == $width) {
|
||||
$points[$offset] = $width - 1;
|
||||
$nudged = true;
|
||||
}
|
||||
if ($y == -1) {
|
||||
$points[$offset + 1] = 0.0;
|
||||
$nudged = true;
|
||||
} else if ($y == $height) {
|
||||
$points[$offset + 1] = $height - 1;
|
||||
$nudged = true;
|
||||
}
|
||||
}
|
||||
// Check and nudge points from end:
|
||||
$nudged = true;
|
||||
for ($offset = count($points) - 2; $offset >= 0 && $nudged; $offset -= 2) {
|
||||
$x = (int) $points[$offset];
|
||||
$y = (int) $points[$offset + 1];
|
||||
if ($x < -1 || $x > $width || $y < -1 || $y > $height) {
|
||||
throw NotFoundException::getNotFoundInstance();
|
||||
}
|
||||
$nudged = false;
|
||||
if ($x == -1) {
|
||||
$points[$offset] = 0.0;
|
||||
$nudged = true;
|
||||
} else if ($x == $width) {
|
||||
$points[$offset] = $width - 1;
|
||||
$nudged = true;
|
||||
}
|
||||
if ($y == -1) {
|
||||
$points[$offset + 1] = 0.0;
|
||||
$nudged = true;
|
||||
} else if ($y == $height) {
|
||||
$points[$offset + 1] = $height - 1;
|
||||
$nudged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
259
vendor/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php
vendored
Normal file
259
vendor/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
use Zxing\Binarizer;
|
||||
use Zxing\LuminanceSource;
|
||||
use Zxing\NotFoundException;
|
||||
|
||||
/**
|
||||
* This class implements a local thresholding algorithm, which while slower than the
|
||||
* GlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for
|
||||
* high frequency images of barcodes with black data on white backgrounds. For this application,
|
||||
* it does a much better job than a global blackpoint with severe shadows and gradients.
|
||||
* However it tends to produce artifacts on lower frequency images and is therefore not
|
||||
* a good general purpose binarizer for uses outside ZXing.
|
||||
*
|
||||
* This class extends GlobalHistogramBinarizer, using the older histogram approach for 1D readers,
|
||||
* and the newer local approach for 2D readers. 1D decoding using a per-row histogram is already
|
||||
* inherently local, and only fails for horizontal gradients. We can revisit that problem later,
|
||||
* but for now it was not a win to use local blocks for 1D.
|
||||
*
|
||||
* This Binarizer is the default for the unit tests and the recommended class for library users.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
final class HybridBinarizer extends GlobalHistogramBinarizer {
|
||||
|
||||
// This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
|
||||
// So this is the smallest dimension in each axis we can accept.
|
||||
private static $BLOCK_SIZE_POWER = 3;
|
||||
private static $BLOCK_SIZE = 8; // ...0100...00
|
||||
private static $BLOCK_SIZE_MASK = 7; // ...0011...11
|
||||
private static $MINIMUM_DIMENSION = 40;
|
||||
private static $MIN_DYNAMIC_RANGE=24;
|
||||
|
||||
private $matrix;
|
||||
|
||||
public function __construct($source) {
|
||||
|
||||
parent::__construct($source);
|
||||
self::$BLOCK_SIZE_POWER = 3;
|
||||
self::$BLOCK_SIZE = 1 << self::$BLOCK_SIZE_POWER; // ...0100...00
|
||||
self::$BLOCK_SIZE_MASK = self::$BLOCK_SIZE - 1; // ...0011...11
|
||||
self::$MINIMUM_DIMENSION = self::$BLOCK_SIZE * 5;
|
||||
self::$MIN_DYNAMIC_RANGE = 24;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the final BitMatrix once for all requests. This could be called once from the
|
||||
* constructor instead, but there are some advantages to doing it lazily, such as making
|
||||
* profiling easier, and not doing heavy lifting when callers don't expect it.
|
||||
*/
|
||||
//@Override
|
||||
public function getBlackMatrix(){
|
||||
if ($this->matrix != null) {
|
||||
return $this->matrix;
|
||||
}
|
||||
$source = $this->getLuminanceSource();
|
||||
$width = $source->getWidth();
|
||||
$height = $source->getHeight();
|
||||
if ($width >= self::$MINIMUM_DIMENSION && $height >= self::$MINIMUM_DIMENSION) {
|
||||
$luminances = $source->getMatrix();
|
||||
$subWidth = $width >> self::$BLOCK_SIZE_POWER;
|
||||
if (($width & self::$BLOCK_SIZE_MASK) != 0) {
|
||||
$subWidth++;
|
||||
}
|
||||
$subHeight = $height >> self::$BLOCK_SIZE_POWER;
|
||||
if (($height & self::$BLOCK_SIZE_MASK) != 0) {
|
||||
$subHeight++;
|
||||
}
|
||||
$blackPoints = $this->calculateBlackPoints($luminances, $subWidth, $subHeight, $width, $height);
|
||||
|
||||
$newMatrix = new BitMatrix($width, $height);
|
||||
$this->calculateThresholdForBlock($luminances, $subWidth, $subHeight, $width, $height, $blackPoints, $newMatrix);
|
||||
$this->matrix = $newMatrix;
|
||||
} else {
|
||||
// If the image is too small, fall back to the global histogram approach.
|
||||
$this->matrix = parent::getBlackMatrix();
|
||||
}
|
||||
return $this->matrix;
|
||||
}
|
||||
|
||||
//@Override
|
||||
public function createBinarizer($source) {
|
||||
return new HybridBinarizer($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* For each block in the image, calculate the average black point using a 5x5 grid
|
||||
* of the blocks around it. Also handles the corner cases (fractional blocks are computed based
|
||||
* on the last pixels in the row/column which are also used in the previous block).
|
||||
*/
|
||||
private static function calculateThresholdForBlock($luminances,
|
||||
$subWidth,
|
||||
$subHeight,
|
||||
$width,
|
||||
$height,
|
||||
$blackPoints,
|
||||
$matrix) {
|
||||
for ($y = 0; $y < $subHeight; $y++) {
|
||||
$yoffset = intval32bits($y << self::$BLOCK_SIZE_POWER);
|
||||
$maxYOffset = $height - self::$BLOCK_SIZE;
|
||||
if ($yoffset > $maxYOffset) {
|
||||
$yoffset = $maxYOffset;
|
||||
}
|
||||
for ($x = 0; $x < $subWidth; $x++) {
|
||||
$xoffset = intval32bits($x << self::$BLOCK_SIZE_POWER);
|
||||
$maxXOffset = $width - self::$BLOCK_SIZE;
|
||||
if ($xoffset > $maxXOffset) {
|
||||
$xoffset = $maxXOffset;
|
||||
}
|
||||
$left = self::cap($x, 2, $subWidth - 3);
|
||||
$top = self::cap($y, 2, $subHeight - 3);
|
||||
$sum = 0;
|
||||
for ($z = -2; $z <= 2; $z++) {
|
||||
$blackRow = $blackPoints[$top + $z];
|
||||
$sum += $blackRow[$left - 2] + $blackRow[$left - 1] + $blackRow[$left] + $blackRow[$left + 1] + $blackRow[$left + 2];
|
||||
}
|
||||
$average = intval($sum / 25);
|
||||
|
||||
self::thresholdBlock($luminances, $xoffset, $yoffset, $average, $width, $matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function cap($value, $min, $max) {
|
||||
if($value<$min){
|
||||
return $min;
|
||||
}elseif($value>$max){
|
||||
return $max;
|
||||
}else{
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a single threshold to a block of pixels.
|
||||
*/
|
||||
private static function thresholdBlock($luminances,
|
||||
$xoffset,
|
||||
$yoffset,
|
||||
$threshold,
|
||||
$stride,
|
||||
$matrix) {
|
||||
|
||||
for ($y = 0, $offset = $yoffset * $stride + $xoffset; $y < self::$BLOCK_SIZE; $y++, $offset += $stride) {
|
||||
for ($x = 0; $x < self::$BLOCK_SIZE; $x++) {
|
||||
// Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
|
||||
if (($luminances[$offset + $x] & 0xFF) <= $threshold) {
|
||||
$matrix->set($xoffset + $x, $yoffset + $y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a single black point for each block of pixels and saves it away.
|
||||
* See the following thread for a discussion of this algorithm:
|
||||
* http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
|
||||
*/
|
||||
private static function calculateBlackPoints($luminances,
|
||||
$subWidth,
|
||||
$subHeight,
|
||||
$width,
|
||||
$height) {
|
||||
$blackPoints = fill_array(0,$subHeight,0);
|
||||
foreach($blackPoints as $key=>$point){
|
||||
$blackPoints[$key] = fill_array(0,$subWidth,0);
|
||||
}
|
||||
for ($y = 0; $y < $subHeight; $y++) {
|
||||
$yoffset = intval32bits($y << self::$BLOCK_SIZE_POWER);
|
||||
$maxYOffset = $height - self::$BLOCK_SIZE;
|
||||
if ($yoffset > $maxYOffset) {
|
||||
$yoffset = $maxYOffset;
|
||||
}
|
||||
for ($x = 0; $x < $subWidth; $x++) {
|
||||
$xoffset = intval32bits($x << self::$BLOCK_SIZE_POWER);
|
||||
$maxXOffset = $width - self::$BLOCK_SIZE;
|
||||
if ($xoffset > $maxXOffset) {
|
||||
$xoffset = $maxXOffset;
|
||||
}
|
||||
$sum = 0;
|
||||
$min = 0xFF;
|
||||
$max = 0;
|
||||
for ($yy = 0, $offset = $yoffset * $width + $xoffset; $yy < self::$BLOCK_SIZE; $yy++, $offset += $width) {
|
||||
for ($xx = 0; $xx < self::$BLOCK_SIZE; $xx++) {
|
||||
$pixel = intval32bits(intval($luminances[intval($offset +$xx)]) & 0xFF);
|
||||
$sum += $pixel;
|
||||
// still looking for good contrast
|
||||
if ($pixel < $min) {
|
||||
$min = $pixel;
|
||||
}
|
||||
if ($pixel > $max) {
|
||||
$max = $pixel;
|
||||
}
|
||||
}
|
||||
// short-circuit min/max tests once dynamic range is met
|
||||
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 += intval32bits($luminances[$offset +$xx] & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The default estimate is the average of the values in the block.
|
||||
$average = intval32bits($sum >> (self::$BLOCK_SIZE_POWER * 2));
|
||||
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.
|
||||
//
|
||||
// The default assumption is that the block is light/background. Since no estimate for
|
||||
// the level of dark pixels exists locally, use half the min for the block.
|
||||
$average = intval($min / 2);
|
||||
|
||||
if ($y > 0 && $x > 0) {
|
||||
// Correct the "white background" assumption for blocks that have neighbors by comparing
|
||||
// the pixels in this block to the previously calculated black points. This is based on
|
||||
// the fact that dark barcode symbology is always surrounded by some amount of light
|
||||
// background for which reasonable black point estimates were made. The bp estimated at
|
||||
// the boundaries is used for the interior.
|
||||
|
||||
// The (min < bp) is arbitrary but works better than other heuristics that were tried.
|
||||
$averageNeighborBlackPoint =
|
||||
intval(($blackPoints[$y - 1][$x] + (2 * $blackPoints[$y][$x - 1]) + $blackPoints[$y - 1][$x - 1]) / 4);
|
||||
if ($min < $averageNeighborBlackPoint) {
|
||||
$average = $averageNeighborBlackPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
$blackPoints[$y][$x] = intval($average);
|
||||
}
|
||||
}
|
||||
return $blackPoints;
|
||||
}
|
||||
|
||||
}
|
||||
161
vendor/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php
vendored
Normal file
161
vendor/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common;
|
||||
|
||||
/**
|
||||
* <p>This class implements a perspective transform in two dimensions. Given four source and four
|
||||
* destination points, it will compute the transformation implied between them. The code is based
|
||||
* directly upon section 3.4.2 of George Wolberg's "Digital Image Warping"; see pages 54-56.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class PerspectiveTransform {
|
||||
|
||||
private $a11;
|
||||
private $a12;
|
||||
private $a13;
|
||||
private $a21;
|
||||
private $a22;
|
||||
private $a23;
|
||||
private $a31;
|
||||
private $a32;
|
||||
private $a33;
|
||||
|
||||
private function __construct($a11, $a21, $a31,
|
||||
$a12, $a22, $a32,
|
||||
$a13, $a23, $a33) {
|
||||
$this->a11 = $a11;
|
||||
$this->a12 = $a12;
|
||||
$this->a13 = $a13;
|
||||
$this->a21 = $a21;
|
||||
$this->a22 = $a22;
|
||||
$this->a23 = $a23;
|
||||
$this->a31 = $a31;
|
||||
$this->a32 = $a32;
|
||||
$this->a33 = $a33;
|
||||
}
|
||||
|
||||
public static function quadrilateralToQuadrilateral($x0, $y0,
|
||||
$x1, $y1,
|
||||
$x2, $y2,
|
||||
$x3, $y3,
|
||||
$x0p, $y0p,
|
||||
$x1p, $y1p,
|
||||
$x2p, $y2p,
|
||||
$x3p, $y3p) {
|
||||
|
||||
$qToS = self::quadrilateralToSquare($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3);
|
||||
$sToQ = self::squareToQuadrilateral($x0p, $y0p, $x1p, $y1p, $x2p, $y2p, $x3p, $y3p);
|
||||
return $sToQ->times($qToS);
|
||||
}
|
||||
|
||||
public function transformPoints(&$points,&$yValues=0) {
|
||||
if($yValues) {
|
||||
$this->transformPoints_($points,$yValues);
|
||||
return;
|
||||
}
|
||||
$max =count($points);
|
||||
$a11 = $this->a11;
|
||||
$a12 = $this->a12;
|
||||
$a13 = $this->a13;
|
||||
$a21 = $this->a21;
|
||||
$a22 = $this->a22;
|
||||
$a23 = $this->a23;
|
||||
$a31 = $this->a31;
|
||||
$a32 = $this->a32;
|
||||
$a33 = $this->a33;
|
||||
for ($i = 0; $i < $max; $i += 2) {
|
||||
$x = $points[$i];
|
||||
$y = $points[$i + 1];
|
||||
$denominator = $a13 * $x + $a23 * $y + $a33;
|
||||
$points[$i] = ($a11 * $x + $a21 * $y + $a31) / $denominator;
|
||||
$points[$i + 1] = ($a12 * $x + $a22 * $y +$a32) / $denominator;
|
||||
}
|
||||
}
|
||||
|
||||
public function transformPoints_(&$xValues, &$yValues) {
|
||||
$n = count($xValues);
|
||||
for ($i = 0; $i < $n; $i ++) {
|
||||
$x = $xValues[$i];
|
||||
$y = $yValues[$i];
|
||||
$denominator = $this->a13 * $x + $this->a23 * $y + $this->a33;
|
||||
$xValues[$i] = ($this->a11 * $x + $this->a21 * $y + $this->a31) / $denominator;
|
||||
$yValues[$i] = ($this->a12 * $x + $this->a22 *$y + $this->a32) / $denominator;
|
||||
}
|
||||
}
|
||||
|
||||
public static function squareToQuadrilateral($x0, $y0,
|
||||
$x1, $y1,
|
||||
$x2, $y2,
|
||||
$x3, $y3) {
|
||||
$dx3 = $x0 - $x1 + $x2 - $x3;
|
||||
$dy3 = $y0 - $y1 + $y2 - $y3;
|
||||
if ($dx3 == 0.0 && $dy3 == 0.0) {
|
||||
// Affine
|
||||
return new PerspectiveTransform($x1 - $x0, $x2 - $x1, $x0,
|
||||
$y1 - $y0, $y2 - $y1, $y0,
|
||||
0.0, 0.0, 1.0);
|
||||
} else {
|
||||
$dx1 = $x1 - $x2;
|
||||
$dx2 = $x3 - $x2;
|
||||
$dy1 = $y1 - $y2;
|
||||
$dy2 = $y3 - $y2;
|
||||
$denominator = $dx1 * $dy2 - $dx2 * $dy1;
|
||||
$a13 = ($dx3 * $dy2 - $dx2 * $dy3) / $denominator;
|
||||
$a23 = ($dx1 * $dy3 - $dx3 * $dy1) / $denominator;
|
||||
return new PerspectiveTransform($x1 - $x0 + $a13 * $x1, $x3 - $x0 + $a23 * $x3, $x0,
|
||||
$y1 - $y0 + $a13 * $y1, $y3 - $y0 + $a23 * $y3, $y0,
|
||||
$a13, $a23, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
public static function quadrilateralToSquare($x0, $y0,
|
||||
$x1, $y1,
|
||||
$x2, $y2,
|
||||
$x3, $y3) {
|
||||
// Here, the adjoint serves as the inverse:
|
||||
return self::squareToQuadrilateral($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3)->buildAdjoint();
|
||||
}
|
||||
|
||||
function buildAdjoint() {
|
||||
// Adjoint is the transpose of the cofactor matrix:
|
||||
return new PerspectiveTransform($this->a22 * $this->a33 - $this->a23 * $this->a32,
|
||||
$this->a23 * $this->a31 - $this->a21 * $this->a33,
|
||||
$this->a21 * $this->a32 - $this->a22 * $this->a31,
|
||||
$this->a13 * $this->a32 - $this->a12 * $this->a33,
|
||||
$this->a11 * $this->a33 - $this->a13 * $this->a31,
|
||||
$this->a12 * $this->a31 - $this->a11 * $this->a32,
|
||||
$this->a12 * $this->a23 - $this->a13 * $this->a22,
|
||||
$this->a13 * $this->a21 - $this->a11 * $this->a23,
|
||||
$this->a11 * $this->a22 - $this->a12 * $this->a21);
|
||||
}
|
||||
|
||||
function times($other) {
|
||||
return new PerspectiveTransform($this->a11 * $other->a11 + $this->a21 * $other->a12 + $this->a31 * $other->a13,
|
||||
$this->a11 * $other->a21 + $this->a21 * $other->a22 + $this->a31 * $other->a23,
|
||||
$this->a11 * $other->a31 + $this->a21 * $other->a32 + $this->a31 * $other->a33,
|
||||
$this->a12 * $other->a11 + $this->a22 * $other->a12 + $this->a32 * $other->a13,
|
||||
$this->a12 * $other->a21 + $this->a22 * $other->a22 + $this->a32 * $other->a23,
|
||||
$this->a12 * $other->a31 + $this->a22 * $other->a32 + $this->a32 * $other->a33,
|
||||
$this->a13 * $other->a11 + $this->a23 * $other->a12 + $this->a33 * $other->a13,
|
||||
$this->a13 * $other->a21 + $this->a23 * $other->a22 + $this->a33 * $other->a23,
|
||||
$this->a13 * $other->a31 + $this->a23 * $other->a32 + $this->a33 * $other->a33);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
93
vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php
vendored
Normal file
93
vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
function arraycopy($srcArray,$srcPos,$destArray, $destPos, $length){//System.arraycopy
|
||||
|
||||
$srcArrayToCopy = array_slice($srcArray,$srcPos,$length);
|
||||
array_splice($destArray,$destPos,$length,$srcArrayToCopy);
|
||||
return $destArray;
|
||||
}
|
||||
|
||||
|
||||
function overflow32($value) {//There is no need to overflow 64 bits to 32 bit
|
||||
return $value;
|
||||
}
|
||||
|
||||
function hashCode( $s )
|
||||
{
|
||||
$h = 0;
|
||||
$len = strlen($s);
|
||||
for($i = 0; $i < $len; $i++)
|
||||
{
|
||||
$h = overflow32(31 * $h + ord($s[$i]));
|
||||
}
|
||||
|
||||
return $h;
|
||||
}
|
||||
|
||||
|
||||
function numberOfTrailingZeros($i) {
|
||||
if ($i == 0) return 32;
|
||||
$num = 0;
|
||||
while (($i & 1) == 0) {
|
||||
$i >>= 1;
|
||||
$num++;
|
||||
}
|
||||
return $num;
|
||||
}
|
||||
function intval32bits($value)
|
||||
{
|
||||
$value = ($value & 0xFFFFFFFF);
|
||||
|
||||
if ($value & 0x80000000)
|
||||
$value = -((~$value & 0xFFFFFFFF) + 1);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
function uRShift($a, $b)
|
||||
{
|
||||
|
||||
if($b == 0) return $a;
|
||||
return ($a >> $b) & ~(1<<(8*PHP_INT_SIZE-1)>>($b-1));
|
||||
}
|
||||
/*
|
||||
function sdvig3($num,$count=1){//>>> 32 bit
|
||||
$s = decbin($num);
|
||||
|
||||
$sarray = str_split($s,1);
|
||||
$sarray = array_slice($sarray,-32);//32bit
|
||||
|
||||
for($i=0;$i<=1;$i++) {
|
||||
array_pop($sarray);
|
||||
array_unshift($sarray, '0');
|
||||
}
|
||||
return bindec(implode($sarray));
|
||||
}
|
||||
*/
|
||||
|
||||
function sdvig3($a,$b) {
|
||||
|
||||
if ($a >= 0) {
|
||||
return bindec(decbin($a>>$b)); //simply right shift for positive number
|
||||
}
|
||||
|
||||
$bin = decbin($a>>$b);
|
||||
|
||||
$bin = substr($bin, $b); // zero fill on the left side
|
||||
|
||||
$o = bindec($bin);
|
||||
return $o;
|
||||
}
|
||||
|
||||
function floatToIntBits($float_val)
|
||||
{
|
||||
$int = unpack('i', pack('f', $float_val));
|
||||
return $int[1];
|
||||
}
|
||||
|
||||
function fill_array($index,$count,$value){
|
||||
if($count<=0){
|
||||
return array(0);
|
||||
}else {
|
||||
return array_fill($index, $count, $value);
|
||||
}
|
||||
}
|
||||
46
vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php
vendored
Normal file
46
vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2012 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common\Detector;
|
||||
|
||||
final class MathUtils {
|
||||
|
||||
private function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends up being a bit faster than {@link Math#round(float)}. This merely rounds its
|
||||
* argument to the nearest int, where x.5 rounds up to x+1. Semantics of this shortcut
|
||||
* differ slightly from {@link Math#round(float)} in that half rounds down for negative
|
||||
* values. -2.5 rounds to -3, not -2. For purposes here it makes no difference.
|
||||
*
|
||||
* @param d real value to round
|
||||
* @return nearest {@code int}
|
||||
*/
|
||||
public static function round($d) {
|
||||
return (int) ($d + ($d < 0.0 ? -0.5 : 0.5));
|
||||
}
|
||||
|
||||
public static function distance($aX, $aY, $bX, $bY) {
|
||||
$xDiff = $aX - $bX;
|
||||
$yDiff = $aY - $bY;
|
||||
return (float) sqrt($xDiff * $xDiff + $yDiff * $yDiff);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
225
vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MonochromeRectangleDetector.php
vendored
Normal file
225
vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MonochromeRectangleDetector.php
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Ashot
|
||||
* Date: 3/24/15
|
||||
* Time: 21:23
|
||||
*/
|
||||
namespace Zxing\Common\Detector;
|
||||
|
||||
use \Zxing\NotFoundException;
|
||||
use \Zxing\ResultPoint;
|
||||
use \Zxing\BitMatrix;
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
|
||||
*/
|
||||
//require_once('./lib/NotFoundException.php');
|
||||
//require_once('./lib/ResultPoint.php');
|
||||
//require_once('./lib/common/BitMatrix.php');
|
||||
|
||||
|
||||
/**
|
||||
* <p>A somewhat generic detector that looks for a barcode-like rectangular region within an image.
|
||||
* It looks within a mostly white region of an image for a region of black and white, but mostly
|
||||
* black. It returns the four corners of the region, as best it can determine.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @port Ashot Khanamiryan
|
||||
*/
|
||||
class MonochromeRectangleDetector {
|
||||
private static $MAX_MODULES = 32;
|
||||
private $image;
|
||||
function __construct($image){
|
||||
$this->image = $image;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Detects a rectangular region of black and white -- mostly black -- with a region of mostly
|
||||
* white, in an image.</p>
|
||||
*
|
||||
* @return {@link ResultPoint}[] describing the corners of the rectangular region. The first and
|
||||
* last points are opposed on the diagonal, as are the second and third. The first point will be
|
||||
* the topmost point and the last, the bottommost. The second point will be leftmost and the
|
||||
* third, the rightmost
|
||||
* @throws NotFoundException if no Data Matrix Code can be found
|
||||
*/
|
||||
public function detect(){
|
||||
|
||||
$height = $this->image->getHeight();
|
||||
$width = $this->image->getWidth();
|
||||
$halfHeight = $height / 2;
|
||||
$halfWidth = $width / 2;
|
||||
|
||||
$deltaY = max(1, $height / (self::$MAX_MODULES * 8));
|
||||
$deltaX = max(1, $width / (self::$MAX_MODULES * 8));
|
||||
|
||||
|
||||
$top = 0;
|
||||
$bottom = $height;
|
||||
$left = 0;
|
||||
$right = $width;
|
||||
$pointA = $this->findCornerFromCenter($halfWidth, 0, $left, $right,
|
||||
$halfHeight, -$deltaY, $top, $bottom, $halfWidth / 2);
|
||||
$top = (int) $pointA->getY() - 1;
|
||||
$pointB = $this->findCornerFromCenter($halfWidth, -$deltaX, $left,$right,
|
||||
$halfHeight, 0, $top, $bottom, $halfHeight / 2);
|
||||
$left = (int) $pointB->getX() - 1;
|
||||
$pointC = $this->findCornerFromCenter($halfWidth, $deltaX, $left, $right,
|
||||
$halfHeight, 0, $top, $bottom, $halfHeight / 2);
|
||||
$right = (int) $pointC->getX() + 1;
|
||||
$pointD = $this->findCornerFromCenter($halfWidth, 0, $left, $right,
|
||||
$halfHeight, $deltaY, $top, $bottom, $halfWidth / 2);
|
||||
$bottom = (int) $pointD->getY() + 1;
|
||||
|
||||
// Go try to find po$A again with better information -- might have been off at first.
|
||||
$pointA = $this->findCornerFromCenter($halfWidth, 0, $left, $right,
|
||||
$halfHeight, -$deltaY, $top, $bottom, $halfWidth / 4);
|
||||
|
||||
return new ResultPoint( $pointA, $pointB, $pointC, $pointD );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to locate a corner of the barcode by scanning up, down, left or right from a center
|
||||
* point which should be within the barcode.
|
||||
*
|
||||
* @param centerX center's x component (horizontal)
|
||||
* @param deltaX same as deltaY but change in x per step instead
|
||||
* @param left minimum value of x
|
||||
* @param right maximum value of x
|
||||
* @param centerY center's y component (vertical)
|
||||
* @param deltaY change in y per step. If scanning up this is negative; down, positive;
|
||||
* left or right, 0
|
||||
* @param top minimum value of y to search through (meaningless when di == 0)
|
||||
* @param bottom maximum value of y
|
||||
* @param maxWhiteRun maximum run of white pixels that can still be considered to be within
|
||||
* the barcode
|
||||
* @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found
|
||||
* @throws NotFoundException if such a point cannot be found
|
||||
*/
|
||||
private function findCornerFromCenter($centerX,
|
||||
$deltaX,
|
||||
$left,
|
||||
$right,
|
||||
$centerY,
|
||||
$deltaY,
|
||||
$top,
|
||||
$bottom,
|
||||
$maxWhiteRun){
|
||||
$lastRange = null;
|
||||
for ($y = $centerY, $x = $centerX;
|
||||
$y < $bottom && $y >= $top && $x < $right && $x >= $left;
|
||||
$y += $deltaY, $x += $deltaX) {
|
||||
$range = 0;
|
||||
if ($deltaX == 0) {
|
||||
// horizontal slices, up and down
|
||||
$range = $this->blackWhiteRange($y, $maxWhiteRun, $left, $right, true);
|
||||
} else {
|
||||
// vertical slices, left and right
|
||||
$range = $this->blackWhiteRange($x, $maxWhiteRun, $top, $bottom, false);
|
||||
}
|
||||
if ($range == null) {
|
||||
if ($lastRange == null) {
|
||||
throw NotFoundException::getNotFoundInstance();
|
||||
}
|
||||
// lastRange was found
|
||||
if ($deltaX == 0) {
|
||||
$lastY = $y - $deltaY;
|
||||
if ($lastRange[0] < $centerX) {
|
||||
if ($lastRange[1] > $centerX) {
|
||||
// straddle, choose one or the other based on direction
|
||||
return new ResultPoint($deltaY > 0 ? $lastRange[0] : $lastRange[1], $lastY);
|
||||
}
|
||||
return new ResultPoint($lastRange[0], $lastY);
|
||||
} else {
|
||||
return new ResultPoint($lastRange[1], $lastY);
|
||||
}
|
||||
} else {
|
||||
$lastX = $x - $deltaX;
|
||||
if ($lastRange[0] < $centerY) {
|
||||
if ($lastRange[1] > $centerY) {
|
||||
return new ResultPoint($lastX, $deltaX < 0 ? $lastRange[0] : $lastRange[1]);
|
||||
}
|
||||
return new ResultPoint($lastX, $lastRange[0]);
|
||||
} else {
|
||||
return new ResultPoint($lastX, $lastRange[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$lastRange = $range;
|
||||
}
|
||||
throw NotFoundException::getNotFoundInstance();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Computes the start and end of a region of pixels, either horizontally or vertically, that could
|
||||
* be part of a Data Matrix barcode.
|
||||
*
|
||||
* @param fixedDimension if scanning horizontally, this is the row (the fixed vertical location)
|
||||
* where we are scanning. If scanning vertically it's the column, the fixed horizontal location
|
||||
* @param maxWhiteRun largest run of white pixels that can still be considered part of the
|
||||
* barcode region
|
||||
* @param minDim minimum pixel location, horizontally or vertically, to consider
|
||||
* @param maxDim maximum pixel location, horizontally or vertically, to consider
|
||||
* @param horizontal if true, we're scanning left-right, instead of up-down
|
||||
* @return int[] with start and end of found range, or null if no such range is found
|
||||
* (e.g. only white was found)
|
||||
*/
|
||||
|
||||
private function blackWhiteRange($fixedDimension, $maxWhiteRun, $minDim, $maxDim, $horizontal){
|
||||
$center = ($minDim + $maxDim) / 2;
|
||||
|
||||
// Scan left/up first
|
||||
$start = $center;
|
||||
while ($start >= $minDim) {
|
||||
if ($horizontal ? $this->image->get($start, $fixedDimension) : $this->image->get($fixedDimension, $start)) {
|
||||
$start--;
|
||||
} else {
|
||||
$whiteRunStart = $start;
|
||||
do {
|
||||
$start--;
|
||||
} while ($start >= $minDim && !($horizontal ? $this->image->get($start, $fixedDimension) :
|
||||
$this->image->get($fixedDimension, $start)));
|
||||
$whiteRunSize = $whiteRunStart - $start;
|
||||
if ($start < $minDim || $whiteRunSize > $maxWhiteRun) {
|
||||
$start = $whiteRunStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$start++;
|
||||
|
||||
// Then try right/down
|
||||
$end = $center;
|
||||
while ($end < $maxDim) {
|
||||
if ($horizontal ? $this->image->get($end, $fixedDimension) : $this->image->get($fixedDimension, $end)) {
|
||||
$end++;
|
||||
} else {
|
||||
$whiteRunStart = $end;
|
||||
do {
|
||||
$end++;
|
||||
} while ($end < $maxDim && !($horizontal ? $this->image->get($end, $fixedDimension) :
|
||||
$this->image->get($fixedDimension, $end)));
|
||||
$whiteRunSize = $end - $whiteRunStart;
|
||||
if ($end >= $maxDim || $whiteRunSize > $maxWhiteRun) {
|
||||
$end = $whiteRunStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$end--;
|
||||
|
||||
return $end > $start ? array($start, $end) : null;
|
||||
}
|
||||
}
|
||||
181
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php
vendored
Normal file
181
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common\Reedsolomon;
|
||||
|
||||
/**
|
||||
* <p>This class contains utility methods for performing mathematical operations over
|
||||
* the Galois Fields. Operations use a given primitive polynomial in calculations.</p>
|
||||
*
|
||||
* <p>Throughout this package, elements of the GF are represented as an {@code int}
|
||||
* for convenience and speed (but at the cost of memory).
|
||||
* </p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author David Olivier
|
||||
*/
|
||||
final class GenericGF {
|
||||
|
||||
public static $AZTEC_DATA_12;
|
||||
public static $AZTEC_DATA_10;
|
||||
public static $AZTEC_DATA_6;
|
||||
public static $AZTEC_PARAM;
|
||||
public static $QR_CODE_FIELD_256;
|
||||
public static $DATA_MATRIX_FIELD_256;
|
||||
public static $AZTEC_DATA_8;
|
||||
public static $MAXICODE_FIELD_64;
|
||||
|
||||
private $expTable;
|
||||
private $logTable;
|
||||
private $zero;
|
||||
private $one;
|
||||
private $size;
|
||||
private $primitive;
|
||||
private $generatorBase;
|
||||
|
||||
|
||||
public static function Init(){
|
||||
self::$AZTEC_DATA_12 = new GenericGF(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1
|
||||
self::$AZTEC_DATA_10 = new GenericGF(0x409, 1024, 1); // x^10 + x^3 + 1
|
||||
self::$AZTEC_DATA_6 = new GenericGF(0x43, 64, 1); // x^6 + x + 1
|
||||
self::$AZTEC_PARAM = new GenericGF(0x13, 16, 1); // x^4 + x + 1
|
||||
self::$QR_CODE_FIELD_256 = new GenericGF(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
|
||||
self::$DATA_MATRIX_FIELD_256 = new GenericGF(0x012D, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1
|
||||
self::$AZTEC_DATA_8 = self::$DATA_MATRIX_FIELD_256;
|
||||
self::$MAXICODE_FIELD_64 = self::$AZTEC_DATA_6;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a representation of GF(size) using the given primitive polynomial.
|
||||
*
|
||||
* @param primitive irreducible polynomial whose coefficients are represented by
|
||||
* the bits of an int, where the least-significant bit represents the constant
|
||||
* coefficient
|
||||
* @param size the size of the field
|
||||
* @param b the factor b in the generator polynomial can be 0- or 1-based
|
||||
* (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
|
||||
* In most cases it should be 1, but for QR code it is 0.
|
||||
*/
|
||||
public function __construct($primitive, $size, $b) {
|
||||
$this->primitive = $primitive;
|
||||
$this->size = $size;
|
||||
$this->generatorBase = $b;
|
||||
|
||||
$this->expTable = array();
|
||||
$this->logTable =array();
|
||||
$x = 1;
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
$this->expTable[$i] = $x;
|
||||
$x *= 2; // we're assuming the generator alpha is 2
|
||||
if ($x >= $size) {
|
||||
$x ^= $primitive;
|
||||
$x &= $size-1;
|
||||
}
|
||||
}
|
||||
for ($i = 0; $i < $size-1; $i++) {
|
||||
$this->logTable[$this->expTable[$i]] = $i;
|
||||
}
|
||||
// logTable[0] == 0 but this should never be used
|
||||
$this->zero = new GenericGFPoly($this, array(0));
|
||||
$this->one = new GenericGFPoly($this, array(1));
|
||||
}
|
||||
|
||||
function getZero() {
|
||||
return $this->zero;
|
||||
}
|
||||
|
||||
function getOne() {
|
||||
return $this->one;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the monomial representing coefficient * x^degree
|
||||
*/
|
||||
function buildMonomial($degree, $coefficient) {
|
||||
if ($degree < 0) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
if ($coefficient == 0) {
|
||||
return $this->zero;
|
||||
}
|
||||
$coefficients = fill_array(0,$degree+1,0);//new int[degree + 1];
|
||||
$coefficients[0] = $coefficient;
|
||||
return new GenericGFPoly($this, $coefficients);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements both addition and subtraction -- they are the same in GF(size).
|
||||
*
|
||||
* @return sum/difference of a and b
|
||||
*/
|
||||
static function addOrSubtract($a, $b) {
|
||||
return $a ^ $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 2 to the power of a in GF(size)
|
||||
*/
|
||||
function exp($a) {
|
||||
return $this->expTable[$a];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return base 2 log of a in GF(size)
|
||||
*/
|
||||
function log($a) {
|
||||
if ($a == 0) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
return $this->logTable[$a];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return multiplicative inverse of a
|
||||
*/
|
||||
function inverse($a) {
|
||||
if ($a == 0) {
|
||||
throw new Exception();
|
||||
}
|
||||
return $this->expTable[$this->size - $this->logTable[$a] - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return product of a and b in GF(size)
|
||||
*/
|
||||
function multiply($a, $b) {
|
||||
if ($a == 0 || $b == 0) {
|
||||
return 0;
|
||||
}
|
||||
return $this->expTable[($this->logTable[$a] + $this->logTable[$b]) % ($this->size - 1)];
|
||||
}
|
||||
|
||||
public function getSize() {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function getGeneratorBase() {
|
||||
return $this->generatorBase;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public function toString() {
|
||||
return "GF(0x" . dechex(intval($this->primitive)) . ',' . $this->size . ')';
|
||||
}
|
||||
|
||||
}
|
||||
GenericGF::Init();
|
||||
268
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php
vendored
Normal file
268
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common\Reedsolomon;
|
||||
|
||||
/**
|
||||
* <p>Represents a polynomial whose coefficients are elements of a GF.
|
||||
* Instances of this class are immutable.</p>
|
||||
*
|
||||
* <p>Much credit is due to William Rucklidge since portions of this code are an indirect
|
||||
* port of his C++ Reed-Solomon implementation.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class GenericGFPoly {
|
||||
|
||||
private $field;
|
||||
private $coefficients;
|
||||
|
||||
/**
|
||||
* @param field the {@link GenericGF} instance representing the field to use
|
||||
* to perform computations
|
||||
* @param coefficients array coefficients as ints representing elements of GF(size), arranged
|
||||
* from most significant (highest-power term) coefficient to least significant
|
||||
* @throws IllegalArgumentException if argument is null or empty,
|
||||
* or if leading coefficient is 0 and this is not a
|
||||
* constant polynomial (that is, it is not the monomial "0")
|
||||
*/
|
||||
function __construct($field, $coefficients) {
|
||||
if (count($coefficients) == 0) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
$this->field = $field;
|
||||
$coefficientsLength = count($coefficients);
|
||||
if ($coefficientsLength > 1 && $coefficients[0] == 0) {
|
||||
// Leading term must be non-zero for anything except the constant polynomial "0"
|
||||
$firstNonZero = 1;
|
||||
while ($firstNonZero < $coefficientsLength && $coefficients[$firstNonZero] == 0) {
|
||||
$firstNonZero++;
|
||||
}
|
||||
if ($firstNonZero == $coefficientsLength) {
|
||||
$this->coefficients = array(0);
|
||||
} else {
|
||||
$this->coefficients = fill_array(0,$coefficientsLength - $firstNonZero,0);
|
||||
$this->coefficients = arraycopy($coefficients,
|
||||
$firstNonZero,
|
||||
$this->coefficients,
|
||||
0,
|
||||
count($this->coefficients));
|
||||
}
|
||||
} else {
|
||||
$this->coefficients = $coefficients;
|
||||
}
|
||||
}
|
||||
|
||||
function getCoefficients() {
|
||||
return $this->coefficients;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return degree of this polynomial
|
||||
*/
|
||||
function getDegree() {
|
||||
return count($this->coefficients) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true iff this polynomial is the monomial "0"
|
||||
*/
|
||||
function isZero() {
|
||||
return $this->coefficients[0] == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return coefficient of x^degree term in this polynomial
|
||||
*/
|
||||
function getCoefficient($degree) {
|
||||
return $this->coefficients[count($this->coefficients) - 1 - $degree];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return evaluation of this polynomial at a given point
|
||||
*/
|
||||
function evaluateAt($a) {
|
||||
if ($a == 0) {
|
||||
// Just return the x^0 coefficient
|
||||
return $this->getCoefficient(0);
|
||||
}
|
||||
$size = count($this->coefficients);
|
||||
if ($a == 1) {
|
||||
// Just the sum of the coefficients
|
||||
$result = 0;
|
||||
foreach ($this->coefficients as $coefficient ) {
|
||||
$result = GenericGF::addOrSubtract($result, $coefficient);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
$result = $this->coefficients[0];
|
||||
for ($i = 1; $i < $size; $i++) {
|
||||
$result = GenericGF::addOrSubtract($this->field->multiply($a, $result), $this->coefficients[$i]);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function addOrSubtract($other) {
|
||||
if ($this->field !== $other->field) {
|
||||
throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field");
|
||||
}
|
||||
if ($this->isZero()) {
|
||||
return $other;
|
||||
}
|
||||
if ($other->isZero()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$smallerCoefficients = $this->coefficients;
|
||||
$largerCoefficients = $other->coefficients;
|
||||
if (count($smallerCoefficients) > count($largerCoefficients)) {
|
||||
$temp = $smallerCoefficients;
|
||||
$smallerCoefficients = $largerCoefficients;
|
||||
$largerCoefficients = $temp;
|
||||
}
|
||||
$sumDiff = fill_array(0,count($largerCoefficients),0);
|
||||
$lengthDiff = count($largerCoefficients) - count($smallerCoefficients);
|
||||
// Copy high-order terms only found in higher-degree polynomial's coefficients
|
||||
$sumDiff = arraycopy($largerCoefficients, 0, $sumDiff, 0, $lengthDiff);
|
||||
|
||||
for ($i = $lengthDiff; $i < count($largerCoefficients); $i++) {
|
||||
$sumDiff[$i] = GenericGF::addOrSubtract($smallerCoefficients[$i - $lengthDiff], $largerCoefficients[$i]);
|
||||
}
|
||||
|
||||
return new GenericGFPoly($this->field, $sumDiff);
|
||||
}
|
||||
|
||||
function multiply($other) {
|
||||
if(is_int($other)){
|
||||
return $this->multiply_($other);
|
||||
}
|
||||
if ($this->field !== $other->field) {
|
||||
throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field");
|
||||
}
|
||||
if ($this->isZero() || $other->isZero()) {
|
||||
return $this->field->getZero();
|
||||
}
|
||||
$aCoefficients = $this->coefficients;
|
||||
$aLength = count($aCoefficients);
|
||||
$bCoefficients = $other->coefficients;
|
||||
$bLength = count($bCoefficients);
|
||||
$product = fill_array(0,$aLength + $bLength - 1,0);
|
||||
for ($i = 0; $i < $aLength; $i++) {
|
||||
$aCoeff = $aCoefficients[$i];
|
||||
for ($j = 0; $j < $bLength; $j++) {
|
||||
$product[$i + $j] = GenericGF::addOrSubtract($product[$i + $j],
|
||||
$this->field->multiply($aCoeff, $bCoefficients[$j]));
|
||||
}
|
||||
}
|
||||
return new GenericGFPoly($this->field, $product);
|
||||
}
|
||||
|
||||
function multiply_($scalar) {
|
||||
if ($scalar == 0) {
|
||||
return $this->field->getZero();
|
||||
}
|
||||
if ($scalar == 1) {
|
||||
return $this;
|
||||
}
|
||||
$size = count($this->coefficients);
|
||||
$product = fill_array(0,$size,0);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
$product[$i] = $this->field->multiply($this->coefficients[$i], $scalar);
|
||||
}
|
||||
return new GenericGFPoly($this->field, $product);
|
||||
}
|
||||
|
||||
function multiplyByMonomial($degree, $coefficient) {
|
||||
if ($degree < 0) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
if ($coefficient == 0) {
|
||||
return $this->field->getZero();
|
||||
}
|
||||
$size = count($this->coefficients);
|
||||
$product = fill_array(0,$size + $degree,0);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
$product[$i] = $this->field->multiply($this->coefficients[$i], $coefficient);
|
||||
}
|
||||
return new GenericGFPoly($this->field, $product);
|
||||
}
|
||||
|
||||
function divide($other) {
|
||||
if ($this->field !==$other->field) {
|
||||
throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field");
|
||||
}
|
||||
if ($other->isZero()) {
|
||||
throw new \InvalidArgumentException("Divide by 0");
|
||||
}
|
||||
|
||||
$quotient = $this->field->getZero();
|
||||
$remainder = $this;
|
||||
|
||||
$denominatorLeadingTerm = $other->getCoefficient($other->getDegree());
|
||||
$inverseDenominatorLeadingTerm = $this->field->inverse($denominatorLeadingTerm);
|
||||
|
||||
while ($remainder->getDegree() >= $other->getDegree() && !$remainder->isZero()) {
|
||||
$degreeDifference = $remainder->getDegree() - $other->getDegree();
|
||||
$scale = $this->field->multiply($remainder->getCoefficient($remainder->getDegree()), $inverseDenominatorLeadingTerm);
|
||||
$term = $other->multiplyByMonomial($degreeDifference, $scale);
|
||||
$iterationQuotient = $this->field->buildMonomial($degreeDifference, $scale);
|
||||
$quotient = $quotient->addOrSubtract($iterationQuotient);
|
||||
$remainder = $remainder->addOrSubtract($term);
|
||||
}
|
||||
|
||||
return array($quotient, $remainder );
|
||||
}
|
||||
|
||||
//@Override
|
||||
public function toString() {
|
||||
$result = '';
|
||||
for ($degree = $this->getDegree(); $degree >= 0; $degree--) {
|
||||
$coefficient = $this->getCoefficient($degree);
|
||||
if ($coefficient != 0) {
|
||||
if ($coefficient < 0) {
|
||||
$result.=" - ";
|
||||
$coefficient = -$coefficient;
|
||||
} else {
|
||||
if (strlen($result) > 0) {
|
||||
$result .= " + ";
|
||||
}
|
||||
}
|
||||
if ($degree == 0 || $coefficient != 1) {
|
||||
$alphaPower = $this->field->log($coefficient);
|
||||
if ($alphaPower == 0) {
|
||||
$result.='1';
|
||||
} else if ($alphaPower == 1) {
|
||||
$result.='a';
|
||||
} else {
|
||||
$result.="a^";
|
||||
$result.=($alphaPower);
|
||||
}
|
||||
}
|
||||
if ($degree != 0) {
|
||||
if ($degree == 1) {
|
||||
$result.='x';
|
||||
} else {
|
||||
$result.="x^";
|
||||
$result.= $degree;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
192
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php
vendored
Normal file
192
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common\Reedsolomon;
|
||||
|
||||
/**
|
||||
* <p>Implements Reed-Solomon decoding, as the name implies.</p>
|
||||
*
|
||||
* <p>The algorithm will not be explained here, but the following references were helpful
|
||||
* in creating this implementation:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>Bruce Maggs.
|
||||
* <a href="http://www.cs.cmu.edu/afs/cs.cmu.edu/project/pscico-guyb/realworld/www/rs_decode.ps">
|
||||
* "Decoding Reed-Solomon Codes"</a> (see discussion of Forney's Formula)</li>
|
||||
* <li>J.I. Hall. <a href="www.mth.msu.edu/~jhall/classes/codenotes/GRS.pdf">
|
||||
* "Chapter 5. Generalized Reed-Solomon Codes"</a>
|
||||
* (see discussion of Euclidean algorithm)</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Much credit is due to William Rucklidge since portions of this code are an indirect
|
||||
* port of his C++ Reed-Solomon implementation.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author William Rucklidge
|
||||
* @author sanfordsquires
|
||||
*/
|
||||
final class ReedSolomonDecoder {
|
||||
|
||||
private $field;
|
||||
|
||||
public function __construct($field) {
|
||||
$this->field = $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Decodes given set of received codewords, which include both data and error-correction
|
||||
* codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
|
||||
* in the input.</p>
|
||||
*
|
||||
* @param received data and error-correction codewords
|
||||
* @param twoS number of error-correction codewords available
|
||||
* @throws ReedSolomonException if decoding fails for any reason
|
||||
*/
|
||||
public function decode(&$received, $twoS) {
|
||||
$poly = new GenericGFPoly($this->field, $received);
|
||||
$syndromeCoefficients = fill_array(0,$twoS,0);
|
||||
$noError = true;
|
||||
for ($i = 0; $i < $twoS; $i++) {
|
||||
$eval = $poly->evaluateAt($this->field->exp($i + $this->field->getGeneratorBase()));
|
||||
$syndromeCoefficients[count($syndromeCoefficients) - 1 - $i] = $eval;
|
||||
if ($eval != 0) {
|
||||
$noError = false;
|
||||
}
|
||||
}
|
||||
if ($noError) {
|
||||
return;
|
||||
}
|
||||
$syndrome = new GenericGFPoly($this->field, $syndromeCoefficients);
|
||||
$sigmaOmega =
|
||||
$this->runEuclideanAlgorithm($this->field->buildMonomial($twoS, 1), $syndrome, $twoS);
|
||||
$sigma = $sigmaOmega[0];
|
||||
$omega = $sigmaOmega[1];
|
||||
$errorLocations = $this->findErrorLocations($sigma);
|
||||
$errorMagnitudes = $this->findErrorMagnitudes($omega, $errorLocations);
|
||||
for ($i = 0; $i < count($errorLocations); $i++) {
|
||||
$position = count($received) - 1 - $this->field->log($errorLocations[$i]);
|
||||
if ($position < 0) {
|
||||
throw new ReedSolomonException("Bad error location");
|
||||
}
|
||||
$received[$position] = GenericGF::addOrSubtract($received[$position], $errorMagnitudes[$i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function runEuclideanAlgorithm($a, $b, $R)
|
||||
{
|
||||
// Assume a's degree is >= b's
|
||||
if ($a->getDegree() < $b->getDegree()) {
|
||||
$temp = $a;
|
||||
$a = $b;
|
||||
$b = $temp;
|
||||
}
|
||||
|
||||
$rLast = $a;
|
||||
$r = $b;
|
||||
$tLast = $this->field->getZero();
|
||||
$t = $this->field->getOne();
|
||||
|
||||
// Run Euclidean algorithm until r's degree is less than R/2
|
||||
while ($r->getDegree() >= $R / 2) {
|
||||
$rLastLast = $rLast;
|
||||
$tLastLast = $tLast;
|
||||
$rLast = $r;
|
||||
$tLast = $t;
|
||||
|
||||
// Divide rLastLast by rLast, with quotient in q and remainder in r
|
||||
if ($rLast->isZero()) {
|
||||
// Oops, Euclidean algorithm already terminated?
|
||||
throw new ReedSolomonException("r_{i-1} was zero");
|
||||
}
|
||||
$r = $rLastLast;
|
||||
$q = $this->field->getZero();
|
||||
$denominatorLeadingTerm = $rLast->getCoefficient($rLast->getDegree());
|
||||
$dltInverse = $this->field->inverse($denominatorLeadingTerm);
|
||||
while ($r->getDegree() >= $rLast->getDegree() && !$r->isZero()) {
|
||||
$degreeDiff = $r->getDegree() - $rLast->getDegree();
|
||||
$scale = $this->field->multiply($r->getCoefficient($r->getDegree()), $dltInverse);
|
||||
$q = $q->addOrSubtract($this->field->buildMonomial($degreeDiff, $scale));
|
||||
$r = $r->addOrSubtract($rLast->multiplyByMonomial($degreeDiff, $scale));
|
||||
}
|
||||
|
||||
$t = $q->multiply($tLast)->addOrSubtract($tLastLast);
|
||||
|
||||
if ($r->getDegree() >= $rLast->getDegree()) {
|
||||
throw new IllegalStateException("Division algorithm failed to reduce polynomial?");
|
||||
}
|
||||
}
|
||||
|
||||
$sigmaTildeAtZero = $t->getCoefficient(0);
|
||||
if ($sigmaTildeAtZero == 0) {
|
||||
throw new ReedSolomonException("sigmaTilde(0) was zero");
|
||||
}
|
||||
|
||||
$inverse = $this->field->inverse($sigmaTildeAtZero);
|
||||
$sigma = $t->multiply($inverse);
|
||||
$omega = $r->multiply($inverse);
|
||||
return array($sigma, $omega);
|
||||
}
|
||||
|
||||
private function findErrorLocations($errorLocator) {
|
||||
// This is a direct application of Chien's search
|
||||
$numErrors = $errorLocator->getDegree();
|
||||
if ($numErrors == 1) { // shortcut
|
||||
return array($errorLocator->getCoefficient(1) );
|
||||
}
|
||||
$result = fill_array(0,$numErrors,0);
|
||||
$e = 0;
|
||||
for ($i = 1; $i < $this->field->getSize() && $e < $numErrors; $i++) {
|
||||
if ($errorLocator->evaluateAt($i) == 0) {
|
||||
$result[$e] = $this->field->inverse($i);
|
||||
$e++;
|
||||
}
|
||||
}
|
||||
if ($e != $numErrors) {
|
||||
throw new ReedSolomonException("Error locator degree does not match number of roots");
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function findErrorMagnitudes($errorEvaluator, $errorLocations) {
|
||||
// This is directly applying Forney's Formula
|
||||
$s = count($errorLocations);
|
||||
$result = fill_array(0,$s,0);
|
||||
for ($i = 0; $i < $s; $i++) {
|
||||
$xiInverse = $this->field->inverse($errorLocations[$i]);
|
||||
$denominator = 1;
|
||||
for ($j = 0; $j < $s; $j++) {
|
||||
if ($i != $j) {
|
||||
//denominator = field.multiply(denominator,
|
||||
// GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
|
||||
// Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
|
||||
// Below is a funny-looking workaround from Steven Parkes
|
||||
$term = $this->field->multiply($errorLocations[$j], $xiInverse);
|
||||
$termPlus1 = ($term & 0x1) == 0 ? $term | 1 : $term & ~1;
|
||||
$denominator = $this->field->multiply($denominator, $termPlus1);
|
||||
}
|
||||
}
|
||||
$result[$i] = $this->field->multiply($errorEvaluator->evaluateAt($xiInverse),
|
||||
$this->field->inverse($denominator));
|
||||
if ($this->field->getGeneratorBase() != 0) {
|
||||
$result[$i] = $this->field->multiply($result[$i], $xiInverse);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
31
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php
vendored
Normal file
31
vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2007 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Zxing\Common\Reedsolomon;
|
||||
|
||||
/**
|
||||
* <p>Thrown when an exception occurs during Reed-Solomon decoding, such as when
|
||||
* there are too many errors to correct.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class ReedSolomonException extends \Exception {
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user