83 if (!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);
253 if (!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)
641 if ((is_null($code)) OR ($code ==
'\0') OR ($code ==
'')) {
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);
723 if (is_null($this->datacode)) {
726 $spec = $this->
getEccSpec($this->version, $this->level, $spec);
730 $this->ecccode = array_fill(0, $this->eccLength, 0);
737 $this->width = $this->
getWidth($this->version);
738 $this->frame = $this->
newFrame($this->version);
739 $this->x = $this->width - 1;
740 $this->y = $this->width - 1;
747 for ($j=0; $j<8; $j++) {
755 for ($i=0; $i<$j; $i++) {
760 $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
762 if (QR_FIND_BEST_MASK) {
763 $masked = $this->
mask($this->width, $this->frame, $this->level);
765 $masked = $this->
makeMask($this->width, $this->frame, (intval(QR_DEFAULT_MASK) % 8), $this->level);
768 $masked = $this->
makeMask($this->width, $this->frame, $mask, $this->level);
770 if ($masked == NULL) {
773 $this->data = $masked;
786 $this->frame[$at[
'y']][$at[
'x']] = chr($val);
795 return ord($this->frame[$at[
'y']][$at[
'x']]);
804 if ($this->bit == -1) {
806 return array(
'x'=>$this->x,
'y'=>$this->y);
811 if ($this->bit == 0) {
819 if ($this->dir < 0) {
840 if ((
$x < 0) OR (
$y < 0)) {
845 }
while(ord($this->frame[
$y][
$x]) & 0x80);
846 return array(
'x'=>$x,
'y'=>
$y);
858 protected function init($spec) {
861 $rs = $this->
init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
866 for ($i=0; $i < $endfor; ++$i) {
867 $ecc = array_slice($this->ecccode, $eccPos);
868 $this->rsblocks[$blockNo] = array();
869 $this->rsblocks[$blockNo][
'dataLength'] = $dl;
870 $this->rsblocks[$blockNo][
'data'] = array_slice($this->datacode, $dataPos);
871 $this->rsblocks[$blockNo][
'eccLength'] = $el;
872 $ecc = $this->
encode_rs_char($rs, $this->rsblocks[$blockNo][
'data'], $ecc);
873 $this->rsblocks[$blockNo][
'ecc'] = $ecc;
874 $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
884 $rs = $this->
init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
889 for ($i=0; $i < $endfor; ++$i) {
890 $ecc = array_slice($this->ecccode, $eccPos);
891 $this->rsblocks[$blockNo] = array();
892 $this->rsblocks[$blockNo][
'dataLength'] = $dl;
893 $this->rsblocks[$blockNo][
'data'] = array_slice($this->datacode, $dataPos);
894 $this->rsblocks[$blockNo][
'eccLength'] = $el;
895 $ecc = $this->
encode_rs_char($rs, $this->rsblocks[$blockNo][
'data'], $ecc);
896 $this->rsblocks[$blockNo][
'ecc'] = $ecc;
897 $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc);
910 if ($this->count < $this->dataLength) {
913 if ($col >= $this->rsblocks[0][
'dataLength']) {
916 $ret = $this->rsblocks[
$row][
'data'][$col];
917 } elseif ($this->count < $this->dataLength + $this->eccLength) {
920 $ret = $this->rsblocks[
$row][
'ecc'][$col];
943 for ($i=0; $i<8; ++$i) {
954 $frame[$i + 1][8] = chr($v);
956 $format = $format >> 1;
958 for ($i=0; $i<7; ++$i) {
969 $frame[8][6 - $i] = chr($v);
971 $format = $format >> 1;
983 return (
$x +
$y) & 1;
1013 return (
$x +
$y) % 3;
1023 return (((
int)(
$y / 2)) + ((
int)(
$x / 3))) & 1;
1033 return ((
$x *
$y) & 1) + (
$x *
$y) % 3;
1043 return (((
$x *
$y) & 1) + (
$x * $y) % 3) & 1;
1053 return (((
$x *
$y) % 3) + ((
$x + $y) & 1)) & 1;
1064 $bitMask = array_fill(0,
$width, array_fill(0,
$width, 0));
1068 $bitMask[
$y][
$x] = 0;
1070 $maskFunc = call_user_func(array($this,
'mask'.$maskNo), $x,
$y);
1071 $bitMask[
$y][
$x] = ($maskFunc == 0)?1:0;
1097 if ($bitMask[
$y][
$x] == 1) {
1098 $d[
$y][
$x] = chr(ord($s[
$y][
$x]) ^ ((
int)($bitMask[
$y][$x])));
1100 $b += (int)(ord(
$d[
$y][
$x]) & 1);
1115 $masked = array_fill(0,
$width, str_repeat(
"\0",
$width));
1128 for ($i=0; $i<$length; ++$i) {
1129 if ($this->runLength[$i] >= 5) {
1130 $demerit += (N1 + ($this->runLength[$i] - 5));
1133 if (($i >= 3) AND ($i < ($length-2)) AND ($this->runLength[$i] % 3 == 0)) {
1134 $fact = (int)($this->runLength[$i] / 3);
1135 if (($this->runLength[$i-2] == $fact)
1136 AND ($this->runLength[$i-1] == $fact)
1137 AND ($this->runLength[$i+1] == $fact)
1138 AND ($this->runLength[$i+2] == $fact)) {
1139 if (($this->runLength[$i-3] < 0) OR ($this->runLength[$i-3] >= (4 * $fact))) {
1141 } elseif ((($i+3) >= $length) OR ($this->runLength[$i+3] >= (4 * $fact))) {
1162 $this->runLength[0] = 1;
1168 if ((
$x > 0) AND (
$y > 0)) {
1169 $b22 = ord($frameY[
$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
1170 $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
1171 if (($b22 | ($w22 ^ 1)) & 1) {
1175 if ((
$x == 0) AND (ord($frameY[
$x]) & 1)) {
1176 $this->runLength[0] = -1;
1178 $this->runLength[$head] = 1;
1180 if ((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
1182 $this->runLength[$head] = 1;
1184 $this->runLength[$head]++;
1188 $demerit += $this->
calcN1N3($head+1);
1192 $this->runLength[0] = 1;
1195 $this->runLength[0] = -1;
1197 $this->runLength[$head] = 1;
1201 $this->runLength[$head] = 1;
1203 $this->runLength[$head]++;
1207 $demerit += $this->
calcN1N3($head+1);
1220 $minDemerit = PHP_INT_MAX;
1222 $bestMask = array();
1223 $checked_masks = array(0, 1, 2, 3, 4, 5, 6, 7);
1224 if (QR_FIND_FROM_RANDOM !==
false) {
1225 $howManuOut = 8 - (QR_FIND_FROM_RANDOM % 9);
1226 for ($i = 0; $i < $howManuOut; ++$i) {
1227 $remPos = rand (0, count($checked_masks)-1);
1228 unset($checked_masks[$remPos]);
1229 $checked_masks = array_values($checked_masks);
1233 foreach ($checked_masks as $i) {
1234 $mask = array_fill(0,
$width, str_repeat(
"\0",
$width));
1240 $demerit = (int)((
int)(abs($blacks - 50) / 5) * N4);
1242 if ($demerit < $minDemerit) {
1243 $minDemerit = $demerit;
1262 if ($pos >= strlen($str)) {
1265 return ((ord($str[$pos]) >= ord(
'0'))&&(ord($str[$pos]) <= ord(
'9')));
1275 if ($pos >= strlen($str)) {
1278 return ($this->
lookAnTable(ord($str[$pos])) >= 0);
1287 if ($pos >= strlen($this->dataStr)) {
1290 $c = $this->dataStr[$pos];
1291 if ($this->
isdigitat($this->dataStr, $pos)) {
1293 } elseif ($this->
isalnumat($this->dataStr, $pos)) {
1295 } elseif ($this->hint == QR_MODE_KJ) {
1296 if ($pos+1 < strlen($this->dataStr)) {
1297 $d = $this->dataStr[$pos+1];
1298 $word = (ord($c) << 8) | ord(
$d);
1299 if (($word >= 0x8140 && $word <= 0x9ffc) OR ($word >= 0xe040 && $word <= 0xebbf)) {
1314 while($this->
isdigitat($this->dataStr, $p)) {
1319 if ($mode == QR_MODE_8B) {
1324 return $this->
eat8();
1327 if ($mode == QR_MODE_AN) {
1332 return $this->
eatAn();
1335 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_NM, $run, str_split($this->dataStr));
1347 while($this->
isalnumat($this->dataStr, $p)) {
1348 if ($this->
isdigitat($this->dataStr, $p)) {
1350 while($this->
isdigitat($this->dataStr, $q)) {
1366 if (!$this->
isalnumat($this->dataStr, $p)) {
1371 return $this->
eat8();
1374 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_AN, $run, str_split($this->dataStr));
1387 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_KJ, $p, str_split($this->dataStr));
1399 $dataStrLen = strlen($this->dataStr);
1400 while($p < $dataStrLen) {
1402 if ($mode == QR_MODE_KJ) {
1405 if ($mode == QR_MODE_NM) {
1407 while($this->
isdigitat($this->dataStr, $q)) {
1418 } elseif ($mode == QR_MODE_AN) {
1420 while($this->
isalnumat($this->dataStr, $q)) {
1436 $this->items = $this->
appendNewInputItem($this->items, QR_MODE_8B, $run, str_split($this->dataStr));
1445 while (strlen($this->dataStr) > 0) {
1449 $length = $this->
eatNum();
1453 $length = $this->
eatAn();
1457 if (
$hint == QR_MODE_KJ) {
1460 $length = $this->
eat8();
1465 $length = $this->
eat8();
1475 $this->dataStr = substr($this->dataStr, $length);
1484 $stringLen = strlen($this->dataStr);
1486 while ($p < $stringLen) {
1487 $mode = $this->
identifyMode(substr($this->dataStr, $p), $this->hint);
1488 if ($mode == QR_MODE_KJ) {
1491 if ((ord($this->dataStr[$p]) >= ord(
'a')) AND (ord($this->dataStr[$p]) <= ord(
'z'))) {
1492 $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
1514 if (count($setData) <
$size) {
1515 $setData = array_merge($setData, array_fill(0, (
$size - count($setData)), 0));
1520 $inputitem = array();
1521 $inputitem[
'mode'] = $mode;
1522 $inputitem[
'size'] =
$size;
1523 $inputitem[
'data'] = $setData;
1524 $inputitem[
'bstream'] = $bstream;
1535 $words = (int)($inputitem[
'size'] / 3);
1536 $inputitem[
'bstream'] = array();
1538 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, $val);
1540 for ($i=0; $i < $words; ++$i) {
1541 $val = (ord($inputitem[
'data'][$i*3 ]) - ord(
'0')) * 100;
1542 $val += (ord($inputitem[
'data'][$i*3+1]) - ord(
'0')) * 10;
1543 $val += (ord($inputitem[
'data'][$i*3+2]) - ord(
'0'));
1544 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 10, $val);
1546 if ($inputitem[
'size'] - $words * 3 == 1) {
1547 $val = ord($inputitem[
'data'][$words*3]) - ord(
'0');
1548 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, $val);
1549 } elseif (($inputitem[
'size'] - ($words * 3)) == 2) {
1550 $val = (ord($inputitem[
'data'][$words*3 ]) - ord(
'0')) * 10;
1551 $val += (ord($inputitem[
'data'][$words*3+1]) - ord(
'0'));
1552 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 7, $val);
1564 $words = (int)($inputitem[
'size'] / 2);
1565 $inputitem[
'bstream'] = array();
1566 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x02);
1568 for ($i=0; $i < $words; ++$i) {
1569 $val = (int)($this->
lookAnTable(ord($inputitem[
'data'][$i*2])) * 45);
1570 $val += (int)($this->
lookAnTable(ord($inputitem[
'data'][($i*2)+1])));
1571 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 11, $val);
1573 if ($inputitem[
'size'] & 1) {
1574 $val = $this->
lookAnTable(ord($inputitem[
'data'][($words * 2)]));
1575 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 6, $val);
1587 $inputitem[
'bstream'] = array();
1588 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x4);
1590 for ($i=0; $i < $inputitem[
'size']; ++$i) {
1591 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 8, ord($inputitem[
'data'][$i]));
1603 $inputitem[
'bstream'] = array();
1604 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x8);
1606 for ($i=0; $i<$inputitem[
'size']; $i+=2) {
1607 $val = (ord($inputitem[
'data'][$i]) << 8) | ord($inputitem[
'data'][$i+1]);
1608 if ($val <= 0x9ffc) {
1613 $h = ($val >> 8) * 0xc0;
1614 $val = ($val & 0xff) + $h;
1615 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 13, $val);
1626 $inputitem[
'bstream'] = array();
1627 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, 0x03);
1628 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, ord($inputitem[
'data'][1]) - 1);
1629 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 4, ord($inputitem[
'data'][0]) - 1);
1630 $inputitem[
'bstream'] = $this->
appendNum($inputitem[
'bstream'], 8, ord($inputitem[
'data'][2]));
1641 $inputitem[
'bstream'] = array();
1643 if ($inputitem[
'size'] > $words) {
1644 $st1 = $this->
newInputItem($inputitem[
'mode'], $words, $inputitem[
'data']);
1645 $st2 = $this->
newInputItem($inputitem[
'mode'], $inputitem[
'size'] - $words, array_slice($inputitem[
'data'], $words));
1648 $inputitem[
'bstream'] = array();
1649 $inputitem[
'bstream'] = $this->
appendBitstream($inputitem[
'bstream'], $st1[
'bstream']);
1650 $inputitem[
'bstream'] = $this->
appendBitstream($inputitem[
'bstream'], $st2[
'bstream']);
1652 switch($inputitem[
'mode']) {
1697 if (!empty($newitem)) {
1712 if (
$size > MAX_STRUCTURED_SYMBOLS) {
1715 if (($index <= 0) OR ($index > MAX_STRUCTURED_SYMBOLS)) {
1718 $buf = array(
$size, $index, $parity);
1720 array_unshift(
$items, $entry);
1731 foreach (
$items as $item) {
1732 if ($item[
'mode'] != QR_MODE_ST) {
1733 for ($i=$item[
'size']-1; $i>=0; --$i) {
1734 $parity ^= $item[
'data'][$i];
1748 for ($i=0; $i<
$size; ++$i) {
1749 if ((ord(
$data[$i]) < ord(
'0')) OR (ord(
$data[$i]) > ord(
'9'))){
1762 return (($c > 127)?-1:$this->anTable[$c]);
1772 for ($i=0; $i<
$size; ++$i) {
1786 $w = (int)(
$size / 3);
1788 switch(
$size - ($w * 3)) {
1807 $bits = (int)(
$size * 5.5);
1820 return (
int)(
$size * 8);
1829 return (
int)(
$size * 6.5);
1842 for ($i=0; $i<
$size; $i+=2) {
1843 $val = (ord(
$data[$i]) << 8) | ord(
$data[$i+1]);
1844 if (($val < 0x8140) OR (($val > 0x9ffc) AND ($val < 0xe040)) OR ($val > 0xebbf)) {
1896 foreach (
$items as $item) {
1897 switch($item[
'mode']) {
1915 return STRUCTURE_HEADER_BITS;
1923 $num = (int)(($item[
'size'] + $m - 1) / $m);
1924 $bits += $num * (4 + $l);
1959 $chunks = (int)($payload / 10);
1960 $remain = $payload - $chunks * 10;
1961 $size = $chunks * 3;
1964 } elseif ($remain >= 4) {
1970 $chunks = (int)($payload / 11);
1971 $remain = $payload - $chunks * 11;
1972 $size = $chunks * 2;
1979 $size = (int)($payload / 8);
1983 $size = (int)(($payload / 13) * 2);
1987 $size = (int)($payload / 8);
1999 if (
$size > $maxsize) {
2012 foreach (
$items as $key => $item) {
2014 $bits = count(
$items[$key][
'bstream']);
2027 if ($ver > $this->version) {
2028 $this->version = $ver;
2040 } elseif ($ver > $this->version) {
2041 $this->version = $ver;
2055 if (is_null($bstream)) {
2058 $bits = count($bstream);
2059 $maxwords = $this->
getDataLength($this->version, $this->level);
2060 $maxbits = $maxwords * 8;
2061 if ($maxbits == $bits) {
2064 if ($maxbits - $bits < 5) {
2065 return $this->
appendNum($bstream, $maxbits - $bits, 0);
2068 $words = (int)(($bits + 7) / 8);
2070 $padding = $this->
appendNum($padding, $words * 8 - $bits + 4, 0);
2071 $padlen = $maxwords - $words;
2074 for ($i=0; $i<$padlen; ++$i) {
2075 $padbuf[$i] = ($i&1)?0x11:0xec;
2077 $padding = $this->
appendBytes($padding, $padlen, $padbuf);
2093 foreach (
$items as $item) {
2129 return array_fill(0, $setLength, 0);
2140 $mask = 1 << ($bits - 1);
2141 for ($i=0; $i<$bits; ++$i) {
2161 for ($i=0; $i<
$size; ++$i) {
2163 for ($j=0; $j<8; ++$j) {
2164 if (
$data[$i] & $mask) {
2183 if ((!is_array($append)) OR (count($append) == 0)) {
2186 if (count($bitstream) == 0) {
2189 return array_values(array_merge($bitstream, $append));
2228 if (is_null($bstream)) {
2231 $size = count($bstream);
2235 $data = array_fill(0, (
int)((
$size + 7) / 8), 0);
2236 $bytes = (int)(
$size / 8);
2238 for ($i=0; $i<$bytes; $i++) {
2240 for ($j=0; $j<8; $j++) {
2249 for ($j=0; $j<(
$size & 7); $j++) {
2273 $srctab[
$y] = substr_replace($srctab[
$y], ($replLen !==
false)?substr($repl,0,$replLen):$repl,
$x, ($replLen !==
false)?$replLen:strlen($repl));
2303 return $this->capacity[
$version][QRCAP_WIDTH];
2312 return $this->capacity[
$version][QRCAP_REMINDER];
2322 for ($i = 1; $i <= QRSPEC_VERSION_MAX; ++$i) {
2323 $words = ($this->capacity[$i][QRCAP_WORDS] - $this->capacity[$i][QRCAP_EC][
$level]);
2324 if ($words >=
$size) {
2339 if ($mode == QR_MODE_ST) {
2349 return $this->lengthTableBits[$mode][$l];
2359 if ($mode == QR_MODE_ST) {
2369 $bits = $this->lengthTableBits[$mode][$l];
2370 $words = (1 << $bits) - 1;
2371 if ($mode == QR_MODE_KJ) {
2385 if (count($spec) < 5) {
2386 $spec = array(0, 0, 0, 0, 0);
2395 $spec[2] = (int)($ecc /
$b1);
2400 $spec[1] = (int)(
$data / (
$b1 + $b2));
2401 $spec[2] = (int)($ecc / (
$b1 + $b2));
2403 $spec[4] = $spec[1] + 1;
2417 "\xa1\xa1\xa1\xa1\xa1",
2418 "\xa1\xa0\xa0\xa0\xa1",
2419 "\xa1\xa0\xa1\xa0\xa1",
2420 "\xa1\xa0\xa0\xa0\xa1",
2421 "\xa1\xa1\xa1\xa1\xa1"
2425 for (
$y=0;
$y < 5;
$y++) {
2448 if ($w * $w - 3 == 1) {
2454 $cx = $this->alignmentPattern[
$version][0];
2456 for (
$x=1;
$x < $wo; ++
$x) {
2461 $cy = $this->alignmentPattern[
$version][0];
2462 for (
$y=0;
$y < $wo; ++
$y) {
2463 $cx = $this->alignmentPattern[
$version][0];
2464 for (
$x=0;
$x < $wo; ++
$x) {
2482 return $this->versionPattern[(
$version - 7)];
2492 if (($mask < 0) OR ($mask > 7)) {
2498 return $this->formatInfo[
$level][$mask];
2510 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
2511 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
2512 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
2513 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
2514 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
2515 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
2516 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
2518 for (
$y=0;
$y < 7;
$y++) {
2531 $frameLine = str_repeat (
"\0",
$width);
2539 for (
$y=0;
$y < 7; ++
$y) {
2542 $frame[$yOffset][7] =
"\xc0";
2545 $setPattern = str_repeat(
"\xc0", 8);
2550 $setPattern = str_repeat(
"\x84", 9);
2554 for (
$y=0;
$y < 8; ++
$y,++$yOffset) {
2556 $frame[$yOffset][8] =
"\x84";
2560 for ($i=1; $i < $wo; ++$i) {
2561 $frame[6][7+$i] = chr(0x90 | ($i & 1));
2562 $frame[7+$i][6] = chr(0x90 | ($i & 1));
2598 if (!isset($this->frames[
$version])) {
2601 if (is_null($this->frames[$version])) {
2613 return ($spec[0] + $spec[3]);
2676 return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]);
2685 return ($spec[0] + $spec[3]) * $spec[2];
2702 protected function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) {
2703 foreach ($this->rsitems as $rs) {
2704 if (($rs[
'pad'] != $pad) OR ($rs[
'nroots'] != $nroots) OR ($rs[
'mm'] != $symsize)
2705 OR ($rs[
'gfpoly'] != $gfpoly) OR ($rs[
'fcr'] != $fcr) OR ($rs[
'prim'] != $prim)) {
2710 $rs = $this->
init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
2711 array_unshift($this->rsitems, $rs);
2726 while (
$x >= $rs[
'nn']) {
2728 $x = (
$x >> $rs[
'mm']) + (
$x & $rs[
'nn']);
2743 protected function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) {
2747 if (($symsize < 0) OR ($symsize > 8)) {
2750 if (($fcr < 0) OR ($fcr >= (1<<$symsize))) {
2753 if (($prim <= 0) OR ($prim >= (1<<$symsize))) {
2756 if (($nroots < 0) OR ($nroots >= (1<<$symsize))) {
2759 if (($pad < 0) OR ($pad >= ((1<<$symsize) -1 - $nroots))) {
2763 $rs[
'mm'] = $symsize;
2764 $rs[
'nn'] = (1 << $symsize) - 1;
2766 $rs[
'alpha_to'] = array_fill(0, ($rs[
'nn'] + 1), 0);
2767 $rs[
'index_of'] = array_fill(0, ($rs[
'nn'] + 1), 0);
2772 $rs[
'index_of'][0] = $A0;
2773 $rs[
'alpha_to'][$A0] = 0;
2775 for ($i=0; $i<$rs[
'nn']; ++$i) {
2776 $rs[
'index_of'][$sr] = $i;
2777 $rs[
'alpha_to'][$i] = $sr;
2779 if ($sr & (1 << $symsize)) {
2789 $rs[
'genpoly'] = array_fill(0, ($nroots + 1), 0);
2791 $rs[
'prim'] = $prim;
2792 $rs[
'nroots'] = $nroots;
2793 $rs[
'gfpoly'] = $gfpoly;
2795 for ($iprim=1; ($iprim % $prim) != 0; $iprim += $rs[
'nn']) {
2798 $rs[
'iprim'] = (int)($iprim / $prim);
2799 $rs[
'genpoly'][0] = 1;
2800 for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {
2801 $rs[
'genpoly'][$i+1] = 1;
2803 for ($j = $i; $j > 0; --$j) {
2804 if ($rs[
'genpoly'][$j] != 0) {
2805 $rs[
'genpoly'][$j] = $rs[
'genpoly'][$j-1] ^ $rs[
'alpha_to'][$this->
modnn($rs, $rs[
'index_of'][$rs[
'genpoly'][$j]] + $root)];
2807 $rs[
'genpoly'][$j] = $rs[
'genpoly'][$j-1];
2811 $rs[
'genpoly'][0] = $rs[
'alpha_to'][$this->
modnn($rs, $rs[
'index_of'][$rs[
'genpoly'][0]] + $root)];
2814 for ($i = 0; $i <= $nroots; ++$i) {
2815 $rs[
'genpoly'][$i] = $rs[
'index_of'][$rs[
'genpoly'][$i]];
2830 $ALPHA_TO =& $rs[
'alpha_to'];
2831 $INDEX_OF =& $rs[
'index_of'];
2832 $GENPOLY =& $rs[
'genpoly'];
2833 $NROOTS =& $rs[
'nroots'];
2835 $PRIM =& $rs[
'prim'];
2836 $IPRIM =& $rs[
'iprim'];
2839 $parity = array_fill(0, $NROOTS, 0);
2840 for ($i=0; $i < ($NN - $NROOTS - $PAD); $i++) {
2841 $feedback = $INDEX_OF[
$data[$i] ^ $parity[0]];
2842 if ($feedback != $A0) {
2846 $feedback = $this->
modnn($rs, $NN - $GENPOLY[$NROOTS] + $feedback);
2847 for ($j=1; $j < $NROOTS; ++$j) {
2848 $parity[$j] ^= $ALPHA_TO[$this->
modnn($rs, $feedback + $GENPOLY[($NROOTS - $j)])];
2852 array_shift($parity);
2853 if ($feedback != $A0) {
2854 array_push($parity, $ALPHA_TO[$this->
modnn($rs, $feedback + $GENPOLY[0])]);
2856 array_push($parity, 0);