This page lists files in the current directory. You can view content, get download/execute commands for Wget, Curl, or PowerShell, or filter the list using wildcards (e.g., `*.sh`).
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/ByteStream.php'
<?php
/**
* ByteStream.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Estimate;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Spec;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\ByteStream
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
class ByteStream extends \Com\Tecnick\Barcode\Type\Square\QrCode\Encode
{
/**
* Encoding mode
*
* @var int
*/
protected $hint = 2;
/**
* QR code version.
* The Size of QRcode is defined as version. Version is an integer value from 1 to 40.
* Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases.
* So version 40 is 177*177 matrix.
*
* @var int
*/
public $version = 0;
/**
* Error correction level
*
* @var int
*/
protected $level = 0;
/**
* Initialize
*
* @param int $hint Encoding mode
* @param int $version Code version
* @param int $level Error Correction Level
*/
public function __construct($hint, $version, $level)
{
$this->hint = $hint;
$this->version = $version;
$this->level = $level;
}
/**
* Pack all bit streams padding bits into a byte array
*
* @param array $items items
*
* @return array padded merged byte stream
*/
public function getByteStream($items)
{
return $this->bitstreamToByte(
$this->appendPaddingBit(
$this->mergeBitStream($items)
)
);
}
/**
* Convert bitstream to bytes
*
* @param array $bstream Original bitstream
*
* @return array of bytes
*/
protected function bitstreamToByte($bstream)
{
$size = count($bstream);
if ($size == 0) {
return array();
}
$data = array_fill(0, (int)(($size + 7) / 8), 0);
$bytes = (int)($size / 8);
$pos = 0;
for ($idx = 0; $idx < $bytes; ++$idx) {
$val = 0;
for ($jdx = 0; $jdx < 8; ++$jdx) {
$val = $val << 1;
$val |= $bstream[$pos];
$pos++;
}
$data[$idx] = $val;
}
if ($size & 7) {
$val = 0;
for ($jdx = 0; $jdx < ($size & 7); ++$jdx) {
$val = $val << 1;
$val |= $bstream[$pos];
$pos++;
}
$data[$bytes] = $val;
}
return $data;
}
/**
* merge the bit stream
*
* @param array $items Items
*
* @return array bitstream
*/
protected function mergeBitStream($items)
{
$items = $this->convertData($items);
$bstream = array();
foreach ($items as $item) {
$bstream = $this->appendBitstream($bstream, $item['bstream']);
}
return $bstream;
}
/**
* convertData
*
* @param array $items Items
*
* @return array items
*/
protected function convertData($items)
{
$ver = $this->estimateVersion($items, $this->level);
if ($ver > $this->version) {
$this->version = $ver;
}
while (true) {
$cbs = $this->createBitStream($items);
$items = $cbs[0];
$bits = $cbs[1];
if ($bits < 0) {
throw new BarcodeException('Negative Bits value');
}
$ver = $this->getMinimumVersion((int)(($bits + 7) / 8), $this->level);
if ($ver > $this->version) {
$this->version = $ver;
} else {
break;
}
}
return $items;
}
/**
* Create BitStream
*
* @param $items
*
* @return array of items and total bits
*/
protected function createBitStream($items)
{
$total = 0;
foreach ($items as $key => $item) {
$items[$key] = $this->encodeBitStream($item, $this->version);
$bits = count($items[$key]['bstream']);
$total += $bits;
}
return array($items, $total);
}
/**
* Encode BitStream
*
* @param array $inputitem
* @param int $version
*
* @return array input item
*/
public function encodeBitStream($inputitem, $version)
{
$inputitem['bstream'] = array();
$specObj = new Spec;
$words = $specObj->maximumWords($inputitem['mode'], $version);
if ($inputitem['size'] > $words) {
$st1 = $this->newInputItem($inputitem['mode'], $words, $inputitem['data']);
$st2 = $this->newInputItem(
$inputitem['mode'],
($inputitem['size'] - $words),
array_slice($inputitem['data'], $words)
);
$st1 = $this->encodeBitStream($st1, $version);
$st2 = $this->encodeBitStream($st2, $version);
$inputitem['bstream'] = array();
$inputitem['bstream'] = $this->appendBitstream($inputitem['bstream'], $st1['bstream']);
$inputitem['bstream'] = $this->appendBitstream($inputitem['bstream'], $st2['bstream']);
} else {
switch ($inputitem['mode']) {
case Data::$encodingModes['NM']:
$inputitem = $this->encodeModeNum($inputitem, $version);
break;
case Data::$encodingModes['AN']:
$inputitem = $this->encodeModeAn($inputitem, $version);
break;
case Data::$encodingModes['8B']:
$inputitem = $this->encodeMode8($inputitem, $version);
break;
case Data::$encodingModes['KJ']:
$inputitem = $this->encodeModeKanji($inputitem, $version);
break;
case Data::$encodingModes['ST']:
$inputitem = $this->encodeModeStructure($inputitem);
break;
}
}
return $inputitem;
}
/**
* Append Padding Bit to bitstream
*
* @param array $bstream Bit stream
*
* @return array bitstream
*/
protected function appendPaddingBit($bstream)
{
if (is_null($bstream)) {
return null;
}
$bits = count($bstream);
$specObj = new Spec;
$maxwords = $specObj->getDataLength($this->version, $this->level);
$maxbits = $maxwords * 8;
if ($maxbits == $bits) {
return $bstream;
}
if ($maxbits - $bits < 5) {
return $this->appendNum($bstream, $maxbits - $bits, 0);
}
$bits += 4;
$words = (int)(($bits + 7) / 8);
$padding = array();
$padding = $this->appendNum($padding, $words * 8 - $bits + 4, 0);
$padlen = $maxwords - $words;
if ($padlen > 0) {
$padbuf = array();
for ($idx = 0; $idx < $padlen; ++$idx) {
$padbuf[$idx] = (($idx & 1) ? 0x11 : 0xec);
}
$padding = $this->appendBytes($padding, $padlen, $padbuf);
}
return $this->appendBitstream($bstream, $padding);
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Data.php'
<?php
/**
* Data.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Data
*
* Data for QrCode Barcode type class
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
class Data
{
/**
* Maximum QR Code version.
*/
const QRSPEC_VERSION_MAX = 40;
/**
* Maximum matrix size for maximum version (version 40 is 177*177 matrix).
*/
const QRSPEC_WIDTH_MAX = 177;
// -----------------------------------------------------
/**
* Matrix index to get width from $capacity array.
*/
const QRCAP_WIDTH = 0;
/**
* Matrix index to get number of words from $capacity array.
*/
const QRCAP_WORDS = 1;
/**
* Matrix index to get remainder from $capacity array.
*/
const QRCAP_REMINDER = 2;
/**
* Matrix index to get error correction level from $capacity array.
*/
const QRCAP_EC = 3;
// -----------------------------------------------------
// Structure (currently usupported)
/**
* Number of header bits for structured mode
*/
const STRUCTURE_HEADER_BITS = 20;
/**
* Max number of symbols for structured mode
*/
const MAX_STRUCTURED_SYMBOLS = 16;
// -----------------------------------------------------
// Masks
/**
* Down point base value for case 1 mask pattern (concatenation of same color in a line or a column)
*/
const N1 = 3;
/**
* Down point base value for case 2 mask pattern (module block of same color)
*/
const N2 = 3;
/**
* Down point base value for case 3 mask pattern
* (1:1:3:1:1(dark:bright:dark:bright:dark)pattern in a line or a column)
*/
const N3 = 40;
/**
* Down point base value for case 4 mask pattern (ration of dark modules in whole)
*/
const N4 = 10;
/**
* Encoding modes (characters which can be encoded in QRcode)
*
* NL : variable
* NM : Encoding mode numeric (0-9). 3 characters are encoded to 10bit length.
* AN : Encoding mode alphanumeric (0-9A-Z $%*+-./:) 45characters. 2 characters are encoded to 11bit length.
* 8B : Encoding mode 8bit byte data. In theory, 2953 characters or less can be stored in a QRcode.
* KJ : Encoding mode KANJI. A KANJI character (multibyte character) is encoded to 13bit length.
* ST : Encoding mode STRUCTURED
*
* @var array
*/
public static $encodingModes = array('NL' => -1, 'NM' => 0, 'AN' => 1, '8B' => 2, 'KJ' => 3, 'ST' => 4);
/**
* Array of valid error correction levels
* QRcode has a function of an error correcting for miss reading that white is black.
* Error correcting is defined in 4 level as below.
* L : About 7% or less errors can be corrected.
* M : About 15% or less errors can be corrected.
* Q : About 25% or less errors can be corrected.
* H : About 30% or less errors can be corrected.
*
* @var array
*/
public static $errCorrLevels = array('L' => 0, 'M' => 1, 'Q' => 2, 'H' => 3);
/**
* Alphabet-numeric conversion table.
*
* @var array
*/
public static $anTable = array(
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //
36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, //
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, //
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, //
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 //
);
/**
* Array Table of the capacity of symbols.
* See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004.
*
* @var array
*/
public static $capacity = array(
array( 0, 0, 0, array( 0, 0, 0, 0)), //
array( 21, 26, 0, array( 7, 10, 13, 17)), // 1
array( 25, 44, 7, array( 10, 16, 22, 28)), //
array( 29, 70, 7, array( 15, 26, 36, 44)), //
array( 33, 100, 7, array( 20, 36, 52, 64)), //
array( 37, 134, 7, array( 26, 48, 72, 88)), // 5
array( 41, 172, 7, array( 36, 64, 96, 112)), //
array( 45, 196, 0, array( 40, 72, 108, 130)), //
array( 49, 242, 0, array( 48, 88, 132, 156)), //
array( 53, 292, 0, array( 60, 110, 160, 192)), //
array( 57, 346, 0, array( 72, 130, 192, 224)), // 10
array( 61, 404, 0, array( 80, 150, 224, 264)), //
array( 65, 466, 0, array( 96, 176, 260, 308)), //
array( 69, 532, 0, array( 104, 198, 288, 352)), //
array( 73, 581, 3, array( 120, 216, 320, 384)), //
array( 77, 655, 3, array( 132, 240, 360, 432)), // 15
array( 81, 733, 3, array( 144, 280, 408, 480)), //
array( 85, 815, 3, array( 168, 308, 448, 532)), //
array( 89, 901, 3, array( 180, 338, 504, 588)), //
array( 93, 991, 3, array( 196, 364, 546, 650)), //
array( 97, 1085, 3, array( 224, 416, 600, 700)), // 20
array(101, 1156, 4, array( 224, 442, 644, 750)), //
array(105, 1258, 4, array( 252, 476, 690, 816)), //
array(109, 1364, 4, array( 270, 504, 750, 900)), //
array(113, 1474, 4, array( 300, 560, 810, 960)), //
array(117, 1588, 4, array( 312, 588, 870, 1050)), // 25
array(121, 1706, 4, array( 336, 644, 952, 1110)), //
array(125, 1828, 4, array( 360, 700, 1020, 1200)), //
array(129, 1921, 3, array( 390, 728, 1050, 1260)), //
array(133, 2051, 3, array( 420, 784, 1140, 1350)), //
array(137, 2185, 3, array( 450, 812, 1200, 1440)), // 30
array(141, 2323, 3, array( 480, 868, 1290, 1530)), //
array(145, 2465, 3, array( 510, 924, 1350, 1620)), //
array(149, 2611, 3, array( 540, 980, 1440, 1710)), //
array(153, 2761, 3, array( 570, 1036, 1530, 1800)), //
array(157, 2876, 0, array( 570, 1064, 1590, 1890)), // 35
array(161, 3034, 0, array( 600, 1120, 1680, 1980)), //
array(165, 3196, 0, array( 630, 1204, 1770, 2100)), //
array(169, 3362, 0, array( 660, 1260, 1860, 2220)), //
array(173, 3532, 0, array( 720, 1316, 1950, 2310)), //
array(177, 3706, 0, array( 750, 1372, 2040, 2430)) // 40
);
/**
* Array Length indicator.
*
* @var array
*/
public static $lengthTableBits = array(
array(10, 12, 14),
array( 9, 11, 13),
array( 8, 16, 16),
array( 8, 10, 12)
);
/**
* Array Table of the error correction code (Reed-Solomon block).
* See Table 12-16 (pp.30-36), JIS X0510:2004.
*
* @var array
*/
public static $eccTable = array(
array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)), //
array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1
array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), //
array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)), //
array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)), //
array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5
array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)), //
array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)), //
array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)), //
array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)), //
array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), // 10
array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)), //
array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)), //
array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)), //
array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)), //
array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), // 15
array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)), //
array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)), //
array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)), //
array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)), //
array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), // 20
array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)), //
array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)), //
array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)), //
array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)), //
array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), // 25
array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)), //
array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)), //
array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)), //
array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)), //
array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), // 30
array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)), //
array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)), //
array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)), //
array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)), //
array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), // 35
array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)), //
array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)), //
array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), //
array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), //
array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)) // 40
);
/**
* Array Positions of alignment patterns.
* This array includes only the second and the third position of the alignment patterns.
* Rest of them can be calculated from the distance between them.
* See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
*
* @var array
*/
public static $alignmentPattern = array(
array( 0, 0),
array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5
array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), // 11-15
array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), // 16-20
array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), // 21-25
array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), // 26-30
array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), // 31-35
array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58) // 35-40
);
/**
* Array Version information pattern (BCH coded).
* See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
* size: [QRSPEC_VERSION_MAX - 6]
*
* @var array
*/
public static $versionPattern = array(
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, //
0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, //
0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, //
0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64, //
0x27541, 0x28c69
);
/**
* Array Format information
*
* @var array
*/
public static $formatInfo = array(
array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), //
array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), //
array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed), //
array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b) //
);
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Encode.php'
<?php
/**
* Encode.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Encode
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class Encode extends \Com\Tecnick\Barcode\Type\Square\QrCode\EncodingMode
{
/**
* encode Mode Num
*
* @param array $inputitem
* @param int $version
*
* @return array input item
*/
protected function encodeModeNum($inputitem, $version)
{
$words = (int)($inputitem['size'] / 3);
$inputitem['bstream'] = array();
$val = 0x1;
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, $val);
$inputitem['bstream'] = $this->appendNum(
$inputitem['bstream'],
$this->getLengthIndicator(Data::$encodingModes['NM'], $version),
$inputitem['size']
);
for ($i=0; $i < $words; ++$i) {
$val = (ord($inputitem['data'][$i*3 ]) - ord('0')) * 100;
$val += (ord($inputitem['data'][$i*3+1]) - ord('0')) * 10;
$val += (ord($inputitem['data'][$i*3+2]) - ord('0'));
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 10, $val);
}
if ($inputitem['size'] - $words * 3 == 1) {
$val = ord($inputitem['data'][$words*3]) - ord('0');
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, $val);
} elseif (($inputitem['size'] - ($words * 3)) == 2) {
$val = (ord($inputitem['data'][$words*3 ]) - ord('0')) * 10;
$val += (ord($inputitem['data'][$words*3+1]) - ord('0'));
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 7, $val);
}
return $inputitem;
}
/**
* encode Mode An
*
* @param array $inputitem
* @param int $version
*
* @return array input item
*/
protected function encodeModeAn($inputitem, $version)
{
$words = (int)($inputitem['size'] / 2);
$inputitem['bstream'] = array();
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x02);
$inputitem['bstream'] = $this->appendNum(
$inputitem['bstream'],
$this->getLengthIndicator(Data::$encodingModes['AN'], $version),
$inputitem['size']
);
for ($idx = 0; $idx < $words; ++$idx) {
$val = (int)($this->lookAnTable(ord($inputitem['data'][($idx * 2)])) * 45);
$val += (int)($this->lookAnTable(ord($inputitem['data'][($idx * 2)+1])));
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 11, $val);
}
if ($inputitem['size'] & 1) {
$val = $this->lookAnTable(ord($inputitem['data'][($words * 2)]));
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 6, $val);
}
return $inputitem;
}
/**
* encode Mode 8
*
* @param array $inputitem
* @param int $version
*
* @return array input item
*/
protected function encodeMode8($inputitem, $version)
{
$inputitem['bstream'] = array();
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x4);
$inputitem['bstream'] = $this->appendNum(
$inputitem['bstream'],
$this->getLengthIndicator(Data::$encodingModes['8B'], $version),
$inputitem['size']
);
for ($idx = 0; $idx < $inputitem['size']; ++$idx) {
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 8, ord($inputitem['data'][$idx]));
}
return $inputitem;
}
/**
* encode Mode Kanji
*
* @param array $inputitem
* @param int $version
*
* @return array input item
*/
protected function encodeModeKanji($inputitem, $version)
{
$inputitem['bstream'] = array();
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x8);
$inputitem['bstream'] = $this->appendNum(
$inputitem['bstream'],
$this->getLengthIndicator(Data::$encodingModes['KJ'], $version),
(int)($inputitem['size'] / 2)
);
for ($idx = 0; $idx < $inputitem['size']; $idx += 2) {
$val = (ord($inputitem['data'][$idx]) << 8) | ord($inputitem['data'][($idx + 1)]);
if ($val <= 0x9ffc) {
$val -= 0x8140;
} else {
$val -= 0xc140;
}
$val = ($val & 0xff) + (($val >> 8) * 0xc0);
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 13, $val);
}
return $inputitem;
}
/**
* encode Mode Structure
*
* @param array $inputitem
*
* @return array input item
*/
protected function encodeModeStructure($inputitem)
{
$inputitem['bstream'] = array();
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x03);
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, ord($inputitem['data'][1]) - 1);
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, ord($inputitem['data'][0]) - 1);
$inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 8, ord($inputitem['data'][2]));
return $inputitem;
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Encoder.php'
<?php
/**
* Encoder.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Spec;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Encoder
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
class Encoder extends \Com\Tecnick\Barcode\Type\Square\QrCode\Init
{
/**
* Data code
*
* @var array
*/
protected $datacode = array();
/**
* Error correction code
*
* @var array
*/
protected $ecccode = array();
/**
* Blocks
*
* @var array
*/
protected $blocks;
/**
* Reed-Solomon blocks
*
* @var array
*/
protected $rsblocks = array(); //of RSblock
/**
* Counter
*
* @var int
*/
protected $count;
/**
* Data length
*
* @var int
*/
protected $dataLength;
/**
* Error correction length
*
* @var int
*/
protected $eccLength;
/**
* Value bv1
*
* @var int
*/
protected $bv1;
/**
* Width.
*
* @var int
*/
protected $width;
/**
* Frame
*
* @var array
*/
protected $frame;
/**
* Horizontal bit position
*
* @var int
*/
protected $xpos;
/**
* Vertical bit position
*
* @var int
*/
protected $ypos;
/**
* Direction
*
* @var int
*/
protected $dir;
/**
* Single bit value
*
* @var int
*/
protected $bit;
/**
* Reed-Solomon items
*
* @va array
*/
protected $rsitems = array();
/**
* Encode mask
*
* @param int $maskNo Mask number (masking mode)
* @param array $datacode Data code to encode
*
* @return array Encoded Mask
*/
public function encodeMask($maskNo, $datacode)
{
// initialize values
$this->datacode = $datacode;
$spec = $this->spc->getEccSpec($this->version, $this->level, array(0, 0, 0, 0, 0));
$this->bv1 = $this->spc->rsBlockNum1($spec);
$this->dataLength = $this->spc->rsDataLength($spec);
$this->eccLength = $this->spc->rsEccLength($spec);
$this->ecccode = array_fill(0, $this->eccLength, 0);
$this->blocks = $this->spc->rsBlockNum($spec);
$this->init($spec);
$this->count = 0;
$this->width = $this->spc->getWidth($this->version);
$this->frame = $this->spc->createFrame($this->version);
$this->xpos = ($this->width - 1);
$this->ypos = ($this->width - 1);
$this->dir = -1;
$this->bit = -1;
// interleaved data and ecc codes
for ($idx = 0; $idx < ($this->dataLength + $this->eccLength); $idx++) {
$code = $this->getCode();
$bit = 0x80;
for ($jdx = 0; $jdx < 8; $jdx++) {
$addr = $this->getNextPosition();
$this->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
$bit = $bit >> 1;
}
}
// remainder bits
$rbits = $this->spc->getRemainder($this->version);
for ($idx = 0; $idx < $rbits; $idx++) {
$addr = $this->getNextPosition();
$this->setFrameAt($addr, 0x02);
}
// masking
$this->runLength = array_fill(0, (Data::QRSPEC_WIDTH_MAX + 1), 0);
if ($maskNo < 0) {
if ($this->qr_find_best_mask) {
$mask = $this->mask($this->width, $this->frame, $this->level);
} else {
$mask = $this->makeMask($this->width, $this->frame, (intval($this->qr_default_mask) % 8), $this->level);
}
} else {
$mask = $this->makeMask($this->width, $this->frame, $maskNo, $this->level);
}
if ($mask == null) {
throw new BarcodeException('Null Mask');
}
return $mask;
}
/**
* Return Reed-Solomon block code
*
* @return array rsblocks
*/
protected function getCode()
{
if ($this->count < $this->dataLength) {
$row = ($this->count % $this->blocks);
$col = floor($this->count / $this->blocks);
if ($col >= $this->rsblocks[0]['dataLength']) {
$row += $this->bv1;
}
$ret = $this->rsblocks[$row]['data'][$col];
} elseif ($this->count < ($this->dataLength + $this->eccLength)) {
$row = (($this->count - $this->dataLength) % $this->blocks);
$col = floor(($this->count - $this->dataLength) / $this->blocks);
$ret = $this->rsblocks[$row]['ecc'][$col];
} else {
return 0;
}
++$this->count;
return $ret;
}
/**
* Set frame value at specified position
*
* @param array $pos X,Y position
* @param int $val Value of the character to set
*/
protected function setFrameAt($pos, $val)
{
$this->frame[$pos['y']][$pos['x']] = chr($val);
}
/**
* Return the next frame position
*
* @return array of x,y coordinates
*/
protected function getNextPosition()
{
do {
if ($this->bit == -1) {
$this->bit = 0;
return array('x' => $this->xpos, 'y' => $this->ypos);
}
$xpos = $this->xpos;
$ypos = $this->ypos;
$wdt = $this->width;
$this->getNextPositionB($xpos, $ypos, $wdt);
if (($xpos < 0) || ($ypos < 0)) {
throw new BarcodeException('Error getting next position');
}
$this->xpos = $xpos;
$this->ypos = $ypos;
} while (ord($this->frame[$ypos][$xpos]) & 0x80);
return array('x' => $xpos, 'y' => $ypos);
}
/**
* Internal cycle for getNextPosition
*
* @param int $xpos
* @param int $ypos
* @param int $wdt
*/
protected function getNextPositionB(&$xpos, &$ypos, $wdt)
{
if ($this->bit == 0) {
--$xpos;
++$this->bit;
} else {
++$xpos;
$ypos += $this->dir;
--$this->bit;
}
if ($this->dir < 0) {
if ($ypos < 0) {
$ypos = 0;
$xpos -= 2;
$this->dir = 1;
if ($xpos == 6) {
--$xpos;
$ypos = 9;
}
}
} else {
if ($ypos == $wdt) {
$ypos = $wdt - 1;
$xpos -= 2;
$this->dir = -1;
if ($xpos == 6) {
--$xpos;
$ypos -= 8;
}
}
}
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/EncodingMode.php'
<?php
/**
* EncodingMode.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\EncodingMode
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class EncodingMode extends \Com\Tecnick\Barcode\Type\Square\QrCode\InputItem
{
/**
* Get the encoding mode to use
*
* @param string $data Data
* @param int $pos Position
*
* @return int mode
*/
public function getEncodingMode($data, $pos)
{
if (!isset($data[$pos])) {
return Data::$encodingModes['NL'];
}
if ($this->isDigitAt($data, $pos)) {
return Data::$encodingModes['NM'];
}
if ($this->isAlphanumericAt($data, $pos)) {
return Data::$encodingModes['AN'];
}
return $this->getEncodingModeKj($data, $pos);
}
/**
* Get the encoding mode for KJ or 8B
*
* @param string $data Data
* @param int $pos Position
*
* @return int mode
*/
protected function getEncodingModeKj($data, $pos)
{
if (($this->hint == Data::$encodingModes['KJ']) && isset($data[($pos + 1)])) {
$word = ((ord($data[$pos]) << 8) | ord($data[($pos + 1)]));
if ((($word >= 0x8140) && ($word <= 0x9ffc)) || (($word >= 0xe040) && ($word <= 0xebbf))) {
return Data::$encodingModes['KJ'];
}
}
return Data::$encodingModes['8B'];
}
/**
* Return true if the character at specified position is a number
*
* @param string $str Data
* @param int $pos Character position
*
* @return boolean
*/
public function isDigitAt($str, $pos)
{
if (!isset($str[$pos])) {
return false;
}
return ((ord($str[$pos]) >= ord('0')) && (ord($str[$pos]) <= ord('9')));
}
/**
* Return true if the character at specified position is an alphanumeric character
*
* @param string $str Data
* @param int $pos Character position
*
* @return boolean
*/
public function isAlphanumericAt($str, $pos)
{
if (!isset($str[$pos])) {
return false;
}
return ($this->lookAnTable(ord($str[$pos])) >= 0);
}
/**
* Look up the alphabet-numeric conversion table (see JIS X0510:2004, pp.19)
*
* @param int $chr Character value
*
* @return value
*/
public function lookAnTable($chr)
{
return (($chr > 127) ? -1 : Data::$anTable[$chr]);
}
/**
* Return the size of length indicator for the mode and version
*
* @param int $mode Encoding mode
* @param int $version Version
*
* @return int the size of the appropriate length indicator (bits).
*/
public function getLengthIndicator($mode)
{
if ($mode == Data::$encodingModes['ST']) {
return 0;
}
if ($this->version <= 9) {
$len = 0;
} elseif ($this->version <= 26) {
$len = 1;
} else {
$len = 2;
}
return Data::$lengthTableBits[$mode][$len];
}
/**
* Append one bitstream to another
*
* @param array $bitstream Original bitstream
* @param array $append Bitstream to append
*
* @return array bitstream
*/
protected function appendBitstream($bitstream, $append)
{
if ((!is_array($append)) || (count($append) == 0)) {
return $bitstream;
}
if (count($bitstream) == 0) {
return $append;
}
return array_values(array_merge($bitstream, $append));
}
/**
* Append one bitstream created from number to another
*
* @param array $bitstream Original bitstream
* @param int $bits Number of bits
* @param int $num Number
*
* @return array bitstream
*/
protected function appendNum($bitstream, $bits, $num)
{
if ($bits == 0) {
return 0;
}
return $this->appendBitstream($bitstream, $this->newFromNum($bits, $num));
}
/**
* Append one bitstream created from bytes to another
*
* @param array $bitstream Original bitstream
* @param int $size Size
* @param array $data Bytes
*
* @return array bitstream
*/
protected function appendBytes($bitstream, $size, $data)
{
if ($size == 0) {
return 0;
}
return $this->appendBitstream($bitstream, $this->newFromBytes($size, $data));
}
/**
* Return new bitstream from number
*
* @param int $bits Number of bits
* @param int $num Number
*
* @return array bitstream
*/
protected function newFromNum($bits, $num)
{
$bstream = $this->allocate($bits);
$mask = 1 << ($bits - 1);
for ($idx = 0; $idx < $bits; ++$idx) {
if ($num & $mask) {
$bstream[$idx] = 1;
} else {
$bstream[$idx] = 0;
}
$mask = $mask >> 1;
}
return $bstream;
}
/**
* Return new bitstream from bytes
*
* @param int $size Size
* @param array $data Bytes
*
* @return array bitstream
*/
protected function newFromBytes($size, $data)
{
$bstream = $this->allocate($size * 8);
$pval = 0;
for ($idx = 0; $idx < $size; ++$idx) {
$mask = 0x80;
for ($jdx = 0; $jdx < 8; ++$jdx) {
if ($data[$idx] & $mask) {
$bstream[$pval] = 1;
} else {
$bstream[$pval] = 0;
}
$pval++;
$mask = $mask >> 1;
}
}
return $bstream;
}
/**
* Return an array with zeros
*
* @param int $setLength Array size
*
* @return array
*/
protected function allocate($setLength)
{
return array_fill(0, $setLength, 0);
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Estimate.php'
<?php
/**
* Estimate.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Estimate
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class Estimate
{
/**
* estimateBitsModeNum
*
* @param int $size
*
* @return int number of bits
*/
public function estimateBitsModeNum($size)
{
$wdt = (int)($size / 3);
$bits = ($wdt * 10);
switch ($size - ($wdt * 3)) {
case 1:
$bits += 4;
break;
case 2:
$bits += 7;
break;
}
return $bits;
}
/**
* estimateBitsModeAn
*
* @param int $size
*
* @return int number of bits
*/
public function estimateBitsModeAn($size)
{
$bits = (int)($size * 5.5); // (size / 2 ) * 11
if ($size & 1) {
$bits += 6;
}
return $bits;
}
/**
* estimateBitsMode8
*
* @param int $size
*
* @return int number of bits
*/
public function estimateBitsMode8($size)
{
return (int)($size * 8);
}
/**
* estimateBitsModeKanji
*
* @param int $size
*
* @return int number of bits
*/
public function estimateBitsModeKanji($size)
{
return (int)($size * 6.5); // (size / 2 ) * 13
}
/**
* Estimate version
*
* @param array $items
* @param int $level
*
* @return int version
*/
public function estimateVersion($items, $level)
{
$version = 0;
$prev = 0;
do {
$prev = $version;
$bits = $this->estimateBitStreamSize($items, $prev);
$version = $this->getMinimumVersion((int)(($bits + 7) / 8), $level);
if ($version < 0) {
return -1;
}
} while ($version > $prev);
return $version;
}
/**
* Return a version number that satisfies the input code length.
*
* @param int $size Input code length (bytes)
* @param int $level Error correction level
*
* @return int version number
*
* @throws BarcodeException
*/
protected function getMinimumVersion($size, $level)
{
for ($idx = 1; $idx <= Data::QRSPEC_VERSION_MAX; ++$idx) {
$words = (Data::$capacity[$idx][Data::QRCAP_WORDS] - Data::$capacity[$idx][Data::QRCAP_EC][$level]);
if ($words >= $size) {
return $idx;
}
}
throw new BarcodeException(
'The size of input data is greater than Data::QR capacity, try to lower the error correction mode'
);
}
/**
* estimateBitStreamSize
*
* @param array $items
* @param int $version
*
* @return int bits
*/
protected function estimateBitStreamSize($items, $version)
{
$bits = 0;
if ($version == 0) {
$version = 1;
}
foreach ($items as $item) {
switch ($item['mode']) {
case Data::$encodingModes['NM']:
$bits = $this->estimateBitsModeNum($item['size']);
break;
case Data::$encodingModes['AN']:
$bits = $this->estimateBitsModeAn($item['size']);
break;
case Data::$encodingModes['8B']:
$bits = $this->estimateBitsMode8($item['size']);
break;
case Data::$encodingModes['KJ']:
$bits = $this->estimateBitsModeKanji($item['size']);
break;
case Data::$encodingModes['ST']:
return Data::STRUCTURE_HEADER_BITS;
default:
return 0;
}
$len = $this->getLengthIndicator($item['mode'], $version);
$mod = 1 << $len;
$num = (int)(($item['size'] + $mod - 1) / $mod);
$bits += $num * (4 + $len);
}
return $bits;
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Init.php'
<?php
/**
* Init.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Spec;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Init
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class Init extends \Com\Tecnick\Barcode\Type\Square\QrCode\Mask
{
/**
* Initialize code
*
* @param array $spec Array of ECC specification
*/
protected function init($spec)
{
$dlv = $this->spc->rsDataCodes1($spec);
$elv = $this->spc->rsEccCodes1($spec);
$rsv = $this->initRs(8, 0x11d, 0, 1, $elv, 255 - $dlv - $elv);
$blockNo = 0;
$dataPos = 0;
$eccPos = 0;
$endfor = $this->spc->rsBlockNum1($spec);
$this->initLoop($endfor, $dlv, $elv, $rsv, $eccPos, $blockNo, $dataPos, $ecc);
if ($this->spc->rsBlockNum2($spec) == 0) {
return;
}
$dlv = $this->spc->rsDataCodes2($spec);
$elv = $this->spc->rsEccCodes2($spec);
$rsv = $this->initRs(8, 0x11d, 0, 1, $elv, 255 - $dlv - $elv);
if ($rsv == null) {
throw new BarcodeException('Empty RS');
}
$endfor = $this->spc->rsBlockNum2($spec);
$this->initLoop($endfor, $dlv, $elv, $rsv, $eccPos, $blockNo, $dataPos, $ecc);
}
/**
* Internal loop for init
*
* @param int $endfor
* @param int $dlv
* @param int $elv
* @param int $rsv
* @param int $eccPos
* @param int $blockNo
* @param int $dataPos
* @param int $ecc
*/
protected function initLoop($endfor, $dlv, $elv, $rsv, &$eccPos, &$blockNo, &$dataPos, &$ecc)
{
for ($idx = 0; $idx < $endfor; ++$idx) {
$ecc = array_slice($this->ecccode, $eccPos);
$this->rsblocks[$blockNo] = array();
$this->rsblocks[$blockNo]['dataLength'] = $dlv;
$this->rsblocks[$blockNo]['data'] = array_slice($this->datacode, $dataPos);
$this->rsblocks[$blockNo]['eccLength'] = $elv;
$ecc = $this->encodeRsChar($rsv, $this->rsblocks[$blockNo]['data'], $ecc);
$this->rsblocks[$blockNo]['ecc'] = $ecc;
$this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc);
$dataPos += $dlv;
$eccPos += $elv;
$blockNo++;
}
}
/**
* Initialize a Reed-Solomon codec and add it to existing rsitems
*
* @param int $symsize Symbol size, bits
* @param int $gfpoly Field generator polynomial coefficients
* @param int $fcr First root of RS code generator polynomial, index form
* @param int $prim Primitive element to generate polynomial roots
* @param int $nroots RS code generator polynomial degree (number of roots)
* @param int $pad Padding bytes at front of shortened block
*
* @return array Array of RS values:
* mm = Bits per symbol;
* nn = Symbols per block;
* alpha_to = log lookup table array;
* index_of = Antilog lookup table array;
* genpoly = Generator polynomial array;
* nroots = Number of generator;
* roots = number of parity symbols;
* fcr = First consecutive root, index form;
* prim = Primitive element, index form;
* iprim = prim-th root of 1, index form;
* pad = Padding bytes in shortened block;
* gfpoly.
*/
protected function initRs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
{
foreach ($this->rsitems as $rsv) {
if (($rsv['pad'] != $pad)
|| ($rsv['nroots'] != $nroots)
|| ($rsv['mm'] != $symsize)
|| ($rsv['gfpoly'] != $gfpoly)
|| ($rsv['fcr'] != $fcr)
|| ($rsv['prim'] != $prim)) {
continue;
}
return $rsv;
}
$rsv = $this->initRsChar($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
array_unshift($this->rsitems, $rsv);
return $rsv;
}
/**
* modnn
*
* @param array $rsv RS values
* @param int $xpos X position
*
* @return int X position
*/
protected function modnn($rsv, $xpos)
{
while ($xpos >= $rsv['nn']) {
$xpos -= $rsv['nn'];
$xpos = (($xpos >> $rsv['mm']) + ($xpos & $rsv['nn']));
}
return $xpos;
}
/**
* Check the params for the initRsChar and throws an exception in case of error.
*
* @param int $symsize Symbol size, bits
* @param int $fcr First root of RS code generator polynomial, index form
* @param int $prim Primitive element to generate polynomial roots
*
* @throws BarcodeException in case of error
*/
protected function checkRsCharParamsA($symsize, $fcr, $prim)
{
$shfsymsize = (1 << $symsize);
if (($symsize < 0)
|| ($symsize > 8)
|| ($fcr < 0)
|| ($fcr >= $shfsymsize)
|| ($prim <= 0)
|| ($prim >= $shfsymsize)
) {
throw new BarcodeException('Invalid parameters');
}
}
/**
* Check the params for the initRsChar and throws an exception in case of error.
*
* @param int $symsize Symbol size, bits
* @param int $nroots RS code generator polynomial degree (number of roots)
* @param int $pad Padding bytes at front of shortened block
*
* @throws BarcodeException in case of error
*/
protected function checkRsCharParamsB($symsize, $nroots, $pad)
{
$shfsymsize = (1 << $symsize);
if (($nroots < 0)
|| ($nroots >= $shfsymsize)
|| ($pad < 0)
|| ($pad >= ($shfsymsize - 1 - $nroots))
) {
throw new BarcodeException('Invalid parameters');
}
}
/**
* Initialize a Reed-Solomon codec and returns an array of values.
*
* @param int $symsize Symbol size, bits
* @param int $gfpoly Field generator polynomial coefficients
* @param int $fcr First root of RS code generator polynomial, index form
* @param int $prim Primitive element to generate polynomial roots
* @param int $nroots RS code generator polynomial degree (number of roots)
* @param int $pad Padding bytes at front of shortened block
*
* @return array Array of RS values:
* mm = Bits per symbol;
* nn = Symbols per block;
* alpha_to = log lookup table array;
* index_of = Antilog lookup table array;
* genpoly = Generator polynomial array;
* nroots = Number of generator;
* roots = number of parity symbols;
* fcr = First consecutive root, index form;
* prim = Primitive element, index form;
* iprim = prim-th root of 1, index form;
* pad = Padding bytes in shortened block;
* gfpoly.
*/
protected function initRsChar($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
{
$this->checkRsCharParamsA($symsize, $fcr, $prim);
$this->checkRsCharParamsB($symsize, $nroots, $pad);
$rsv = array();
$rsv['mm'] = $symsize;
$rsv['nn'] = ((1 << $symsize) - 1);
$rsv['pad'] = $pad;
$rsv['alpha_to'] = array_fill(0, ($rsv['nn'] + 1), 0);
$rsv['index_of'] = array_fill(0, ($rsv['nn'] + 1), 0);
// PHP style macro replacement
$nnv =& $rsv['nn'];
$azv =& $nnv;
// Generate Galois field lookup tables
$rsv['index_of'][0] = $azv; // log(zero) = -inf
$rsv['alpha_to'][$azv] = 0; // alpha**-inf = 0
$srv = 1;
for ($idx = 0; $idx <$rsv['nn']; ++$idx) {
$rsv['index_of'][$srv] = $idx;
$rsv['alpha_to'][$idx] = $srv;
$srv <<= 1;
if ($srv & (1 << $symsize)) {
$srv ^= $gfpoly;
}
$srv &= $rsv['nn'];
}
if ($srv != 1) {
throw new BarcodeException('field generator polynomial is not primitive!');
}
// form RS code generator polynomial from its roots
$rsv['genpoly'] = array_fill(0, ($nroots + 1), 0);
$rsv['fcr'] = $fcr;
$rsv['prim'] = $prim;
$rsv['nroots'] = $nroots;
$rsv['gfpoly'] = $gfpoly;
// find prim-th root of 1, used in decoding
for ($iprim = 1; ($iprim % $prim) != 0; $iprim += $rsv['nn']) {
; // intentional empty-body loop!
}
$rsv['iprim'] = (int)($iprim / $prim);
$rsv['genpoly'][0] = 1;
for ($idx = 0, $root = ($fcr * $prim); $idx < $nroots; ++$idx, $root += $prim) {
$rsv['genpoly'][($idx + 1)] = 1;
// multiply rs->genpoly[] by @**(root + x)
for ($jdx = $idx; $jdx > 0; --$jdx) {
if ($rsv['genpoly'][$jdx] != 0) {
$rsv['genpoly'][$jdx] = ($rsv['genpoly'][($jdx - 1)]
^ $rsv['alpha_to'][$this->modnn($rsv, $rsv['index_of'][$rsv['genpoly'][$jdx]] + $root)]);
} else {
$rsv['genpoly'][$jdx] = $rsv['genpoly'][($jdx - 1)];
}
}
// rs->genpoly[0] can never be zero
$rsv['genpoly'][0] = $rsv['alpha_to'][$this->modnn($rsv, $rsv['index_of'][$rsv['genpoly'][0]] + $root)];
}
// convert rs->genpoly[] to index form for quicker encoding
for ($idx = 0; $idx <= $nroots; ++$idx) {
$rsv['genpoly'][$idx] = $rsv['index_of'][$rsv['genpoly'][$idx]];
}
return $rsv;
}
/**
* Encode a Reed-Solomon codec and returns the parity array
*
* @param array $rsv RS values
* @param array $data Data
* @param array $parity Parity
*
* @return array Parity array
*/
protected function encodeRsChar($rsv, $data, $parity)
{
// the total number of symbols in a RS block
$nnv =& $rsv['nn'];
// the address of an array of NN elements to convert Galois field elements
// in index (log) form to polynomial form
$alphato =& $rsv['alpha_to'];
// the address of an array of NN elements to convert Galois field elements
// in polynomial form to index (log) form
$indexof =& $rsv['index_of'];
// an array of NROOTS+1 elements containing the generator polynomial in index form
$genpoly =& $rsv['genpoly'];
// the number of roots in the RS code generator polynomial,
// which is the same as the number of parity symbols in a block
$nroots =& $rsv['nroots'];
// the number of pad symbols in a block
$pad =& $rsv['pad'];
$azv =& $nnv;
$parity = array_fill(0, $nroots, 0);
for ($idx = 0; $idx < ($nnv - $nroots - $pad); ++$idx) {
$feedback = $indexof[$data[$idx] ^ $parity[0]];
if ($feedback != $azv) {
// feedback term is non-zero
// This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
// always be for the polynomials constructed by initRs()
$feedback = $this->modnn($rsv, ($nnv - $genpoly[$nroots] + $feedback));
for ($jdx = 1; $jdx < $nroots; ++$jdx) {
$parity[$jdx] ^= $alphato[$this->modnn($rsv, $feedback + $genpoly[($nroots - $jdx)])];
}
}
// Shift
array_shift($parity);
if ($feedback != $azv) {
array_push($parity, $alphato[$this->modnn($rsv, $feedback + $genpoly[0])]);
} else {
array_push($parity, 0);
}
}
return $parity;
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/InputItem.php'
<?php
/**
* InputItem.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\InputItem
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class InputItem extends \Com\Tecnick\Barcode\Type\Square\QrCode\Estimate
{
/**
* Append data to an input object.
* The data is copied and appended to the input object.
*
* @param array $items Input items
* @param int $mode Encoding mode.
* @param int $size Size of data (byte).
* @param array $data Array of input data.
*
* @return array items
*/
public function appendNewInputItem($items, $mode, $size, $data)
{
$newitem = $this->newInputItem($mode, $size, $data);
if (!empty($newitem)) {
$items[] = $newitem;
}
return $items;
}
/**
* newInputItem
*
* @param int $mode Encoding mode.
* @param int $size Size of data (byte).
* @param array $data Array of input data.
* @param array $bstream Binary stream
*
* @return array input item
*/
protected function newInputItem($mode, $size, $data, $bstream = null)
{
$setData = array_slice($data, 0, $size);
if (count($setData) < $size) {
$setData = array_merge($setData, array_fill(0, ($size - count($setData)), 0));
}
if (!$this->check($mode, $size, $setData)) {
throw new BarcodeException('Invalid input item');
}
return array(
'mode' => $mode,
'size' => $size,
'data' => $setData,
'bstream' => $bstream,
);
}
/**
* Validate the input data.
*
* @param int $mode Encoding mode.
* @param int $size Size of data (byte).
* @param array $data Data to validate
*
* @return boolean true in case of valid data, false otherwise
*/
protected function check($mode, $size, $data)
{
if ($size <= 0) {
return false;
}
switch ($mode) {
case Data::$encodingModes['NM']:
return $this->checkModeNum($size, $data);
case Data::$encodingModes['AN']:
return $this->checkModeAn($size, $data);
case Data::$encodingModes['KJ']:
return $this->checkModeKanji($size, $data);
case Data::$encodingModes['8B']:
return true;
case Data::$encodingModes['ST']:
return true;
}
return false;
}
/**
* checkModeNum
*
* @param int $size
* @param int $data
*
* @return boolean true or false
*/
protected function checkModeNum($size, $data)
{
for ($idx = 0; $idx < $size; ++$idx) {
if ((ord($data[$idx]) < ord('0')) || (ord($data[$idx]) > ord('9'))) {
return false;
}
}
return true;
}
/**
* checkModeAn
*
* @param int $size
* @param int $data
*
* @return boolean true or false
*/
protected function checkModeAn($size, $data)
{
for ($idx = 0; $idx < $size; ++$idx) {
if ($this->lookAnTable(ord($data[$idx])) == -1) {
return false;
}
}
return true;
}
/**
* checkModeKanji
*
* @param int $size
* @param int $data
*
* @return boolean true or false
*/
protected function checkModeKanji($size, $data)
{
if ($size & 1) {
return false;
}
for ($idx = 0; $idx < $size; $idx += 2) {
$val = (ord($data[$idx]) << 8) | ord($data[($idx + 1)]);
if (($val < 0x8140) || (($val > 0x9ffc) && ($val < 0xe040)) || ($val > 0xebbf)) {
return false;
}
}
return true;
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Mask.php'
<?php
/**
* Mask.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Spec;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Mask
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class Mask extends \Com\Tecnick\Barcode\Type\Square\QrCode\MaskNum
{
/**
* If false, checks all masks available,
* otherwise the value indicates the number of masks to be checked, mask id are random
*
* @var int
*/
protected $qr_find_from_random = false;
/**
* If true, estimates best mask (spec. default, but extremally slow;
* set to false to significant performance boost but (propably) worst quality code
*
* @var bool
*/
protected $qr_find_best_mask = true;
/**
* Default mask used when $this->qr_find_best_mask === false
*
* @var int
*/
protected $qr_default_mask = 2;
/**
* Run length
*
* @var array
*/
protected $runLength = array();
/**
* QR code version.
* The Size of QRcode is defined as version. Version is an integer value from 1 to 40.
* Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases.
* So version 40 is 177*177 matrix.
*
* @var int
*/
public $version = 0;
/**
* Error correction level
*
* @var int
*/
protected $level = 0;
/**
* Spec class object
*
* @var \Com\Tecnick\Barcode\Type\Square\QrCode\Spec
*/
protected $spc;
/**
* Initialize
*
* @param int $version Code version
* @param int $level Error Correction Level
* @param bool $random_mask If false, checks all masks available,
* otherwise the value indicates the number of masks to be checked, mask id are random
* @param bool $best_mask If true, estimates best mask (slow)
* @param int $default_mask Default mask used when $fbm is false
*/
public function __construct($version, $level, $random_mask = false, $best_mask = true, $default_mask = 2)
{
$this->version = $version;
$this->level = $level;
$this->qr_find_from_random = (bool)$random_mask;
$this->qr_find_best_mask = (bool)$best_mask;
$this->qr_default_mask = intval($default_mask);
$this->spc = new Spec;
}
/**
* Get the best mask
*
* @param int $width Width
* @param array $frame Frame
* @param int $level Error Correction lLevel
*
* @return array best mask
*/
protected function mask($width, $frame, $level)
{
$minDemerit = PHP_INT_MAX;
$bestMask = array();
$checked_masks = array(0, 1, 2, 3, 4, 5, 6, 7);
if ($this->qr_find_from_random !== false) {
$howManuOut = (8 - ($this->qr_find_from_random % 9));
for ($idx = 0; $idx < $howManuOut; ++$idx) {
$remPos = rand(0, (count($checked_masks) - 1));
unset($checked_masks[$remPos]);
$checked_masks = array_values($checked_masks);
}
}
$bestMask = $frame;
foreach ($checked_masks as $idx) {
$mask = array_fill(0, $width, str_repeat("\0", $width));
$demerit = 0;
$blacks = 0;
$blacks = $this->makeMaskNo($idx, $width, $frame, $mask);
$blacks += $this->writeFormatInformation($width, $mask, $idx, $level);
$blacks = (int)(100 * $blacks / ($width * $width));
$demerit = (int)((int)(abs($blacks - 50) / 5) * Data::N4);
$demerit += $this->evaluateSymbol($width, $mask);
if ($demerit < $minDemerit) {
$minDemerit = $demerit;
$bestMask = $mask;
}
}
return $bestMask;
}
/**
* Make a mask
*
* @param int $width Mask width
* @param array $frame Frame
* @param int $maskNo Mask number
* @param int $level Error Correction level
*
* @return array mask
*/
protected function makeMask($width, $frame, $maskNo, $level)
{
$this->makeMaskNo($maskNo, $width, $frame, $mask);
$this->writeFormatInformation($width, $mask, $maskNo, $level);
return $mask;
}
/**
* Write Format Information on the frame and returns the number of black bits
*
* @param int $width Mask width
* @param array $frame Frame
* @param int $maskNo Mask number
* @param int $level Error Correction level
*
* @return int blacks
*/
protected function writeFormatInformation($width, &$frame, $maskNo, $level)
{
$blacks = 0;
$spec = new Spec;
$format = $spec->getFormatInfo($maskNo, $level);
for ($idx = 0; $idx < 8; ++$idx) {
if ($format & 1) {
$blacks += 2;
$val = 0x85;
} else {
$val = 0x84;
}
$frame[8][($width - 1 - $idx)] = chr($val);
if ($idx < 6) {
$frame[$idx][8] = chr($val);
} else {
$frame[($idx + 1)][8] = chr($val);
}
$format = $format >> 1;
}
for ($idx = 0; $idx < 7; ++$idx) {
if ($format & 1) {
$blacks += 2;
$val = 0x85;
} else {
$val = 0x84;
}
$frame[($width - 7 + $idx)][8] = chr($val);
if ($idx == 0) {
$frame[8][7] = chr($val);
} else {
$frame[8][(6 - $idx)] = chr($val);
}
$format = $format >> 1;
}
return $blacks;
}
/**
* Evaluate Symbol
*
* @param int $width Width
* @param array $frame Frame
*
* @return int demerit
*/
protected function evaluateSymbol($width, $frame)
{
for ($ypos = 0; $ypos < $width; ++$ypos) {
$frameY = $frame[$ypos];
if ($ypos > 0) {
$frameYM = $frame[($ypos - 1)];
} else {
$frameYM = $frameY;
}
$demerit = $this->evaluateSymbolB($ypos, $width, $frameY, $frameYM);
}
for ($xpos = 0; $xpos < $width; ++$xpos) {
$head = 0;
$this->runLength[0] = 1;
for ($ypos = 0; $ypos < $width; ++$ypos) {
if (($ypos == 0) && (ord($frame[$ypos][$xpos]) & 1)) {
$this->runLength[0] = -1;
$head = 1;
$this->runLength[$head] = 1;
} elseif ($ypos > 0) {
if ((ord($frame[$ypos][$xpos]) ^ ord($frame[($ypos - 1)][$xpos])) & 1) {
$head++;
$this->runLength[$head] = 1;
} else {
$this->runLength[$head]++;
}
}
}
$demerit += $this->calcN1N3($head + 1);
}
return $demerit;
}
/**
* Evaluate Symbol
*
* @param int $ypos Y position
* @param int $width Width
* @param array $frameY
* @param array $frameYM
*
* @return int demerit
*/
protected function evaluateSymbolB($ypos, $width, $frameY, $frameYM)
{
$head = 0;
$demerit = 0;
$this->runLength[0] = 1;
for ($xpos = 0; $xpos < $width; ++$xpos) {
if (($xpos > 0) && ($ypos > 0)) {
$b22 = ord($frameY[$xpos])
& ord($frameY[($xpos - 1)])
& ord($frameYM[$xpos])
& ord($frameYM[($xpos - 1)]);
$w22 = ord($frameY[$xpos])
| ord($frameY[($xpos - 1)])
| ord($frameYM[$xpos])
| ord($frameYM[($xpos - 1)]);
if (($b22 | ($w22 ^ 1)) & 1) {
$demerit += Data::N2;
}
}
if (($xpos == 0) && (ord($frameY[$xpos]) & 1)) {
$this->runLength[0] = -1;
$head = 1;
$this->runLength[$head] = 1;
} elseif ($xpos > 0) {
if ((ord($frameY[$xpos]) ^ ord($frameY[($xpos - 1)])) & 1) {
$head++;
$this->runLength[$head] = 1;
} else {
++$this->runLength[$head];
}
}
}
return ($demerit + $this->calcN1N3($head + 1));
}
/**
* Calc N1 N3
*
* @param int $length
*
* @return int demerit
*/
protected function calcN1N3($length)
{
$demerit = 0;
for ($idx = 0; $idx < $length; ++$idx) {
if ($this->runLength[$idx] >= 5) {
$demerit += (Data::N1 + ($this->runLength[$idx] - 5));
}
if (($idx & 1) && ($idx >= 3) && ($idx < ($length - 2)) && ($this->runLength[$idx] % 3 == 0)) {
$demerit += $this->calcN1N3delta($length, $idx);
}
}
return $demerit;
}
/**
* Calc N1 N3 delta
*
* @param int $length
* @param int $idx
*
* @return int demerit delta
*/
protected function calcN1N3delta($length, $idx)
{
$fact = (int)($this->runLength[$idx] / 3);
if (($this->runLength[($idx - 2)] == $fact)
&& ($this->runLength[($idx - 1)] == $fact)
&& ($this->runLength[($idx + 1)] == $fact)
&& ($this->runLength[($idx + 2)] == $fact)) {
if (($this->runLength[($idx - 3)] < 0) || ($this->runLength[($idx - 3)] >= (4 * $fact))) {
return Data::N3;
} elseif ((($idx + 3) >= $length) || ($this->runLength[($idx + 3)] >= (4 * $fact))) {
return Data::N3;
}
}
return 0;
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/MaskNum.php'
<?php
/**
* MaskNum.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\MaskNum
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class MaskNum
{
/**
* Make Mask Number
*
* @param int $maskNo Mask number
* @param int $width Width
* @param int $frame Frame
* @param int $mask Mask
*
* @return int mask number
*/
protected function makeMaskNo($maskNo, $width, $frame, &$mask)
{
$bnum = 0;
$bitMask = $this->generateMaskNo($maskNo, $width, $frame);
$mask = $frame;
for ($ypos = 0; $ypos < $width; ++$ypos) {
for ($xpos = 0; $xpos < $width; ++$xpos) {
if ($bitMask[$ypos][$xpos] == 1) {
$mask[$ypos][$xpos] = chr(ord($frame[$ypos][$xpos]) ^ ((int)($bitMask[$ypos][$xpos])));
}
$bnum += (int)(ord($mask[$ypos][$xpos]) & 1);
}
}
return $bnum;
}
/**
* Return bit mask
*
* @param int $maskNo Mask number
* @param int $width Width
* @param array $frame Frame
*
* @return array bit mask
*/
protected function generateMaskNo($maskNo, $width, $frame)
{
$bitMask = array_fill(0, $width, array_fill(0, $width, 0));
for ($ypos = 0; $ypos < $width; ++$ypos) {
for ($xpos = 0; $xpos < $width; ++$xpos) {
if (ord($frame[$ypos][$xpos]) & 0x80) {
$bitMask[$ypos][$xpos] = 0;
} else {
$maskFunc = call_user_func(array($this, 'mask'.$maskNo), $xpos, $ypos);
$bitMask[$ypos][$xpos] = (($maskFunc == 0) ? 1 : 0);
}
}
}
return $bitMask;
}
/**
* Mask 0
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask0($xpos, $ypos)
{
return (($xpos + $ypos) & 1);
}
/**
* Mask 1
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask1($xpos, $ypos)
{
$xpos = null;
return ($ypos & 1);
}
/**
* Mask 2
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask2($xpos, $ypos)
{
$ypos = null;
return ($xpos % 3);
}
/**
* Mask 3
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask3($xpos, $ypos)
{
return (($xpos + $ypos) % 3);
}
/**
* Mask 4
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask4($xpos, $ypos)
{
return ((((int)($ypos / 2)) + ((int)($xpos / 3))) & 1);
}
/**
* Mask 5
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask5($xpos, $ypos)
{
return ((($xpos * $ypos) & 1) + ($xpos * $ypos) % 3);
}
/**
* Mask 6
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask6($xpos, $ypos)
{
return (((($xpos * $ypos) & 1) + ($xpos * $ypos) % 3) & 1);
}
/**
* Mask 7
*
* @param int $xpos X position
* @param int $ypos Y position
*
* @return int mask
*/
protected function mask7($xpos, $ypos)
{
return (((($xpos * $ypos) % 3) + (($xpos + $ypos) & 1)) & 1);
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Spec.php'
<?php
/**
* Spec.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Spec
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
class Spec extends \Com\Tecnick\Barcode\Type\Square\QrCode\SpecRs
{
/**
* Replace a value on the array at the specified position
*
* @param array $srctab
* @param int $xpos X position
* @param int $ypos Y position
* @param string $repl Value to replace
* @param int $replLen Length of the repl string
*
* @return array srctab
*/
public function qrstrset($srctab, $xpos, $ypos, $repl, $replLen = false)
{
$srctab[$ypos] = substr_replace(
$srctab[$ypos],
($replLen !== false) ? substr($repl, 0, $replLen) : $repl,
$xpos,
($replLen !== false) ? $replLen : strlen($repl)
);
return $srctab;
}
/**
* Return maximum data code length (bytes) for the version.
*
* @param int $version Version
* @param int $level Error correction level
*
* @return int maximum size (bytes)
*/
public function getDataLength($version, $level)
{
return (Data::$capacity[$version][Data::QRCAP_WORDS] - Data::$capacity[$version][Data::QRCAP_EC][$level]);
}
/**
* Return maximum error correction code length (bytes) for the version.
*
* @param int $version Version
* @param int $level Error correction level
*
* @return int ECC size (bytes)
*/
public function getECCLength($version, $level)
{
return Data::$capacity[$version][Data::QRCAP_EC][$level];
}
/**
* Return the width of the symbol for the version.
*
* @param int $version Version
*
* @return int width
*/
public function getWidth($version)
{
return Data::$capacity[$version][Data::QRCAP_WIDTH];
}
/**
* Return the numer of remainder bits.
*
* @param int $version Version
*
* @return int number of remainder bits
*/
public function getRemainder($version)
{
return Data::$capacity[$version][Data::QRCAP_REMINDER];
}
/**
* Return the maximum length for the mode and version.
*
* @param int $mode Encoding mode
* @param int $version Version
*
* @return int the maximum length (bytes)
*/
public function maximumWords($mode, $version)
{
if ($mode == Data::$encodingModes['ST']) {
return 3;
}
if ($version <= 9) {
$lval = 0;
} elseif ($version <= 26) {
$lval = 1;
} else {
$lval = 2;
}
$bits = Data::$lengthTableBits[$mode][$lval];
$words = (1 << $bits) - 1;
if ($mode == Data::$encodingModes['KJ']) {
$words *= 2; // the number of bytes is required
}
return $words;
}
/**
* Return an array of ECC specification.
*
* @param int $version Version
* @param int $level Error correction level
* @param array $spec Array of ECC specification contains as following:
* {# of type1 blocks, # of data code, # of ecc code, # of type2 blocks, # of data code}
*
* @return array spec
*/
public function getEccSpec($version, $level, $spec)
{
if (count($spec) < 5) {
$spec = array(0, 0, 0, 0, 0);
}
$bv1 = Data::$eccTable[$version][$level][0];
$bv2 = Data::$eccTable[$version][$level][1];
$data = $this->getDataLength($version, $level);
$ecc = $this->getECCLength($version, $level);
if ($bv2 == 0) {
$spec[0] = $bv1;
$spec[1] = (int)($data / $bv1);
$spec[2] = (int)($ecc / $bv1);
$spec[3] = 0;
$spec[4] = 0;
} else {
$spec[0] = $bv1;
$spec[1] = (int)($data / ($bv1 + $bv2));
$spec[2] = (int)($ecc / ($bv1 + $bv2));
$spec[3] = $bv2;
$spec[4] = $spec[1] + 1;
}
return $spec;
}
/**
* Put an alignment marker.
*
* @param array $frame Frame
* @param int $pox X center coordinate of the pattern
* @param int $poy Y center coordinate of the pattern
*
* @return array frame
*/
public function putAlignmentMarker($frame, $pox, $poy)
{
$finder = array(
"\xa1\xa1\xa1\xa1\xa1",
"\xa1\xa0\xa0\xa0\xa1",
"\xa1\xa0\xa1\xa0\xa1",
"\xa1\xa0\xa0\xa0\xa1",
"\xa1\xa1\xa1\xa1\xa1"
);
$yStart = $poy - 2;
$xStart = $pox - 2;
for ($ydx = 0; $ydx < 5; ++$ydx) {
$frame = $this->qrstrset($frame, $xStart, ($yStart + $ydx), $finder[$ydx]);
}
return $frame;
}
/**
* Put an alignment pattern.
*
* @param int $version Version
* @param array $frame Frame
* @param int $width Width
*
* @return array frame
*/
public function putAlignmentPattern($version, $frame, $width)
{
if ($version < 2) {
return $frame;
}
$dval = Data::$alignmentPattern[$version][1] - Data::$alignmentPattern[$version][0];
if ($dval < 0) {
$wdt = 2;
} else {
$wdt = (int)(($width - Data::$alignmentPattern[$version][0]) / $dval + 2);
}
if ($wdt * $wdt - 3 == 1) {
$psx = Data::$alignmentPattern[$version][0];
$psy = Data::$alignmentPattern[$version][0];
$frame = $this->putAlignmentMarker($frame, $psx, $psy);
return $frame;
}
$cpx = Data::$alignmentPattern[$version][0];
$wdo = $wdt - 1;
for ($xpos = 1; $xpos < $wdo; ++$xpos) {
$frame = $this->putAlignmentMarker($frame, 6, $cpx);
$frame = $this->putAlignmentMarker($frame, $cpx, 6);
$cpx += $dval;
}
$cpy = Data::$alignmentPattern[$version][0];
for ($y=0; $y < $wdo; ++$y) {
$cpx = Data::$alignmentPattern[$version][0];
for ($xpos = 0; $xpos < $wdo; ++$xpos) {
$frame = $this->putAlignmentMarker($frame, $cpx, $cpy);
$cpx += $dval;
}
$cpy += $dval;
}
return $frame;
}
/**
* Return BCH encoded version information pattern that is used for the symbol of version 7 or greater.
* Use lower 18 bits.
*
* @param int $version Version
*
* @return BCH encoded version information pattern
*/
public function getVersionPattern($version)
{
if (($version < 7) || ($version > Data::QRSPEC_VERSION_MAX)) {
return 0;
}
return Data::$versionPattern[($version - 7)];
}
/**
* Return BCH encoded format information pattern.
*
* @param array $maskNo Mask number
* @param int $level Error correction level
*
* @return BCH encoded format information pattern
*/
public function getFormatInfo($maskNo, $level)
{
if (($maskNo < 0)
|| ($maskNo > 7)
|| ($level < 0)
|| ($level > 3)
) {
return 0;
}
return Data::$formatInfo[$level][$maskNo];
}
/**
* Put a finder pattern.
*
* @param array $frame Frame
* @param int $pox X center coordinate of the pattern
* @param int $poy Y center coordinate of the pattern
*
* @return array frame
*/
public function putFinderPattern($frame, $pox, $poy)
{
$finder = array(
"\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
"\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
"\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
"\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
"\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
"\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
"\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
);
for ($ypos = 0; $ypos < 7; ++$ypos) {
$frame = $this->qrstrset($frame, $pox, ($poy + $ypos), $finder[$ypos]);
}
return $frame;
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/SpecRs.php'
<?php
/**
* SpecRs.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\SpecRs
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
abstract class SpecRs
{
/**
* Return block number 0
*
* @param array $spec
*
* @return int value
*/
public function rsBlockNum($spec)
{
return ($spec[0] + $spec[3]);
}
/**
* Return block number 1
*
* @param array $spec
*
* @return int value
*/
public function rsBlockNum1($spec)
{
return $spec[0];
}
/**
* Return data codes 1
*
* @param array $spec
*
* @return int value
*/
public function rsDataCodes1($spec)
{
return $spec[1];
}
/**
* Return ecc codes 1
*
* @param array $spec
*
* @return int value
*/
public function rsEccCodes1($spec)
{
return $spec[2];
}
/**
* Return block number 2
*
* @param array $spec
*
* @return int value
*/
public function rsBlockNum2($spec)
{
return $spec[3];
}
/**
* Return data codes 2
*
* @param array $spec
*
* @return int value
*/
public function rsDataCodes2($spec)
{
return $spec[4];
}
/**
* Return ecc codes 2
*
* @param array $spec
*
* @return int value
*/
public function rsEccCodes2($spec)
{
return $spec[2];
}
/**
* Return data length
*
* @param array $spec
*
* @return int value
*/
public function rsDataLength($spec)
{
return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]);
}
/**
* Return ecc length
*
* @param array $spec
*
* @return int value
*/
public function rsEccLength($spec)
{
return ($spec[0] + $spec[3]) * $spec[2];
}
/**
* Return a copy of initialized frame.
*
* @param int $version Version
*
* @return Array of unsigned char.
*/
public function createFrame($version)
{
$width = Data::$capacity[$version][Data::QRCAP_WIDTH];
$frameLine = str_repeat("\0", $width);
$frame = array_fill(0, $width, $frameLine);
// Finder pattern
$frame = $this->putFinderPattern($frame, 0, 0);
$frame = $this->putFinderPattern($frame, $width - 7, 0);
$frame = $this->putFinderPattern($frame, 0, $width - 7);
// Separator
$yOffset = $width - 7;
for ($ypos = 0; $ypos < 7; ++$ypos) {
$frame[$ypos][7] = "\xc0";
$frame[$ypos][$width - 8] = "\xc0";
$frame[$yOffset][7] = "\xc0";
++$yOffset;
}
$setPattern = str_repeat("\xc0", 8);
$frame = $this->qrstrset($frame, 0, 7, $setPattern);
$frame = $this->qrstrset($frame, $width-8, 7, $setPattern);
$frame = $this->qrstrset($frame, 0, $width - 8, $setPattern);
// Format info
$setPattern = str_repeat("\x84", 9);
$frame = $this->qrstrset($frame, 0, 8, $setPattern);
$frame = $this->qrstrset($frame, $width - 8, 8, $setPattern, 8);
$yOffset = $width - 8;
for ($ypos = 0; $ypos < 8; ++$ypos, ++$yOffset) {
$frame[$ypos][8] = "\x84";
$frame[$yOffset][8] = "\x84";
}
// Timing pattern
$wdo = $width - 15;
for ($idx = 1; $idx < $wdo; ++$idx) {
$frame[6][(7 + $idx)] = chr(0x90 | ($idx & 1));
$frame[(7 + $idx)][6] = chr(0x90 | ($idx & 1));
}
// Alignment pattern
$frame = $this->putAlignmentPattern($version, $frame, $width);
// Version information
if ($version >= 7) {
$vinf = $this->getVersionPattern($version);
$val = $vinf;
for ($xpos = 0; $xpos < 6; ++$xpos) {
for ($ypos = 0; $ypos < 3; ++$ypos) {
$frame[(($width - 11) + $ypos)][$xpos] = chr(0x88 | ($val & 1));
$val = $val >> 1;
}
}
$val = $vinf;
for ($ypos = 0; $ypos < 6; ++$ypos) {
for ($xpos = 0; $xpos < 3; ++$xpos) {
$frame[$ypos][($xpos + ($width - 11))] = chr(0x88 | ($val & 1));
$val = $val >> 1;
}
}
}
// and a little bit...
$frame[$width - 8][8] = "\x81";
return $frame;
}
}
wget 'https://lists2.roe3.org/hesk/inc/tecnick/Barcode/Type/Square/QrCode/Split.php'
<?php
/**
* Split.php
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*
* This file is part of tc-lib-barcode software library.
*/
namespace Com\Tecnick\Barcode\Type\Square\QrCode;
use \Com\Tecnick\Barcode\Exception as BarcodeException;
use \Com\Tecnick\Barcode\Type\Square\QrCode\Data;
use \Com\Tecnick\Barcode\Type\Square\QrCode\ByteStream;
/**
* Com\Tecnick\Barcode\Type\Square\QrCode\Split
*
* @since 2015-02-21
* @category Library
* @package Barcode
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-barcode
*/
class Split
{
/**
* EncodingMode class object
*
* @var \Com\Tecnick\Barcode\Type\Square\QrCode\EncodingMode
*/
protected $bsObj;
/**
* Input items
*
* @var array
*/
protected $items = array();
/**
* QR code version.
* The Size of QRcode is defined as version. Version is an integer value from 1 to 40.
* Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases.
* So version 40 is 177*177 matrix.
*
* @var int
*/
protected $version = 0;
/**
* Encoding mode
*
* @var int
*/
protected $hint = 2;
/**
* Initialize
*
* @param ByteStream $bsObj ByteStream Class object
* @param int $hint Encoding mode
* @param int $version Code version
*/
public function __construct($bsObj, $hint, $version)
{
$this->bsObj = $bsObj;
$this->items = array();
$this->hint = $hint;
$this->version = $version;
}
/**
* Split the input string
*
* @param string $data Data
*
* @return array items
*/
public function getSplittedString($data)
{
while (strlen($data) > 0) {
$mode = $this->bsObj->getEncodingMode($data, 0);
switch ($mode) {
case Data::$encodingModes['NM']:
$length = $this->eatNum($data);
break;
case Data::$encodingModes['AN']:
$length = $this->eatAn($data);
break;
case Data::$encodingModes['KJ']:
if ($this->hint == Data::$encodingModes['KJ']) {
$length = $this->eatKanji($data);
} else {
$length = $this->eat8($data);
}
break;
default:
$length = $this->eat8($data);
break;
}
if ($length == 0) {
break;
}
if ($length < 0) {
throw new BarcodeException('Error while splitting the input data');
}
$data = substr($data, $length);
}
return $this->items;
}
/**
* eatNum
*
* @param string $data Data
*
* @return int run
*/
protected function eatNum($data)
{
$lng = $this->bsObj->getLengthIndicator(Data::$encodingModes['NM']);
$pos = 0;
while ($this->bsObj->isDigitAt($data, $pos)) {
$pos++;
}
$mode = $this->bsObj->getEncodingMode($data, $pos);
if ($mode == Data::$encodingModes['8B']) {
$dif = $this->bsObj->estimateBitsModeNum($pos) + 4 + $lng
+ $this->bsObj->estimateBitsMode8(1) // + 4 + l8
- $this->bsObj->estimateBitsMode8($pos + 1); // - 4 - l8
if ($dif > 0) {
return $this->eat8($data);
}
}
if ($mode == Data::$encodingModes['AN']) {
$dif = $this->bsObj->estimateBitsModeNum($pos) + 4 + $lng
+ $this->bsObj->estimateBitsModeAn(1) // + 4 + la
- $this->bsObj->estimateBitsModeAn($pos + 1);// - 4 - la
if ($dif > 0) {
return $this->eatAn($data);
}
}
$this->items = $this->bsObj->appendNewInputItem(
$this->items,
Data::$encodingModes['NM'],
$pos,
str_split($data)
);
return $pos;
}
/**
* eatAn
*
* @param string $data Data
* @return int run
*/
protected function eatAn($data)
{
$lag = $this->bsObj->getLengthIndicator(Data::$encodingModes['AN']);
$lng = $this->bsObj->getLengthIndicator(Data::$encodingModes['NM']);
$pos =1 ;
while ($this->bsObj->isAlphanumericAt($data, $pos)) {
if ($this->bsObj->isDigitAt($data, $pos)) {
$qix = $pos;
while ($this->bsObj->isDigitAt($data, $qix)) {
$qix++;
}
$dif = $this->bsObj->estimateBitsModeAn($pos) // + 4 + lag
+ $this->bsObj->estimateBitsModeNum($qix - $pos) + 4 + $lng
- $this->bsObj->estimateBitsModeAn($qix); // - 4 - la
if ($dif < 0) {
break;
} else {
$pos = $qix;
}
} else {
$pos++;
}
}
if (!$this->bsObj->isAlphanumericAt($data, $pos)) {
$dif = $this->bsObj->estimateBitsModeAn($pos) + 4 + $lag
+ $this->bsObj->estimateBitsMode8(1) // + 4 + l8
- $this->bsObj->estimateBitsMode8($pos + 1); // - 4 - l8
if ($dif > 0) {
return $this->eat8($data);
}
}
$this->items = $this->bsObj->appendNewInputItem(
$this->items,
Data::$encodingModes['AN'],
$pos,
str_split($data)
);
return $pos;
}
/**
* eatKanji
*
* @param string $data Data
* @return int run
*/
protected function eatKanji($data)
{
$pos = 0;
while ($this->bsObj->getEncodingMode($data, $pos) == Data::$encodingModes['KJ']) {
$pos += 2;
}
$this->items = $this->bsObj->appendNewInputItem(
$this->items,
Data::$encodingModes['KJ'],
$pos,
str_split($data)
);
return $pos;
}
/**
* eat8
*
* @param string $data Data
* @return int run
*/
protected function eat8($data)
{
$lag = $this->bsObj->getLengthIndicator(Data::$encodingModes['AN']);
$lng = $this->bsObj->getLengthIndicator(Data::$encodingModes['NM']);
$pos = 1;
$dataStrLen = strlen($data);
while ($pos < $dataStrLen) {
$mode = $this->bsObj->getEncodingMode($data, $pos);
if ($mode == Data::$encodingModes['KJ']) {
break;
}
if ($mode == Data::$encodingModes['NM']) {
$qix = $pos;
while ($this->bsObj->isDigitAt($data, $qix)) {
$qix++;
}
$dif = $this->bsObj->estimateBitsMode8($pos) // + 4 + l8
+ $this->bsObj->estimateBitsModeNum($qix - $pos) + 4 + $lng
- $this->bsObj->estimateBitsMode8($qix); // - 4 - l8
if ($dif < 0) {
break;
} else {
$pos = $qix;
}
} elseif ($mode == Data::$encodingModes['AN']) {
$qix = $pos;
while ($this->bsObj->isAlphanumericAt($data, $qix)) {
$qix++;
}
$dif = $this->bsObj->estimateBitsMode8($pos) // + 4 + l8
+ $this->bsObj->estimateBitsModeAn($qix - $pos) + 4 + $lag
- $this->bsObj->estimateBitsMode8($qix); // - 4 - l8
if ($dif < 0) {
break;
} else {
$pos = $qix;
}
} else {
$pos++;
}
}
$this->items = $this->bsObj->appendNewInputItem(
$this->items,
Data::$encodingModes['8B'],
$pos,
str_split($data)
);
return $pos;
}
}