qrspec.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. <?php
  2. class QRspec
  3. {
  4. static public $capacity = array(
  5. array(
  6. 0,
  7. 0,
  8. 0,
  9. array(0, 0, 0, 0)
  10. ),
  11. array(
  12. 21,
  13. 26,
  14. 0,
  15. array(7, 10, 13, 17)
  16. ),
  17. array(
  18. 25,
  19. 44,
  20. 7,
  21. array(10, 16, 22, 28)
  22. ),
  23. array(
  24. 29,
  25. 70,
  26. 7,
  27. array(15, 26, 36, 44)
  28. ),
  29. array(
  30. 33,
  31. 100,
  32. 7,
  33. array(20, 36, 52, 64)
  34. ),
  35. array(
  36. 37,
  37. 134,
  38. 7,
  39. array(26, 48, 72, 88)
  40. ),
  41. array(
  42. 41,
  43. 172,
  44. 7,
  45. array(36, 64, 96, 112)
  46. ),
  47. array(
  48. 45,
  49. 196,
  50. 0,
  51. array(40, 72, 108, 130)
  52. ),
  53. array(
  54. 49,
  55. 242,
  56. 0,
  57. array(48, 88, 132, 156)
  58. ),
  59. array(
  60. 53,
  61. 292,
  62. 0,
  63. array(60, 110, 160, 192)
  64. ),
  65. array(
  66. 57,
  67. 346,
  68. 0,
  69. array(72, 130, 192, 224)
  70. ),
  71. array(
  72. 61,
  73. 404,
  74. 0,
  75. array(80, 150, 224, 264)
  76. ),
  77. array(
  78. 65,
  79. 466,
  80. 0,
  81. array(96, 176, 260, 308)
  82. ),
  83. array(
  84. 69,
  85. 532,
  86. 0,
  87. array(104, 198, 288, 352)
  88. ),
  89. array(
  90. 73,
  91. 581,
  92. 3,
  93. array(120, 216, 320, 384)
  94. ),
  95. array(
  96. 77,
  97. 655,
  98. 3,
  99. array(132, 240, 360, 432)
  100. ),
  101. array(
  102. 81,
  103. 733,
  104. 3,
  105. array(144, 280, 408, 480)
  106. ),
  107. array(
  108. 85,
  109. 815,
  110. 3,
  111. array(168, 308, 448, 532)
  112. ),
  113. array(
  114. 89,
  115. 901,
  116. 3,
  117. array(180, 338, 504, 588)
  118. ),
  119. array(
  120. 93,
  121. 991,
  122. 3,
  123. array(196, 364, 546, 650)
  124. ),
  125. array(
  126. 97,
  127. 1085,
  128. 3,
  129. array(224, 416, 600, 700)
  130. ),
  131. array(
  132. 101,
  133. 1156,
  134. 4,
  135. array(224, 442, 644, 750)
  136. ),
  137. array(
  138. 105,
  139. 1258,
  140. 4,
  141. array(252, 476, 690, 816)
  142. ),
  143. array(
  144. 109,
  145. 1364,
  146. 4,
  147. array(270, 504, 750, 900)
  148. ),
  149. array(
  150. 113,
  151. 1474,
  152. 4,
  153. array(300, 560, 810, 960)
  154. ),
  155. array(
  156. 117,
  157. 1588,
  158. 4,
  159. array(312, 588, 870, 1050)
  160. ),
  161. array(
  162. 121,
  163. 1706,
  164. 4,
  165. array(336, 644, 952, 1110)
  166. ),
  167. array(
  168. 125,
  169. 1828,
  170. 4,
  171. array(360, 700, 1020, 1200)
  172. ),
  173. array(
  174. 129,
  175. 1921,
  176. 3,
  177. array(390, 728, 1050, 1260)
  178. ),
  179. array(
  180. 133,
  181. 2051,
  182. 3,
  183. array(420, 784, 1140, 1350)
  184. ),
  185. array(
  186. 137,
  187. 2185,
  188. 3,
  189. array(450, 812, 1200, 1440)
  190. ),
  191. array(
  192. 141,
  193. 2323,
  194. 3,
  195. array(480, 868, 1290, 1530)
  196. ),
  197. array(
  198. 145,
  199. 2465,
  200. 3,
  201. array(510, 924, 1350, 1620)
  202. ),
  203. array(
  204. 149,
  205. 2611,
  206. 3,
  207. array(540, 980, 1440, 1710)
  208. ),
  209. array(
  210. 153,
  211. 2761,
  212. 3,
  213. array(570, 1036, 1530, 1800)
  214. ),
  215. array(
  216. 157,
  217. 2876,
  218. 0,
  219. array(570, 1064, 1590, 1890)
  220. ),
  221. array(
  222. 161,
  223. 3034,
  224. 0,
  225. array(600, 1120, 1680, 1980)
  226. ),
  227. array(
  228. 165,
  229. 3196,
  230. 0,
  231. array(630, 1204, 1770, 2100)
  232. ),
  233. array(
  234. 169,
  235. 3362,
  236. 0,
  237. array(660, 1260, 1860, 2220)
  238. ),
  239. array(
  240. 173,
  241. 3532,
  242. 0,
  243. array(720, 1316, 1950, 2310)
  244. ),
  245. array(
  246. 177,
  247. 3706,
  248. 0,
  249. array(750, 1372, 2040, 2430)
  250. )
  251. );
  252. static public $lengthTableBits = array(
  253. array(10, 12, 14),
  254. array(9, 11, 13),
  255. array(8, 16, 16),
  256. array(8, 10, 12)
  257. );
  258. static public $eccTable = array(
  259. array(
  260. array(0, 0),
  261. array(0, 0),
  262. array(0, 0),
  263. array(0, 0)
  264. ),
  265. array(
  266. array(1, 0),
  267. array(1, 0),
  268. array(1, 0),
  269. array(1, 0)
  270. ),
  271. array(
  272. array(1, 0),
  273. array(1, 0),
  274. array(1, 0),
  275. array(1, 0)
  276. ),
  277. array(
  278. array(1, 0),
  279. array(1, 0),
  280. array(2, 0),
  281. array(2, 0)
  282. ),
  283. array(
  284. array(1, 0),
  285. array(2, 0),
  286. array(2, 0),
  287. array(4, 0)
  288. ),
  289. array(
  290. array(1, 0),
  291. array(2, 0),
  292. array(2, 2),
  293. array(2, 2)
  294. ),
  295. array(
  296. array(2, 0),
  297. array(4, 0),
  298. array(4, 0),
  299. array(4, 0)
  300. ),
  301. array(
  302. array(2, 0),
  303. array(4, 0),
  304. array(2, 4),
  305. array(4, 1)
  306. ),
  307. array(
  308. array(2, 0),
  309. array(2, 2),
  310. array(4, 2),
  311. array(4, 2)
  312. ),
  313. array(
  314. array(2, 0),
  315. array(3, 2),
  316. array(4, 4),
  317. array(4, 4)
  318. ),
  319. array(
  320. array(2, 2),
  321. array(4, 1),
  322. array(6, 2),
  323. array(6, 2)
  324. ),
  325. array(
  326. array(4, 0),
  327. array(1, 4),
  328. array(4, 4),
  329. array(3, 8)
  330. ),
  331. array(
  332. array(2, 2),
  333. array(6, 2),
  334. array(4, 6),
  335. array(7, 4)
  336. ),
  337. array(
  338. array(4, 0),
  339. array(8, 1),
  340. array(8, 4),
  341. array(12, 4)
  342. ),
  343. array(
  344. array(3, 1),
  345. array(4, 5),
  346. array(11, 5),
  347. array(11, 5)
  348. ),
  349. array(
  350. array(5, 1),
  351. array(5, 5),
  352. array(5, 7),
  353. array(11, 7)
  354. ),
  355. array(
  356. array(5, 1),
  357. array(7, 3),
  358. array(15, 2),
  359. array(3, 13)
  360. ),
  361. array(
  362. array(1, 5),
  363. array(10, 1),
  364. array(1, 15),
  365. array(2, 17)
  366. ),
  367. array(
  368. array(5, 1),
  369. array(9, 4),
  370. array(17, 1),
  371. array(2, 19)
  372. ),
  373. array(
  374. array(3, 4),
  375. array(3, 11),
  376. array(17, 4),
  377. array(9, 16)
  378. ),
  379. array(
  380. array(3, 5),
  381. array(3, 13),
  382. array(15, 5),
  383. array(15, 10)
  384. ),
  385. array(
  386. array(4, 4),
  387. array(17, 0),
  388. array(17, 6),
  389. array(19, 6)
  390. ),
  391. array(
  392. array(2, 7),
  393. array(17, 0),
  394. array(7, 16),
  395. array(34, 0)
  396. ),
  397. array(
  398. array(4, 5),
  399. array(4, 14),
  400. array(11, 14),
  401. array(16, 14)
  402. ),
  403. array(
  404. array(6, 4),
  405. array(6, 14),
  406. array(11, 16),
  407. array(30, 2)
  408. ),
  409. array(
  410. array(8, 4),
  411. array(8, 13),
  412. array(7, 22),
  413. array(22, 13)
  414. ),
  415. array(
  416. array(10, 2),
  417. array(19, 4),
  418. array(28, 6),
  419. array(33, 4)
  420. ),
  421. array(
  422. array(8, 4),
  423. array(22, 3),
  424. array(8, 26),
  425. array(12, 28)
  426. ),
  427. array(
  428. array(3, 10),
  429. array(3, 23),
  430. array(4, 31),
  431. array(11, 31)
  432. ),
  433. array(
  434. array(7, 7),
  435. array(21, 7),
  436. array(1, 37),
  437. array(19, 26)
  438. ),
  439. array(
  440. array(5, 10),
  441. array(19, 10),
  442. array(15, 25),
  443. array(23, 25)
  444. ),
  445. array(
  446. array(13, 3),
  447. array(2, 29),
  448. array(42, 1),
  449. array(23, 28)
  450. ),
  451. array(
  452. array(17, 0),
  453. array(10, 23),
  454. array(10, 35),
  455. array(19, 35)
  456. ),
  457. array(
  458. array(17, 1),
  459. array(14, 21),
  460. array(29, 19),
  461. array(11, 46)
  462. ),
  463. array(
  464. array(13, 6),
  465. array(14, 23),
  466. array(44, 7),
  467. array(59, 1)
  468. ),
  469. array(
  470. array(12, 7),
  471. array(12, 26),
  472. array(39, 14),
  473. array(22, 41)
  474. ),
  475. array(
  476. array(6, 14),
  477. array(6, 34),
  478. array(46, 10),
  479. array(2, 64)
  480. ),
  481. array(
  482. array(17, 4),
  483. array(29, 14),
  484. array(49, 10),
  485. array(24, 46)
  486. ),
  487. array(
  488. array(4, 18),
  489. array(13, 32),
  490. array(48, 14),
  491. array(42, 32)
  492. ),
  493. array(
  494. array(20, 4),
  495. array(40, 7),
  496. array(43, 22),
  497. array(10, 67)
  498. ),
  499. array(
  500. array(19, 6),
  501. array(18, 31),
  502. array(34, 34),
  503. array(20, 61)
  504. )
  505. );
  506. static public $alignmentPattern = array(
  507. array(0, 0),
  508. array(0, 0),
  509. array(18, 0),
  510. array(22, 0),
  511. array(26, 0),
  512. array(30, 0),
  513. array(34, 0),
  514. array(22, 38),
  515. array(24, 42),
  516. array(26, 46),
  517. array(28, 50),
  518. array(30, 54),
  519. array(32, 58),
  520. array(34, 62),
  521. array(26, 46),
  522. array(26, 48),
  523. array(26, 50),
  524. array(30, 54),
  525. array(30, 56),
  526. array(30, 58),
  527. array(34, 62),
  528. array(28, 50),
  529. array(26, 50),
  530. array(30, 54),
  531. array(28, 54),
  532. array(32, 58),
  533. array(30, 58),
  534. array(34, 62),
  535. array(26, 50),
  536. array(30, 54),
  537. array(26, 52),
  538. array(30, 56),
  539. array(34, 60),
  540. array(30, 58),
  541. array(34, 62),
  542. array(30, 54),
  543. array(24, 50),
  544. array(28, 54),
  545. array(32, 58),
  546. array(26, 54),
  547. array(30, 58)
  548. );
  549. static public $versionPattern = array(31892, 34236, 39577, 42195, 48118, 51042, 55367, 58893, 63784, 68472, 70749, 76311, 79154, 84390, 87683, 92361, 96236, 102084, 102881, 110507, 110734, 117786, 119615, 126325, 127568, 133589, 136944, 141498, 145311, 150283, 152622, 158308, 161089, 167017);
  550. static public $formatInfo = array(
  551. array(30660, 29427, 32170, 30877, 26159, 25368, 27713, 26998),
  552. array(21522, 20773, 24188, 23371, 17913, 16590, 20375, 19104),
  553. array(13663, 12392, 16177, 14854, 9396, 8579, 11994, 11245),
  554. array(5769, 5054, 7399, 6608, 1890, 597, 3340, 2107)
  555. );
  556. static public $frames = array();
  557. static public function getDataLength($version, $level)
  558. {
  559. return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
  560. }
  561. static public function getECCLength($version, $level)
  562. {
  563. return self::$capacity[$version][QRCAP_EC][$level];
  564. }
  565. static public function getWidth($version)
  566. {
  567. return self::$capacity[$version][QRCAP_WIDTH];
  568. }
  569. static public function getRemainder($version)
  570. {
  571. return self::$capacity[$version][QRCAP_REMINDER];
  572. }
  573. static public function getMinimumVersion($size, $level)
  574. {
  575. for ($i = 1; $i <= QRSPEC_VERSION_MAX; $i++) {
  576. $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
  577. if ($size <= $words) {
  578. return $i;
  579. }
  580. }
  581. return -1;
  582. }
  583. static public function lengthIndicator($mode, $version)
  584. {
  585. if ($mode == QR_MODE_STRUCTURE) {
  586. return 0;
  587. }
  588. if ($version <= 9) {
  589. $l = 0;
  590. }
  591. else if ($version <= 26) {
  592. $l = 1;
  593. }
  594. else {
  595. $l = 2;
  596. }
  597. return self::$lengthTableBits[$mode][$l];
  598. }
  599. static public function maximumWords($mode, $version)
  600. {
  601. if ($mode == QR_MODE_STRUCTURE) {
  602. return 3;
  603. }
  604. if ($version <= 9) {
  605. $l = 0;
  606. }
  607. else if ($version <= 26) {
  608. $l = 1;
  609. }
  610. else {
  611. $l = 2;
  612. }
  613. $bits = self::$lengthTableBits[$mode][$l];
  614. $words = (1 << $bits) - 1;
  615. if ($mode == QR_MODE_KANJI) {
  616. $words *= 2;
  617. }
  618. return $words;
  619. }
  620. static public function getEccSpec($version, $level, array &$spec)
  621. {
  622. if (count($spec) < 5) {
  623. $spec = array(0, 0, 0, 0, 0);
  624. }
  625. $b1 = self::$eccTable[$version][$level][0];
  626. $b2 = self::$eccTable[$version][$level][1];
  627. $data = self::getDataLength($version, $level);
  628. $ecc = self::getECCLength($version, $level);
  629. if ($b2 == 0) {
  630. $spec[0] = $b1;
  631. $spec[1] = (int) ($data / $b1);
  632. $spec[2] = (int) ($ecc / $b1);
  633. $spec[3] = 0;
  634. $spec[4] = 0;
  635. }
  636. else {
  637. $spec[0] = $b1;
  638. $spec[1] = (int) ($data / ($b1 + $b2));
  639. $spec[2] = (int) ($ecc / ($b1 + $b2));
  640. $spec[3] = $b2;
  641. $spec[4] = $spec[1] + 1;
  642. }
  643. }
  644. static public function putAlignmentMarker(array &$frame, $ox, $oy)
  645. {
  646. $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");
  647. $yStart = $oy - 2;
  648. $xStart = $ox - 2;
  649. for ($y = 0; $y < 5; $y++) {
  650. QRstr::set($frame, $xStart, $yStart + $y, $finder[$y]);
  651. }
  652. }
  653. static public function putAlignmentPattern($version, &$frame, $width)
  654. {
  655. if ($version < 2) {
  656. return NULL;
  657. }
  658. $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
  659. if ($d < 0) {
  660. $w = 2;
  661. }
  662. else {
  663. $w = (int) (($width - self::$alignmentPattern[$version][0]) / $d + 2);
  664. }
  665. if ($w * $w - 3 == 1) {
  666. $x = self::$alignmentPattern[$version][0];
  667. $y = self::$alignmentPattern[$version][0];
  668. self::putAlignmentMarker($frame, $x, $y);
  669. return NULL;
  670. }
  671. $cx = self::$alignmentPattern[$version][0];
  672. for ($x = 1; $x < $w - 1; $x++) {
  673. self::putAlignmentMarker($frame, 6, $cx);
  674. self::putAlignmentMarker($frame, $cx, 6);
  675. $cx += $d;
  676. }
  677. $cy = self::$alignmentPattern[$version][0];
  678. for ($y = 0; $y < $w - 1; $y++) {
  679. $cx = self::$alignmentPattern[$version][0];
  680. for ($x = 0; $x < $w - 1; $x++) {
  681. self::putAlignmentMarker($frame, $cx, $cy);
  682. $cx += $d;
  683. }
  684. $cy += $d;
  685. }
  686. }
  687. static public function getVersionPattern($version)
  688. {
  689. if ($version < 7 || QRSPEC_VERSION_MAX < $version) {
  690. return 0;
  691. }
  692. return self::$versionPattern[$version - 7];
  693. }
  694. static public function getFormatInfo($mask, $level)
  695. {
  696. if ($mask < 0 || 7 < $mask) {
  697. return 0;
  698. }
  699. if ($level < 0 || 3 < $level) {
  700. return 0;
  701. }
  702. return self::$formatInfo[$level][$mask];
  703. }
  704. static public function putFinderPattern(&$frame, $ox, $oy)
  705. {
  706. $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");
  707. for ($y = 0; $y < 7; $y++) {
  708. QRstr::set($frame, $ox, $oy + $y, $finder[$y]);
  709. }
  710. }
  711. static public function createFrame($version)
  712. {
  713. $width = self::$capacity[$version][QRCAP_WIDTH];
  714. $frameLine = str_repeat('', $width);
  715. $frame = array_fill(0, $width, $frameLine);
  716. self::putFinderPattern($frame, 0, 0);
  717. self::putFinderPattern($frame, $width - 7, 0);
  718. self::putFinderPattern($frame, 0, $width - 7);
  719. $yOffset = $width - 7;
  720. for ($y = 0; $y < 7; $y++) {
  721. $frame[$y][7] = "\xc0";
  722. $frame[$y][$width - 8] = "\xc0";
  723. $frame[$yOffset][7] = "\xc0";
  724. $yOffset++;
  725. }
  726. $setPattern = str_repeat("\xc0", 8);
  727. QRstr::set($frame, 0, 7, $setPattern);
  728. QRstr::set($frame, $width - 8, 7, $setPattern);
  729. QRstr::set($frame, 0, $width - 8, $setPattern);
  730. $setPattern = str_repeat("\x84", 9);
  731. QRstr::set($frame, 0, 8, $setPattern);
  732. QRstr::set($frame, $width - 8, 8, $setPattern, 8);
  733. $yOffset = $width - 8;
  734. for ($y = 0; $y < 8; $y++, $yOffset++) {
  735. $frame[$y][8] = "\x84";
  736. $frame[$yOffset][8] = "\x84";
  737. }
  738. for ($i = 1; $i < $width - 15; $i++) {
  739. $frame[6][7 + $i] = chr(144 | $i & 1);
  740. $frame[7 + $i][6] = chr(144 | $i & 1);
  741. }
  742. self::putAlignmentPattern($version, $frame, $width);
  743. if (7 <= $version) {
  744. $vinf = self::getVersionPattern($version);
  745. $v = $vinf;
  746. for ($x = 0; $x < 6; $x++) {
  747. for ($y = 0; $y < 3; $y++) {
  748. $frame[$width - 11 + $y][$x] = chr(136 | $v & 1);
  749. $v = $v >> 1;
  750. }
  751. }
  752. $v = $vinf;
  753. for ($y = 0; $y < 6; $y++) {
  754. for ($x = 0; $x < 3; $x++) {
  755. $frame[$y][$x + ($width - 11)] = chr(136 | $v & 1);
  756. $v = $v >> 1;
  757. }
  758. }
  759. }
  760. $frame[$width - 8][8] = "\x81";
  761. return $frame;
  762. }
  763. static public function debug($frame, $binary_mode = false)
  764. {
  765. if ($binary_mode) {
  766. foreach ($frame as &$frameLine) {
  767. $frameLine = join('<span class="m">&nbsp;&nbsp;</span>', explode('0', $frameLine));
  768. $frameLine = join('██', explode('1', $frameLine));
  769. }
  770. echo ' <style>
  771. .m { background-color: white; }
  772. </style>
  773. ';
  774. echo '<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
  775. echo join('<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', $frame);
  776. echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';
  777. }
  778. else {
  779. foreach ($frame as &$frameLine) {
  780. $frameLine = join('<span class="m">&nbsp;</span>', explode("\xc0", $frameLine));
  781. $frameLine = join('<span class="m">▒</span>', explode("\xc1", $frameLine));
  782. $frameLine = join('<span class="p">&nbsp;</span>', explode("\xa0", $frameLine));
  783. $frameLine = join('<span class="p">▒</span>', explode("\xa1", $frameLine));
  784. $frameLine = join('<span class="s">◇</span>', explode("\x84", $frameLine));
  785. $frameLine = join('<span class="s">◆</span>', explode("\x85", $frameLine));
  786. $frameLine = join('<span class="x">☢</span>', explode("\x81", $frameLine));
  787. $frameLine = join('<span class="c">&nbsp;</span>', explode("\x90", $frameLine));
  788. $frameLine = join('<span class="c">◷</span>', explode("\x91", $frameLine));
  789. $frameLine = join('<span class="f">&nbsp;</span>', explode("\x88", $frameLine));
  790. $frameLine = join('<span class="f">▒</span>', explode("\x89", $frameLine));
  791. $frameLine = join('♦', explode('', $frameLine));
  792. $frameLine = join('⋅', explode('', $frameLine));
  793. }
  794. echo ' <style>
  795. .p { background-color: yellow; }
  796. .m { background-color: #00FF00; }
  797. .s { background-color: #FF0000; }
  798. .c { background-color: aqua; }
  799. .x { background-color: pink; }
  800. .f { background-color: gold; }
  801. </style>
  802. ';
  803. echo '<pre><tt>';
  804. echo join('<br/ >', $frame);
  805. echo '</tt></pre>';
  806. }
  807. }
  808. static public function serial($frame)
  809. {
  810. return gzcompress(join('
  811. ', $frame), 9);
  812. }
  813. static public function unserial($code)
  814. {
  815. return explode('
  816. ', gzuncompress($code));
  817. }
  818. static public function newFrame($version)
  819. {
  820. if ($version < 1 || QRSPEC_VERSION_MAX < $version) {
  821. return NULL;
  822. }
  823. if (!isset(self::$frames[$version])) {
  824. $fileName = QR_CACHE_DIR . 'frame_' . $version . '.dat';
  825. if (QR_CACHEABLE) {
  826. if (file_exists($fileName)) {
  827. self::$frames[$version] = self::unserial(file_get_contents($fileName));
  828. }
  829. else {
  830. self::$frames[$version] = self::createFrame($version);
  831. file_put_contents($fileName, self::serial(self::$frames[$version]));
  832. }
  833. }
  834. else {
  835. self::$frames[$version] = self::createFrame($version);
  836. }
  837. }
  838. if (is_null(self::$frames[$version])) {
  839. return NULL;
  840. }
  841. return self::$frames[$version];
  842. }
  843. static public function rsBlockNum($spec)
  844. {
  845. return $spec[0] + $spec[3];
  846. }
  847. static public function rsBlockNum1($spec)
  848. {
  849. return $spec[0];
  850. }
  851. static public function rsDataCodes1($spec)
  852. {
  853. return $spec[1];
  854. }
  855. static public function rsEccCodes1($spec)
  856. {
  857. return $spec[2];
  858. }
  859. static public function rsBlockNum2($spec)
  860. {
  861. return $spec[3];
  862. }
  863. static public function rsDataCodes2($spec)
  864. {
  865. return $spec[4];
  866. }
  867. static public function rsEccCodes2($spec)
  868. {
  869. return $spec[2];
  870. }
  871. static public function rsDataLength($spec)
  872. {
  873. return $spec[0] * $spec[1] + $spec[3] * $spec[4];
  874. }
  875. static public function rsEccLength($spec)
  876. {
  877. return ($spec[0] + $spec[3]) * $spec[2];
  878. }
  879. }
  880. define('QRSPEC_VERSION_MAX', 40);
  881. define('QRSPEC_WIDTH_MAX', 177);
  882. define('QRCAP_WIDTH', 0);
  883. define('QRCAP_WORDS', 1);
  884. define('QRCAP_REMINDER', 2);
  885. define('QRCAP_EC', 3);
  886. ?>