83if (!defined(
'QRCODEDEFS')) {
88 define(
'QRCODEDEFS',
true);
97 define(
'QR_MODE_NL', -1);
102 define(
'QR_MODE_NM', 0);
107 define(
'QR_MODE_AN', 1);
112 define(
'QR_MODE_8B', 2);
117 define(
'QR_MODE_KJ', 3);
122 define(
'QR_MODE_ST', 4);
133 define(
'QR_ECLEVEL_L', 0);
138 define(
'QR_ECLEVEL_M', 1);
143 define(
'QR_ECLEVEL_Q', 2);
148 define(
'QR_ECLEVEL_H', 3);
160 define(
'QRSPEC_VERSION_MAX', 40);
165 define(
'QRSPEC_WIDTH_MAX', 177);
172 define(
'QRCAP_WIDTH', 0);
177 define(
'QRCAP_WORDS', 1);
182 define(
'QRCAP_REMINDER', 2);
187 define(
'QRCAP_EC', 3);
196 define(
'STRUCTURE_HEADER_BITS', 20);
201 define(
'MAX_STRUCTURED_SYMBOLS', 16);
234 define(
'QR_FIND_BEST_MASK',
true);
239 define(
'QR_FIND_FROM_RANDOM', 2);
244 define(
'QR_DEFAULT_MASK', 2);
253if (!function_exists(
'str_split')) {
260 function str_split($string, $split_length=1) {
261 if ((strlen($string) > $split_length) OR (!$split_length)) {
263 $c = strlen($string);
264 $parts[] = substr($string, 0, $split_length);
265 $string = substr($string, $split_length);
266 }
while ($string !==
false);
268 $parts = array($string);
464 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
465 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
466 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
467 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
468 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
469 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
470 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
471 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
480 array( 0, 0, 0, array( 0, 0, 0, 0)),
481 array( 21, 26, 0, array( 7, 10, 13, 17)),
482 array( 25, 44, 7, array( 10, 16, 22, 28)),
483 array( 29, 70, 7, array( 15, 26, 36, 44)),
484 array( 33, 100, 7, array( 20, 36, 52, 64)),
485 array( 37, 134, 7, array( 26, 48, 72, 88)),
486 array( 41, 172, 7, array( 36, 64, 96, 112)),
487 array( 45, 196, 0, array( 40, 72, 108, 130)),
488 array( 49, 242, 0, array( 48, 88, 132, 156)),
489 array( 53, 292, 0, array( 60, 110, 160, 192)),
490 array( 57, 346, 0, array( 72, 130, 192, 224)),
491 array( 61, 404, 0, array( 80, 150, 224, 264)),
492 array( 65, 466, 0, array( 96, 176, 260, 308)),
493 array( 69, 532, 0, array( 104, 198, 288, 352)),
494 array( 73, 581, 3, array( 120, 216, 320, 384)),
495 array( 77, 655, 3, array( 132, 240, 360, 432)),
496 array( 81, 733, 3, array( 144, 280, 408, 480)),
497 array( 85, 815, 3, array( 168, 308, 448, 532)),
498 array( 89, 901, 3, array( 180, 338, 504, 588)),
499 array( 93, 991, 3, array( 196, 364, 546, 650)),
500 array( 97, 1085, 3, array( 224, 416, 600, 700)),
501 array(101, 1156, 4, array( 224, 442, 644, 750)),
502 array(105, 1258, 4, array( 252, 476, 690, 816)),
503 array(109, 1364, 4, array( 270, 504, 750, 900)),
504 array(113, 1474, 4, array( 300, 560, 810, 960)),
505 array(117, 1588, 4, array( 312, 588, 870, 1050)),
506 array(121, 1706, 4, array( 336, 644, 952, 1110)),
507 array(125, 1828, 4, array( 360, 700, 1020, 1200)),
508 array(129, 1921, 3, array( 390, 728, 1050, 1260)),
509 array(133, 2051, 3, array( 420, 784, 1140, 1350)),
510 array(137, 2185, 3, array( 450, 812, 1200, 1440)),
511 array(141, 2323, 3, array( 480, 868, 1290, 1530)),
512 array(145, 2465, 3, array( 510, 924, 1350, 1620)),
513 array(149, 2611, 3, array( 540, 980, 1440, 1710)),
514 array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
515 array(157, 2876, 0, array( 570, 1064, 1590, 1890)),
516 array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
517 array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
518 array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
519 array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
520 array(177, 3706, 0, array( 750, 1372, 2040, 2430))
540 array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)),
541 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),
542 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),
543 array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)),
544 array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)),
545 array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)),
546 array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)),
547 array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)),
548 array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)),
549 array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)),
550 array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)),
551 array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)),
552 array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)),
553 array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)),
554 array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)),
555 array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)),
556 array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)),
557 array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)),
558 array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)),
559 array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)),
560 array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)),
561 array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)),
562 array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)),
563 array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)),
564 array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)),
565 array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)),
566 array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
567 array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)),
568 array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
569 array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)),
570 array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)),
571 array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)),
572 array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)),
573 array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),
574 array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)),
575 array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)),
576 array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
577 array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)),
578 array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
579 array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),
580 array(array(19, 6), array(18, 31), array(34, 34), array(20, 61))
591 array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0),
592 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50),
593 array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48),
594 array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62),
595 array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58),
596 array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52),
597 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54),
598 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58)
608 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
609 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
610 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
611 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
620 array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
621 array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
622 array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
623 array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
645 $this->level = array_search($eclevel, array(
'L',
'M',
'Q',
'H'));
646 if ($this->level ===
false) {
647 $this->level = QR_ECLEVEL_L;
649 if (($this->hint != QR_MODE_8B) AND ($this->hint != QR_MODE_KJ)) {
652 if (($this->version < 0) OR ($this->version > QRSPEC_VERSION_MAX)) {
655 $this->items = array();
657 if (is_null($this->data)) {
660 $qrTab = $this->
binarize($this->data);
661 $size = count($qrTab);
665 foreach ($qrTab as $line) {
667 foreach (str_split($line) as $char) {
668 $arrAdd[] = ($char==
'1')?1:0;
692 foreach (
$frame as &$frameLine) {
693 for ($i=0; $i<$len; $i++) {
694 $frameLine[$i] = (ord($frameLine[$i])&1)?
'1':
'0';
705 $this->dataStr = $string;
706 if (!$this->casesensitive) {
721 $spec = array(0, 0, 0, 0, 0);
724 if (is_null($this->datacode)) {
727 $spec = $this->
getEccSpec($this->version, $this->level, $spec);
731 $this->ecccode = array_fill(0, $this->eccLength, 0);
738 $this->width = $this->
getWidth($this->version);
739 $this->frame = $this->
newFrame($this->version);
740 $this->x = $this->width - 1;
741 $this->y = $this->width - 1;
748 for ($j=0; $j<8; $j++) {
756 for ($i=0; $i<$j; $i++) {
761 $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
763 if (QR_FIND_BEST_MASK) {
764 $masked = $this->
mask($this->width, $this->frame, $this->level);
766 $masked = $this->
makeMask($this->width, $this->frame, (intval(QR_DEFAULT_MASK) % 8), $this->level);
769 $masked = $this->
makeMask($this->width, $this->frame,
$mask, $this->level);
771 if ($masked == NULL) {
774 $this->data = $masked;
787 $this->frame[$at[
'y']][$at[
'x']] = chr($val);
796 return ord($this->frame[$at[
'y']][$at[
'x']]);
805 if ($this->bit == -1) {
807 return array(
'x'=>$this->x,
'y'=>$this->y);
812 if ($this->bit == 0) {
820 if ($this->dir < 0) {
841 if ((
$x < 0) OR (
$y < 0)) {
846 }
while(ord($this->frame[
$y][
$x]) & 0x80);
847 return array(
'x'=>
$x,
'y'=>
$y);
859 protected function init($spec) {
862 $rs = $this->
init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
867 for ($i=0; $i < $endfor; ++$i) {
868 $ecc = array_slice($this->ecccode, $eccPos);
869 $this->rsblocks[$blockNo] = array();
870 $this->rsblocks[$blockNo][
'dataLength'] = $dl;
871 $this->rsblocks[$blockNo][
'data'] = array_slice($this->datacode, $dataPos);
872 $this->rsblocks[$blockNo][
'eccLength'] = $el;
873 $ecc = $this->
encode_rs_char($rs, $this->rsblocks[$blockNo][
'data'], $ecc);
874 $this->rsblocks[$blockNo][
'ecc'] = $ecc;
875 $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
885 $rs = $this->
init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
890 for ($i=0; $i < $endfor; ++$i) {
891 $ecc = array_slice($this->ecccode, $eccPos);
892 $this->rsblocks[$blockNo] = array();
893 $this->rsblocks[$blockNo][
'dataLength'] = $dl;
894 $this->rsblocks[$blockNo][
'data'] = array_slice($this->datacode, $dataPos);
895 $this->rsblocks[$blockNo][
'eccLength'] = $el;
896 $ecc = $this->
encode_rs_char($rs, $this->rsblocks[$blockNo][
'data'], $ecc);
897 $this->rsblocks[$blockNo][
'ecc'] = $ecc;
898 $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc);
911 if ($this->count < $this->dataLength) {
914 if ($col >= $this->rsblocks[0][
'dataLength']) {
917 $ret = $this->rsblocks[
$row][
'data'][$col];
918 } elseif ($this->count < $this->dataLength + $this->eccLength) {
921 $ret = $this->rsblocks[
$row][
'ecc'][$col];
944 for ($i=0; $i<8; ++$i) {
955 $frame[$i + 1][8] = chr($v);
957 $format = $format >> 1;
959 for ($i=0; $i<7; ++$i) {
970 $frame[8][6 - $i] = chr($v);
972 $format = $format >> 1;
984 return (
$x +
$y) & 1;
1014 return (
$x +
$y) % 3;
1024 return (((
int)(
$y / 2)) + ((
int)(
$x / 3))) & 1;
1034 return ((
$x *
$y) & 1) + (
$x *
$y) % 3;
1044 return (((
$x *
$y) & 1) + (
$x *
$y) % 3) & 1;
1054 return (((
$x *
$y) % 3) + ((
$x +
$y) & 1)) & 1;
1065 $bitMask = array_fill(0,
$width, array_fill(0,
$width, 0));
1069 $bitMask[
$y][
$x] = 0;
1071 $maskFunc = call_user_func(array($this,
'mask'.$maskNo),
$x,
$y);
1072 $bitMask[
$y][
$x] = ($maskFunc == 0)?1:0;
1098 if ($bitMask[
$y][
$x] == 1) {
1101 $b += (int)(ord(
$d[
$y][
$x]) & 1);
1116 $masked = array_fill(0,
$width, str_repeat(
"\0",
$width));
1129 for ($i=0; $i<$length; ++$i) {
1130 if ($this->runLength[$i] >= 5) {
1131 $demerit += (N1 + ($this->runLength[$i] - 5));
1134 if (($i >= 3) AND ($i < ($length-2)) AND ($this->runLength[$i] % 3 == 0)) {
1135 $fact = (int)($this->runLength[$i] / 3);
1136 if (($this->runLength[$i-2] == $fact)
1137 AND ($this->runLength[$i-1] == $fact)
1138 AND ($this->runLength[$i+1] == $fact)
1139 AND ($this->runLength[$i+2] == $fact)) {
1140 if (($this->runLength[$i-3] < 0) OR ($this->runLength[$i-3] >= (4 * $fact))) {
1142 } elseif ((($i+3) >= $length) OR ($this->runLength[$i+3] >= (4 * $fact))) {
1163 $this->runLength[0] = 1;
1169 if ((
$x > 0) AND (
$y > 0)) {
1170 $b22 = ord($frameY[
$x]) & ord($frameY[
$x-1]) & ord($frameYM[
$x]) & ord($frameYM[
$x-1]);
1171 $w22 = ord($frameY[
$x]) | ord($frameY[
$x-1]) | ord($frameYM[
$x]) | ord($frameYM[
$x-1]);
1172 if (($b22 | ($w22 ^ 1)) & 1) {
1176 if ((
$x == 0) AND (ord($frameY[
$x]) & 1)) {
1177 $this->runLength[0] = -1;
1179 $this->runLength[$head] = 1;
1181 if ((ord($frameY[
$x]) ^ ord($frameY[
$x-1])) & 1) {
1183 $this->runLength[$head] = 1;
1185 $this->runLength[$head]++;
1189 $demerit += $this->
calcN1N3($head+1);
1193 $this->runLength[0] = 1;
1196 $this->runLength[0] = -1;
1198 $this->runLength[$head] = 1;
1202 $this->runLength[$head] = 1;
1204 $this->runLength[$head]++;
1208 $demerit += $this->
calcN1N3($head+1);
1221 $minDemerit = PHP_INT_MAX;
1223 $bestMask = array();
1224 $checked_masks = array(0, 1, 2, 3, 4, 5, 6, 7);
1225 if (QR_FIND_FROM_RANDOM !==
false) {
1226 $howManuOut = 8 - (QR_FIND_FROM_RANDOM % 9);
1227 for ($i = 0; $i < $howManuOut; ++$i) {
1228 $remPos = rand (0, count($checked_masks)-1);
1229 unset($checked_masks[$remPos]);
1230 $checked_masks = array_values($checked_masks);
1234 foreach ($checked_masks as $i) {
1241 $demerit = (int)((
int)(abs($blacks - 50) / 5) * N4);
1243 if ($demerit < $minDemerit) {
1244 $minDemerit = $demerit;
1263 if ($pos >= strlen($str)) {
1266 return ((ord($str[$pos]) >= ord(
'0'))&&(ord($str[$pos]) <= ord(
'9')));
1276 if ($pos >= strlen($str)) {
1279 return ($this->
lookAnTable(ord($str[$pos])) >= 0);
1288 if ($pos >= strlen($this->dataStr)) {
1291 $c = $this->dataStr[$pos];
1292 if ($this->
isdigitat($this->dataStr, $pos)) {
1294 } elseif ($this->
isalnumat($this->dataStr, $pos)) {
1296 } elseif ($this->hint == QR_MODE_KJ) {
1297 if ($pos+1 < strlen($this->dataStr)) {
1298 $d = $this->dataStr[$pos+1];
1299 $word = (ord($c) << 8) | ord(
$d);
1300 if (($word >= 0x8140 && $word <= 0x9ffc) OR ($word >= 0xe040 && $word <= 0xebbf)) {
1315 while($this->
isdigitat($this->dataStr, $p)) {
1320 if ($mode == QR_MODE_8B) {
1325 return $this->
eat8();
1328 if ($mode == QR_MODE_AN) {
1333 return $this->
eatAn();
1336 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_NM, $run, str_split($this->dataStr));
1348 while($this->
isalnumat($this->dataStr, $p)) {
1349 if ($this->
isdigitat($this->dataStr, $p)) {
1351 while($this->
isdigitat($this->dataStr, $q)) {
1367 if (!$this->
isalnumat($this->dataStr, $p)) {
1372 return $this->
eat8();
1375 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_AN, $run, str_split($this->dataStr));
1388 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_KJ, $p, str_split($this->dataStr));
1400 $dataStrLen = strlen($this->dataStr);
1401 while($p < $dataStrLen) {
1403 if ($mode == QR_MODE_KJ) {
1406 if ($mode == QR_MODE_NM) {
1408 while($this->
isdigitat($this->dataStr, $q)) {
1419 } elseif ($mode == QR_MODE_AN) {
1421 while($this->
isalnumat($this->dataStr, $q)) {
1437 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_8B, $run, str_split($this->dataStr));
1446 while (strlen($this->dataStr) > 0) {
1450 $length = $this->
eatNum();
1454 $length = $this->
eatAn();
1458 if (
$hint == QR_MODE_KJ) {
1461 $length = $this->
eat8();
1466 $length = $this->
eat8();
1476 $this->dataStr = substr($this->dataStr, $length);
1485 $stringLen = strlen($this->dataStr);
1487 while ($p < $stringLen) {
1488 $mode = $this->
identifyMode(substr($this->dataStr, $p), $this->hint);
1489 if ($mode == QR_MODE_KJ) {
1492 if ((ord($this->dataStr[$p]) >= ord(
'a')) AND (ord($this->dataStr[$p]) <= ord(
'z'))) {
1493 $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
1515 if (count($setData) <
$size) {
1516 $setData = array_merge($setData, array_fill(0, (
$size - count($setData)), 0));
1521 $inputitem = array();
1522 $inputitem[
'mode'] = $mode;
1523 $inputitem[
'size'] =
$size;
1524 $inputitem[
'data'] = $setData;
1525 $inputitem[
'bstream'] = $bstream;
1536 $words = (int)($inputitem[
'size'] / 3);
1537 $inputitem[
'bstream'] = array();
1539 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, $val);
1541 for ($i=0; $i < $words; ++$i) {
1542 $val = (ord($inputitem[
'data'][$i*3 ]) - ord(
'0')) * 100;
1543 $val += (ord($inputitem[
'data'][$i*3+1]) - ord(
'0')) * 10;
1544 $val += (ord($inputitem[
'data'][$i*3+2]) - ord(
'0'));
1545 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 10, $val);
1547 if ($inputitem[
'size'] - $words * 3 == 1) {
1548 $val = ord($inputitem[
'data'][$words*3]) - ord(
'0');
1549 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, $val);
1550 } elseif (($inputitem[
'size'] - ($words * 3)) == 2) {
1551 $val = (ord($inputitem[
'data'][$words*3 ]) - ord(
'0')) * 10;
1552 $val += (ord($inputitem[
'data'][$words*3+1]) - ord(
'0'));
1553 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 7, $val);
1565 $words = (int)($inputitem[
'size'] / 2);
1566 $inputitem[
'bstream'] = array();
1567 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x02);
1569 for ($i=0; $i < $words; ++$i) {
1570 $val = (int)($this->
lookAnTable(ord($inputitem[
'data'][$i*2])) * 45);
1571 $val += (int)($this->
lookAnTable(ord($inputitem[
'data'][($i*2)+1])));
1572 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 11, $val);
1574 if ($inputitem[
'size'] & 1) {
1575 $val = $this->
lookAnTable(ord($inputitem[
'data'][($words * 2)]));
1576 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 6, $val);
1588 $inputitem[
'bstream'] = array();
1589 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x4);
1591 for ($i=0; $i < $inputitem[
'size']; ++$i) {
1592 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 8, ord($inputitem[
'data'][$i]));
1604 $inputitem[
'bstream'] = array();
1605 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x8);
1607 for ($i=0; $i<$inputitem[
'size']; $i+=2) {
1608 $val = (ord($inputitem[
'data'][$i]) << 8) | ord($inputitem[
'data'][$i+1]);
1609 if ($val <= 0x9ffc) {
1614 $h = ($val >> 8) * 0xc0;
1615 $val = ($val & 0xff) +
$h;
1616 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 13, $val);
1627 $inputitem[
'bstream'] = array();
1628 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x03);
1629 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, ord($inputitem[
'data'][1]) - 1);
1630 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, ord($inputitem[
'data'][0]) - 1);
1631 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 8, ord($inputitem[
'data'][2]));
1642 $inputitem[
'bstream'] = array();
1644 if ($inputitem[
'size'] > $words) {
1645 $st1 = $this->
newInputItem($inputitem[
'mode'], $words, $inputitem[
'data']);
1646 $st2 = $this->
newInputItem($inputitem[
'mode'], $inputitem[
'size'] - $words, array_slice($inputitem[
'data'], $words));
1649 $inputitem[
'bstream'] = array();
1650 $inputitem[
'bstream'] = $this->
appendBitstream($inputitem[
'bstream'], $st1[
'bstream']);
1651 $inputitem[
'bstream'] = $this->
appendBitstream($inputitem[
'bstream'], $st2[
'bstream']);
1653 switch($inputitem[
'mode']) {
1698 if (!empty($newitem)) {
1713 if (
$size > MAX_STRUCTURED_SYMBOLS) {
1716 if (($index <= 0) OR ($index > MAX_STRUCTURED_SYMBOLS)) {
1719 $buf = array(
$size, $index, $parity);
1721 array_unshift(
$items, $entry);
1732 foreach (
$items as $item) {
1733 if ($item[
'mode'] != QR_MODE_ST) {
1734 for ($i=$item[
'size']-1; $i>=0; --$i) {
1735 $parity ^= $item[
'data'][$i];
1749 for ($i=0; $i<
$size; ++$i) {
1750 if ((ord(
$data[$i]) < ord(
'0')) OR (ord(
$data[$i]) > ord(
'9'))){
1763 return (($c > 127)?-1:$this->anTable[$c]);
1773 for ($i=0; $i<
$size; ++$i) {
1808 $bits = (int)(
$size * 5.5);
1821 return (
int)(
$size * 8);
1830 return (
int)(
$size * 6.5);
1843 for ($i=0; $i<
$size; $i+=2) {
1844 $val = (ord(
$data[$i]) << 8) | ord(
$data[$i+1]);
1845 if (($val < 0x8140) OR (($val > 0x9ffc) AND ($val < 0xe040)) OR ($val > 0xebbf)) {
1897 foreach (
$items as $item) {
1898 switch($item[
'mode']) {
1916 return STRUCTURE_HEADER_BITS;
1924 $num = (int)(($item[
'size'] + $m - 1) / $m);
1925 $bits += $num * (4 +
$l);
1960 $chunks = (int)($payload / 10);
1961 $remain = $payload - $chunks * 10;
1962 $size = $chunks * 3;
1965 } elseif ($remain >= 4) {
1971 $chunks = (int)($payload / 11);
1972 $remain = $payload - $chunks * 11;
1973 $size = $chunks * 2;
1980 $size = (int)($payload / 8);
1984 $size = (int)(($payload / 13) * 2);
1988 $size = (int)($payload / 8);
2000 if (
$size > $maxsize) {
2013 foreach (
$items as $key => $item) {
2015 $bits = count(
$items[$key][
'bstream']);
2028 if ($ver > $this->version) {
2029 $this->version = $ver;
2041 } elseif ($ver > $this->version) {
2042 $this->version = $ver;
2056 if (is_null($bstream)) {
2059 $bits = count($bstream);
2060 $maxwords = $this->
getDataLength($this->version, $this->level);
2061 $maxbits = $maxwords * 8;
2062 if ($maxbits == $bits) {
2065 if ($maxbits - $bits < 5) {
2066 return $this->
appendNum($bstream, $maxbits - $bits, 0);
2069 $words = (int)(($bits + 7) / 8);
2071 $padding = $this->
appendNum($padding, $words * 8 - $bits + 4, 0);
2072 $padlen = $maxwords - $words;
2075 for ($i=0; $i<$padlen; ++$i) {
2076 $padbuf[$i] = ($i&1)?0x11:0xec;
2078 $padding = $this->
appendBytes($padding, $padlen, $padbuf);
2094 foreach (
$items as $item) {
2130 return array_fill(0, $setLength, 0);
2141 $mask = 1 << ($bits - 1);
2142 for ($i=0; $i<$bits; ++$i) {
2162 for ($i=0; $i<
$size; ++$i) {
2164 for ($j=0; $j<8; ++$j) {
2184 if ((!is_array($append)) OR (count($append) == 0)) {
2187 if (count($bitstream) == 0) {
2190 return array_values(array_merge($bitstream, $append));
2229 if (is_null($bstream)) {
2232 $size = count($bstream);
2236 $data = array_fill(0, (
int)((
$size + 7) / 8), 0);
2237 $bytes = (int)(
$size / 8);
2239 for ($i=0; $i<$bytes; $i++) {
2241 for ($j=0; $j<8; $j++) {
2250 for ($j=0; $j<(
$size & 7); $j++) {
2274 $srctab[
$y] = substr_replace($srctab[
$y], ($replLen !==
false)?substr($repl,0,$replLen):$repl,
$x, ($replLen !==
false)?$replLen:strlen($repl));
2304 return $this->capacity[
$version][QRCAP_WIDTH];
2313 return $this->capacity[
$version][QRCAP_REMINDER];
2323 for ($i = 1; $i <= QRSPEC_VERSION_MAX; ++$i) {
2324 $words = ($this->capacity[$i][QRCAP_WORDS] - $this->capacity[$i][QRCAP_EC][
$level]);
2325 if ($words >=
$size) {
2340 if ($mode == QR_MODE_ST) {
2350 return $this->lengthTableBits[$mode][
$l];
2360 if ($mode == QR_MODE_ST) {
2370 $bits = $this->lengthTableBits[$mode][
$l];
2371 $words = (1 << $bits) - 1;
2372 if ($mode == QR_MODE_KJ) {
2386 if (count($spec) < 5) {
2387 $spec = array(0, 0, 0, 0, 0);
2396 $spec[2] = (int)($ecc /
$b1);
2401 $spec[1] = (int)(
$data / (
$b1 + $b2));
2402 $spec[2] = (int)($ecc / (
$b1 + $b2));
2404 $spec[4] = $spec[1] + 1;
2418 "\xa1\xa1\xa1\xa1\xa1",
2419 "\xa1\xa0\xa0\xa0\xa1",
2420 "\xa1\xa0\xa1\xa0\xa1",
2421 "\xa1\xa0\xa0\xa0\xa1",
2422 "\xa1\xa1\xa1\xa1\xa1"
2426 for (
$y=0;
$y < 5;
$y++) {
2449 if (
$w *
$w - 3 == 1) {
2455 $cx = $this->alignmentPattern[
$version][0];
2457 for (
$x=1;
$x < $wo; ++
$x) {
2462 $cy = $this->alignmentPattern[
$version][0];
2463 for (
$y=0;
$y < $wo; ++
$y) {
2464 $cx = $this->alignmentPattern[
$version][0];
2465 for (
$x=0;
$x < $wo; ++
$x) {
2483 return $this->versionPattern[(
$version - 7)];
2511 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
2512 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
2513 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
2514 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
2515 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
2516 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
2517 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
2519 for (
$y=0;
$y < 7;
$y++) {
2532 $frameLine = str_repeat (
"\0",
$width);
2540 for (
$y=0;
$y < 7; ++
$y) {
2543 $frame[$yOffset][7] =
"\xc0";
2546 $setPattern = str_repeat(
"\xc0", 8);
2551 $setPattern = str_repeat(
"\x84", 9);
2555 for (
$y=0;
$y < 8; ++
$y,++$yOffset) {
2557 $frame[$yOffset][8] =
"\x84";
2561 for ($i=1; $i < $wo; ++$i) {
2562 $frame[6][7+$i] = chr(0x90 | ($i & 1));
2563 $frame[7+$i][6] = chr(0x90 | ($i & 1));
2599 if (!isset($this->frames[
$version])) {
2602 if (is_null($this->frames[
$version])) {
2614 return ($spec[0] + $spec[3]);
2677 return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]);
2686 return ($spec[0] + $spec[3]) * $spec[2];
2703 protected function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) {
2704 foreach ($this->rsitems as $rs) {
2705 if (($rs[
'pad'] != $pad) OR ($rs[
'nroots'] != $nroots) OR ($rs[
'mm'] != $symsize)
2706 OR ($rs[
'gfpoly'] != $gfpoly) OR ($rs[
'fcr'] != $fcr) OR ($rs[
'prim'] != $prim)) {
2711 $rs = $this->
init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
2712 array_unshift($this->rsitems, $rs);
2727 while (
$x >= $rs[
'nn']) {
2729 $x = (
$x >> $rs[
'mm']) + (
$x & $rs[
'nn']);
2744 protected function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) {
2748 if (($symsize < 0) OR ($symsize > 8)) {
2751 if (($fcr < 0) OR ($fcr >= (1<<$symsize))) {
2754 if (($prim <= 0) OR ($prim >= (1<<$symsize))) {
2757 if (($nroots < 0) OR ($nroots >= (1<<$symsize))) {
2760 if (($pad < 0) OR ($pad >= ((1<<$symsize) -1 - $nroots))) {
2764 $rs[
'mm'] = $symsize;
2765 $rs[
'nn'] = (1 << $symsize) - 1;
2767 $rs[
'alpha_to'] = array_fill(0, ($rs[
'nn'] + 1), 0);
2768 $rs[
'index_of'] = array_fill(0, ($rs[
'nn'] + 1), 0);
2773 $rs[
'index_of'][0] = $A0;
2774 $rs[
'alpha_to'][$A0] = 0;
2776 for ($i=0; $i<$rs[
'nn']; ++$i) {
2777 $rs[
'index_of'][$sr] = $i;
2778 $rs[
'alpha_to'][$i] = $sr;
2780 if ($sr & (1 << $symsize)) {
2790 $rs[
'genpoly'] = array_fill(0, ($nroots + 1), 0);
2792 $rs[
'prim'] = $prim;
2793 $rs[
'nroots'] = $nroots;
2794 $rs[
'gfpoly'] = $gfpoly;
2796 for ($iprim=1; ($iprim % $prim) != 0; $iprim += $rs[
'nn']) {
2799 $rs[
'iprim'] = (int)($iprim / $prim);
2800 $rs[
'genpoly'][0] = 1;
2801 for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {
2802 $rs[
'genpoly'][$i+1] = 1;
2804 for ($j = $i; $j > 0; --$j) {
2805 if ($rs[
'genpoly'][$j] != 0) {
2806 $rs[
'genpoly'][$j] = $rs[
'genpoly'][$j-1] ^ $rs[
'alpha_to'][$this->
modnn($rs, $rs[
'index_of'][$rs[
'genpoly'][$j]] + $root)];
2808 $rs[
'genpoly'][$j] = $rs[
'genpoly'][$j-1];
2812 $rs[
'genpoly'][0] = $rs[
'alpha_to'][$this->
modnn($rs, $rs[
'index_of'][$rs[
'genpoly'][0]] + $root)];
2815 for ($i = 0; $i <= $nroots; ++$i) {
2816 $rs[
'genpoly'][$i] = $rs[
'index_of'][$rs[
'genpoly'][$i]];
2831 $ALPHA_TO =& $rs[
'alpha_to'];
2832 $INDEX_OF =& $rs[
'index_of'];
2833 $GENPOLY =& $rs[
'genpoly'];
2834 $NROOTS =& $rs[
'nroots'];
2836 $PRIM =& $rs[
'prim'];
2837 $IPRIM =& $rs[
'iprim'];
2840 $parity = array_fill(0, $NROOTS, 0);
2841 for ($i=0; $i < ($NN - $NROOTS - $PAD); $i++) {
2842 $feedback = $INDEX_OF[
$data[$i] ^ $parity[0]];
2843 if ($feedback != $A0) {
2847 $feedback = $this->
modnn($rs, $NN - $GENPOLY[$NROOTS] + $feedback);
2848 for ($j=1; $j < $NROOTS; ++$j) {
2849 $parity[$j] ^= $ALPHA_TO[$this->
modnn($rs, $feedback + $GENPOLY[($NROOTS - $j)])];
2853 array_shift($parity);
2854 if ($feedback != $A0) {
2855 array_push($parity, $ALPHA_TO[$this->
modnn($rs, $feedback + $GENPOLY[0])]);
2857 array_push($parity, 0);
Class to create QR-code arrays for TCPDF class.
lookAnTable($c)
Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19).
getFormatInfo($mask, $level)
Return BCH encoded format information pattern.
$eccTable
Array Table of the error correction code (Reed-Solomon block).
getByteStream($items)
Pack all bit streams padding bits into a byte array.
$level
Levels of error correction.
$anTable
Alphabet-numeric convesion table.
putAlignmentMarker($frame, $ox, $oy)
Put an alignment marker.
getEccSpec($version, $level, $spec)
Return an array of ECC specification.
isalnumat($str, $pos)
Return true if the character at specified position is an alphanumeric character.
$capacity
Array Table of the capacity of symbols.
encode_rs_char($rs, $data, $parity)
Encode a Reed-Solomon codec and returns the parity array.
estimateBitsMode8($size)
estimateBitsMode8
bitstreamToByte($bstream)
Convert bitstream to bytes.
estimateBitsModeAn($size)
estimateBitsModeAn
estimateVersion($items)
estimateVersion
setFrameAt($at, $val)
Set frame value at specified position.
lengthOfCode($mode, $version, $bits)
lengthOfCode
rsBlockNum($spec)
Return block number 0.
$rsitems
Reed-Solomon items.
identifyMode($pos)
identifyMode
$eccLength
Error correction length.
getDataLength($version, $level)
Return maximum data code length (bytes) for the version.
putFinderPattern($frame, $ox, $oy)
Put a finder pattern.
calcN1N3($length)
calcN1N3
appendBytes($bitstream, $size, $data)
Append one bitstream created from bytes to another.
maximumWords($mode, $version)
Return the maximum length for the mode and version.
rsBlockNum2($spec)
Return block number 2.
checkModeAn($size, $data)
checkModeAn
$alignmentPattern
Array Positions of alignment patterns.
__construct($code, $eclevel='L')
This is the class constructor.
allocate($setLength)
Return an array with zeros.
makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly=false)
makeMaskNo
$rsblocks
Reed-Solomon blocks.
rsEccCodes2($spec)
Return ecc codes 2.
encodeModeStructure($inputitem)
encodeModeStructure
convertData($items)
convertData
encodeMask($mask)
Encode mask.
estimateBitsModeNum($size)
estimateBitsModeNum
$dataStr
Input data string.
rsEccLength($spec)
Return ecc length.
$formatInfo
Array Format information.
createFrame($version)
Return a copy of initialized frame.
binarize($frame)
Convert the frame in binary form.
putAlignmentPattern($version, $frame, $width)
Put an alignment pattern.
mask($width, $frame, $level)
mask
estimateBitStreamSize($items, $version)
estimateBitStreamSize
getMinimumVersion($size, $level)
Return a version number that satisfies the input code length.
encodeModeAn($inputitem, $version)
encodeModeAn
getVersionPattern($version)
Return BCH encoded version information pattern that is used for the symbol of version 7 or greater.
encodeMode8($inputitem, $version)
encodeMode8
rsEccCodes1($spec)
Return ecc codes 1.
mergeBitStream($items)
mergeBitStream
encodeModeNum($inputitem, $version)
encodeModeNum
getECCLength($version, $level)
Return maximum error correction code length (bytes) for the version.
newInputItem($mode, $size, $data, $bstream=null)
newInputItem
lengthIndicator($mode, $version)
Return the size of length indicator for the mode and version.
appendNewInputItem($items, $mode, $size, $data)
Append data to an input object.
$lengthTableBits
Array Length indicator.
$casesensitive
Boolean flag, if true the input string will be converted to uppercase.
insertStructuredAppendHeader($items, $size, $index, $parity)
insertStructuredAppendHeader
evaluateSymbol($width, $frame)
evaluateSymbol
getNextPosition()
Return the next frame position.
$ecccode
Error correction code.
isdigitat($str, $pos)
Return true if the character at specified position is a number.
check($mode, $size, $data)
Validate the input data.
calcParity($items)
calcParity
getCode()
Return Reed-Solomon block code.
newFromBytes($size, $data)
Return new bitstream from bytes.
checkModeNum($size, $data)
checkModeNum
encodeBitStream($inputitem, $version)
encodeBitStream
newFrame($version)
Set new frame for the specified version.
$structured
Structured QR code (not supported yet).
rsDataCodes2($spec)
Return data codes 2.
encodeModeKanji($inputitem, $version)
encodeModeKanji
estimateBitsModeKanji($size)
estimateBitsModeKanji
getFrameAt($at)
Get frame value at specified position.
writeFormatInformation($width, &$frame, $mask, $level)
Write Format Information on frame and returns the number of black bits.
init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
Initialize a Reed-Solomon codec and add it to existing rsitems.
getWidth($version)
Return the width of the symbol for the version.
appendBitstream($bitstream, $append)
Append one bitstream to another.
qrstrset($srctab, $x, $y, $repl, $replLen=false)
Replace a value on the array at the specified position.
getRemainder($version)
Return the numer of remainder bits.
rsDataCodes1($spec)
Return data codes 1.
rsDataLength($spec)
Return data length.
appendPaddingBit($bstream)
Append Padding Bit to bitstream.
rsBlockNum1($spec)
Return block number 1.
$barcode_array
Barcode array to be returned which is readable by TCPDF.
$versionPattern
Array Version information pattern (BCH coded).
makeMask($width, $frame, $maskNo, $level)
makeMask
generateMaskNo($maskNo, $width, $frame)
Return bitmask.
createBitStream($items)
createBitStream
init($spec)
Initialize code.
appendNum($bitstream, $bits, $num)
Append one bitstream created from number to another.
checkModeKanji($size, $data)
checkModeKanji
getBitStream($items)
Returns a stream of bits.
getBarcodeArray()
Returns a barcode array which is readable by TCPDF.
init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
Initialize a Reed-Solomon codec and returns an array of values.
encodeString($string)
Encode the input string to QR code.
newFromNum($bits, $num)
Return new bitstream from number.