Version.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. <?php
  2. /*
  3. * Copyright 2007 ZXing authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace Zxing\Qrcode\Decoder;
  18. use Zxing\FormatException;
  19. use Zxing\Common\BitMatrix;
  20. /**
  21. * See ISO 18004:2006 Annex D
  22. *
  23. * @author Sean Owen
  24. */
  25. class Version
  26. {
  27. /**
  28. * See ISO 18004:2006 Annex D.
  29. * Element i represents the raw version bits that specify version i + 7
  30. */
  31. private static $VERSION_DECODE_INFO = array(
  32. 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
  33. 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
  34. 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
  35. 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
  36. 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
  37. 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
  38. 0x2542E, 0x26A64, 0x27541, 0x28C69
  39. );
  40. private static $VERSIONS;
  41. private $versionNumber;
  42. private $alignmentPatternCenters;
  43. private $ecBlocks;
  44. private $totalCodewords;
  45. public function __construct($versionNumber,
  46. $alignmentPatternCenters,
  47. $ecBlocks)
  48. {//ECBlocks... ecBlocks
  49. $this->versionNumber = $versionNumber;
  50. $this->alignmentPatternCenters = $alignmentPatternCenters;
  51. $this->ecBlocks = $ecBlocks;
  52. $total = 0;
  53. if(is_array($ecBlocks)) {
  54. $ecCodewords = $ecBlocks[0]->getECCodewordsPerBlock();
  55. $ecbArray = $ecBlocks[0]->getECBlocks();
  56. }else{
  57. $ecCodewords = $ecBlocks->getECCodewordsPerBlock();
  58. $ecbArray = $ecBlocks->getECBlocks();
  59. }
  60. foreach ($ecbArray as $ecBlock) {
  61. $total += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords);
  62. }
  63. $this->totalCodewords = $total;
  64. }
  65. public function getVersionNumber()
  66. {
  67. return $this->versionNumber;
  68. }
  69. public function getAlignmentPatternCenters()
  70. {
  71. return $this->alignmentPatternCenters;
  72. }
  73. public function getTotalCodewords()
  74. {
  75. return $this->totalCodewords;
  76. }
  77. public function getDimensionForVersion()
  78. {
  79. return 17 + 4 * $this->versionNumber;
  80. }
  81. public function getECBlocksForLevel($ecLevel)
  82. {
  83. return $this->ecBlocks[$ecLevel->getOrdinal()];
  84. }
  85. /**
  86. * <p>Deduces version information purely from QR Code dimensions.</p>
  87. *
  88. * @param dimension dimension in modules
  89. * @return Version for a QR Code of that dimension
  90. * @throws FormatException if dimension is not 1 mod 4
  91. */
  92. public static function getProvisionalVersionForDimension($dimension)
  93. {
  94. if ($dimension % 4 != 1) {
  95. throw FormatException::getFormatInstance();
  96. }
  97. try {
  98. return self::getVersionForNumber(($dimension - 17) / 4);
  99. } catch (\InvalidArgumentException $ignored) {
  100. throw FormatException::getFormatInstance();
  101. }
  102. }
  103. public static function getVersionForNumber($versionNumber)
  104. {
  105. if ($versionNumber < 1 || $versionNumber > 40) {
  106. throw new \InvalidArgumentException();
  107. }
  108. if(!self::$VERSIONS){
  109. self::$VERSIONS = self::buildVersions();
  110. }
  111. return self::$VERSIONS[$versionNumber - 1];
  112. }
  113. static function decodeVersionInformation($versionBits)
  114. {
  115. $bestDifference = PHP_INT_MAX;
  116. $bestVersion = 0;
  117. for ($i = 0; $i < count(self::$VERSION_DECODE_INFO); $i++) {
  118. $targetVersion = self::$VERSION_DECODE_INFO[$i];
  119. // Do the version info bits match exactly? done.
  120. if ($targetVersion == $versionBits) {
  121. return self::getVersionForNumber($i + 7);
  122. }
  123. // Otherwise see if this is the closest to a real version info bit string
  124. // we have seen so far
  125. $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion);
  126. if ($bitsDifference < $bestDifference) {
  127. $bestVersion = $i + 7;
  128. $bestDifference = $bitsDifference;
  129. }
  130. }
  131. // We can tolerate up to 3 bits of error since no two version info codewords will
  132. // differ in less than 8 bits.
  133. if ($bestDifference <= 3) {
  134. return self::getVersionForNumber($bestVersion);
  135. }
  136. // If we didn't find a close enough match, fail
  137. return null;
  138. }
  139. /**
  140. * See ISO 18004:2006 Annex E
  141. */
  142. function buildFunctionPattern()
  143. {
  144. $dimension = self::getDimensionForVersion();
  145. $bitMatrix = new BitMatrix($dimension);
  146. // Top left finder pattern + separator + format
  147. $bitMatrix->setRegion(0, 0, 9, 9);
  148. // Top right finder pattern + separator + format
  149. $bitMatrix->setRegion($dimension - 8, 0, 8, 9);
  150. // Bottom left finder pattern + separator + format
  151. $bitMatrix->setRegion(0, $dimension - 8, 9, 8);
  152. // Alignment patterns
  153. $max = count($this->alignmentPatternCenters);
  154. for ($x = 0; $x < $max; $x++) {
  155. $i = $this->alignmentPatternCenters[$x] - 2;
  156. for ($y = 0; $y < $max; $y++) {
  157. if (($x == 0 && ($y == 0 || $y == $max - 1)) || ($x == $max - 1 && $y == 0)) {
  158. // No alignment patterns near the three finder paterns
  159. continue;
  160. }
  161. $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5);
  162. }
  163. }
  164. // Vertical timing pattern
  165. $bitMatrix->setRegion(6, 9, 1, $dimension - 17);
  166. // Horizontal timing pattern
  167. $bitMatrix->setRegion(9, 6, $dimension - 17, 1);
  168. if ($this->versionNumber > 6) {
  169. // Version info, top right
  170. $bitMatrix->setRegion($dimension - 11, 0, 3, 6);
  171. // Version info, bottom left
  172. $bitMatrix->setRegion(0, $dimension - 11, 6, 3);
  173. }
  174. return $bitMatrix;
  175. }
  176. /**
  177. * See ISO 18004:2006 6.5.1 Table 9
  178. */
  179. private static function buildVersions()
  180. {
  181. return array(
  182. new Version(1, array(),
  183. array(new ECBlocks(7, array(new ECB(1, 19))),
  184. new ECBlocks(10, array(new ECB(1, 16))),
  185. new ECBlocks(13, array(new ECB(1, 13))),
  186. new ECBlocks(17, array(new ECB(1, 9))))),
  187. new Version(2, array(6, 18),
  188. array(new ECBlocks(10, array(new ECB(1, 34))),
  189. new ECBlocks(16, array(new ECB(1, 28))),
  190. new ECBlocks(22, array(new ECB(1, 22))),
  191. new ECBlocks(28, array(new ECB(1, 16))))),
  192. new Version(3, array(6, 22),
  193. array( new ECBlocks(15, array(new ECB(1, 55))),
  194. new ECBlocks(26, array(new ECB(1, 44))),
  195. new ECBlocks(18, array(new ECB(2, 17))),
  196. new ECBlocks(22, array(new ECB(2, 13))))),
  197. new Version(4, array(6, 26),
  198. array(new ECBlocks(20, array(new ECB(1, 80))),
  199. new ECBlocks(18, array(new ECB(2, 32))),
  200. new ECBlocks(26, array(new ECB(2, 24))),
  201. new ECBlocks(16, array(new ECB(4, 9))))),
  202. new Version(5, array(6, 30),
  203. array(new ECBlocks(26, array(new ECB(1, 108))),
  204. new ECBlocks(24, array(new ECB(2, 43))),
  205. new ECBlocks(18, array(new ECB(2, 15),
  206. new ECB(2, 16))),
  207. new ECBlocks(22, array(new ECB(2, 11),
  208. new ECB(2, 12))))),
  209. new Version(6, array(6, 34),
  210. array(new ECBlocks(18, array(new ECB(2, 68))),
  211. new ECBlocks(16, array(new ECB(4, 27))),
  212. new ECBlocks(24, array(new ECB(4, 19))),
  213. new ECBlocks(28, array(new ECB(4, 15))))),
  214. new Version(7, array(6, 22, 38),
  215. array(new ECBlocks(20, array(new ECB(2, 78))),
  216. new ECBlocks(18, array(new ECB(4, 31))),
  217. new ECBlocks(18, array(new ECB(2, 14),
  218. new ECB(4, 15))),
  219. new ECBlocks(26, array(new ECB(4, 13),
  220. new ECB(1, 14))))),
  221. new Version(8, array(6, 24, 42),
  222. array(new ECBlocks(24, array(new ECB(2, 97))),
  223. new ECBlocks(22, array(new ECB(2, 38),
  224. new ECB(2, 39))),
  225. new ECBlocks(22, array(new ECB(4, 18),
  226. new ECB(2, 19))),
  227. new ECBlocks(26, array(new ECB(4, 14),
  228. new ECB(2, 15))))),
  229. new Version(9, array(6, 26, 46),
  230. array(new ECBlocks(30, array(new ECB(2, 116))),
  231. new ECBlocks(22, array(new ECB(3, 36),
  232. new ECB(2, 37))),
  233. new ECBlocks(20, array(new ECB(4, 16),
  234. new ECB(4, 17))),
  235. new ECBlocks(24, array(new ECB(4, 12),
  236. new ECB(4, 13))))),
  237. new Version(10, array(6, 28, 50),
  238. array(new ECBlocks(18, array(new ECB(2, 68),
  239. new ECB(2, 69))),
  240. new ECBlocks(26, array(new ECB(4, 43),
  241. new ECB(1, 44))),
  242. new ECBlocks(24, array(new ECB(6, 19),
  243. new ECB(2, 20))),
  244. new ECBlocks(28, array(new ECB(6, 15),
  245. new ECB(2, 16))))),
  246. new Version(11, array(6, 30, 54),
  247. array(new ECBlocks(20, array(new ECB(4, 81))),
  248. new ECBlocks(30, array(new ECB(1, 50),
  249. new ECB(4, 51))),
  250. new ECBlocks(28, array(new ECB(4, 22),
  251. new ECB(4, 23))),
  252. new ECBlocks(24, array(new ECB(3, 12),
  253. new ECB(8, 13))))),
  254. new Version(12, array(6, 32, 58),
  255. array(new ECBlocks(24, array(new ECB(2, 92),
  256. new ECB(2, 93))),
  257. new ECBlocks(22, array(new ECB(6, 36),
  258. new ECB(2, 37))),
  259. new ECBlocks(26, array(new ECB(4, 20),
  260. new ECB(6, 21))),
  261. new ECBlocks(28, array(new ECB(7, 14),
  262. new ECB(4, 15))))),
  263. new Version(13, array(6, 34, 62),
  264. array(new ECBlocks(26, array(new ECB(4, 107))),
  265. new ECBlocks(22, array(new ECB(8, 37),
  266. new ECB(1, 38))),
  267. new ECBlocks(24, array(new ECB(8, 20),
  268. new ECB(4, 21))),
  269. new ECBlocks(22, array(new ECB(12, 11),
  270. new ECB(4, 12))))),
  271. new Version(14, array(6, 26, 46, 66),
  272. array(new ECBlocks(30, array(new ECB(3, 115),
  273. new ECB(1, 116))),
  274. new ECBlocks(24, array(new ECB(4, 40),
  275. new ECB(5, 41))),
  276. new ECBlocks(20, array(new ECB(11, 16),
  277. new ECB(5, 17))),
  278. new ECBlocks(24, array(new ECB(11, 12),
  279. new ECB(5, 13))))),
  280. new Version(15, array(6, 26, 48, 70),
  281. array(new ECBlocks(22, array(new ECB(5, 87),
  282. new ECB(1, 88))),
  283. new ECBlocks(24, array(new ECB(5, 41),
  284. new ECB(5, 42))),
  285. new ECBlocks(30, array(new ECB(5, 24),
  286. new ECB(7, 25))),
  287. new ECBlocks(24, array(new ECB(11, 12),
  288. new ECB(7, 13))))),
  289. new Version(16, array(6, 26, 50, 74),
  290. array(new ECBlocks(24, array(new ECB(5, 98),
  291. new ECB(1, 99))),
  292. new ECBlocks(28, array(new ECB(7, 45),
  293. new ECB(3, 46))),
  294. new ECBlocks(24, array(new ECB(15, 19),
  295. new ECB(2, 20))),
  296. new ECBlocks(30, array(new ECB(3, 15),
  297. new ECB(13, 16))))),
  298. new Version(17, array(6, 30, 54, 78),
  299. array(new ECBlocks(28, array(new ECB(1, 107),
  300. new ECB(5, 108))),
  301. new ECBlocks(28, array(new ECB(10, 46),
  302. new ECB(1, 47))),
  303. new ECBlocks(28, array(new ECB(1, 22),
  304. new ECB(15, 23))),
  305. new ECBlocks(28, array(new ECB(2, 14),
  306. new ECB(17, 15))))),
  307. new Version(18, array(6, 30, 56, 82),
  308. array(new ECBlocks(30, array(new ECB(5, 120),
  309. new ECB(1, 121))),
  310. new ECBlocks(26, array(new ECB(9, 43),
  311. new ECB(4, 44))),
  312. new ECBlocks(28, array(new ECB(17, 22),
  313. new ECB(1, 23))),
  314. new ECBlocks(28, array(new ECB(2, 14),
  315. new ECB(19, 15))))),
  316. new Version(19, array(6, 30, 58, 86),
  317. array(new ECBlocks(28, array(new ECB(3, 113),
  318. new ECB(4, 114))),
  319. new ECBlocks(26, array(new ECB(3, 44),
  320. new ECB(11, 45))),
  321. new ECBlocks(26, array(new ECB(17, 21),
  322. new ECB(4, 22))),
  323. new ECBlocks(26, array(new ECB(9, 13),
  324. new ECB(16, 14))))),
  325. new Version(20, array(6, 34, 62, 90),
  326. array(new ECBlocks(28, array(new ECB(3, 107),
  327. new ECB(5, 108))),
  328. new ECBlocks(26, array(new ECB(3, 41),
  329. new ECB(13, 42))),
  330. new ECBlocks(30, array(new ECB(15, 24),
  331. new ECB(5, 25))),
  332. new ECBlocks(28, array(new ECB(15, 15),
  333. new ECB(10, 16))))),
  334. new Version(21, array(6, 28, 50, 72, 94),
  335. array( new ECBlocks(28, array(new ECB(4, 116),
  336. new ECB(4, 117))),
  337. new ECBlocks(26, array(new ECB(17, 42))),
  338. new ECBlocks(28, array(new ECB(17, 22),
  339. new ECB(6, 23))),
  340. new ECBlocks(30, array(new ECB(19, 16),
  341. new ECB(6, 17))))),
  342. new Version(22, array(6, 26, 50, 74, 98),
  343. array(new ECBlocks(28, array(new ECB(2, 111),
  344. new ECB(7, 112))),
  345. new ECBlocks(28, array(new ECB(17, 46))),
  346. new ECBlocks(30, array(new ECB(7, 24),
  347. new ECB(16, 25))),
  348. new ECBlocks(24, array(new ECB(34, 13))))),
  349. new Version(23, array(6, 30, 54, 78, 102),
  350. new ECBlocks(30, array(new ECB(4, 121),
  351. new ECB(5, 122))),
  352. new ECBlocks(28, array(new ECB(4, 47),
  353. new ECB(14, 48))),
  354. new ECBlocks(30, array(new ECB(11, 24),
  355. new ECB(14, 25))),
  356. new ECBlocks(30, array(new ECB(16, 15),
  357. new ECB(14, 16)))),
  358. new Version(24, array(6, 28, 54, 80, 106),
  359. array(new ECBlocks(30, array(new ECB(6, 117),
  360. new ECB(4, 118))),
  361. new ECBlocks(28, array(new ECB(6, 45),
  362. new ECB(14, 46))),
  363. new ECBlocks(30, array(new ECB(11, 24),
  364. new ECB(16, 25))),
  365. new ECBlocks(30, array(new ECB(30, 16),
  366. new ECB(2, 17))))),
  367. new Version(25, array(6, 32, 58, 84, 110),
  368. array(new ECBlocks(26, array(new ECB(8, 106),
  369. new ECB(4, 107))),
  370. new ECBlocks(28, array(new ECB(8, 47),
  371. new ECB(13, 48))),
  372. new ECBlocks(30, array(new ECB(7, 24),
  373. new ECB(22, 25))),
  374. new ECBlocks(30, array(new ECB(22, 15),
  375. new ECB(13, 16))))),
  376. new Version(26, array(6, 30, 58, 86, 114),
  377. array(new ECBlocks(28, array(new ECB(10, 114),
  378. new ECB(2, 115))),
  379. new ECBlocks(28, array(new ECB(19, 46),
  380. new ECB(4, 47))),
  381. new ECBlocks(28, array(new ECB(28, 22),
  382. new ECB(6, 23))),
  383. new ECBlocks(30, array(new ECB(33, 16),
  384. new ECB(4, 17))))),
  385. new Version(27, array(6, 34, 62, 90, 118),
  386. array(new ECBlocks(30, array(new ECB(8, 122),
  387. new ECB(4, 123))),
  388. new ECBlocks(28, array(new ECB(22, 45),
  389. new ECB(3, 46))),
  390. new ECBlocks(30, array(new ECB(8, 23),
  391. new ECB(26, 24))),
  392. new ECBlocks(30, array(new ECB(12, 15),
  393. new ECB(28, 16))))),
  394. new Version(28, array(6, 26, 50, 74, 98, 122),
  395. array(new ECBlocks(30, array(new ECB(3, 117),
  396. new ECB(10, 118))),
  397. new ECBlocks(28, array(new ECB(3, 45),
  398. new ECB(23, 46))),
  399. new ECBlocks(30, array(new ECB(4, 24),
  400. new ECB(31, 25))),
  401. new ECBlocks(30, array(new ECB(11, 15),
  402. new ECB(31, 16))))),
  403. new Version(29, array(6, 30, 54, 78, 102, 126),
  404. array(new ECBlocks(30, array(new ECB(7, 116),
  405. new ECB(7, 117))),
  406. new ECBlocks(28, array(new ECB(21, 45),
  407. new ECB(7, 46))),
  408. new ECBlocks(30, array(new ECB(1, 23),
  409. new ECB(37, 24))),
  410. new ECBlocks(30, array(new ECB(19, 15),
  411. new ECB(26, 16))))),
  412. new Version(30, array(6, 26, 52, 78, 104, 130),
  413. array(new ECBlocks(30, array(new ECB(5, 115),
  414. new ECB(10, 116))),
  415. new ECBlocks(28, array(new ECB(19, 47),
  416. new ECB(10, 48))),
  417. new ECBlocks(30, array(new ECB(15, 24),
  418. new ECB(25, 25))),
  419. new ECBlocks(30, array(new ECB(23, 15),
  420. new ECB(25, 16))))),
  421. new Version(31, array(6, 30, 56, 82, 108, 134),
  422. array(new ECBlocks(30, array(new ECB(13, 115),
  423. new ECB(3, 116))),
  424. new ECBlocks(28, array(new ECB(2, 46),
  425. new ECB(29, 47))),
  426. new ECBlocks(30, array(new ECB(42, 24),
  427. new ECB(1, 25))),
  428. new ECBlocks(30, array(new ECB(23, 15),
  429. new ECB(28, 16))))),
  430. new Version(32, array(6, 34, 60, 86, 112, 138),
  431. array(new ECBlocks(30, array(new ECB(17, 115))),
  432. new ECBlocks(28, array(new ECB(10, 46),
  433. new ECB(23, 47))),
  434. new ECBlocks(30, array(new ECB(10, 24),
  435. new ECB(35, 25))),
  436. new ECBlocks(30, array(new ECB(19, 15),
  437. new ECB(35, 16))))),
  438. new Version(33, array(6, 30, 58, 86, 114, 142),
  439. array(new ECBlocks(30, array(new ECB(17, 115),
  440. new ECB(1, 116))),
  441. new ECBlocks(28, array(new ECB(14, 46),
  442. new ECB(21, 47))),
  443. new ECBlocks(30, array(new ECB(29, 24),
  444. new ECB(19, 25))),
  445. new ECBlocks(30, array(new ECB(11, 15),
  446. new ECB(46, 16))))),
  447. new Version(34, array(6, 34, 62, 90, 118, 146),
  448. array(new ECBlocks(30, array(new ECB(13, 115),
  449. new ECB(6, 116))),
  450. new ECBlocks(28, array(new ECB(14, 46),
  451. new ECB(23, 47))),
  452. new ECBlocks(30, array(new ECB(44, 24),
  453. new ECB(7, 25))),
  454. new ECBlocks(30, array(new ECB(59, 16),
  455. new ECB(1, 17))))),
  456. new Version(35, array(6, 30, 54, 78, 102, 126, 150),
  457. array(new ECBlocks(30, array(new ECB(12, 121),
  458. new ECB(7, 122))),
  459. new ECBlocks(28, array(new ECB(12, 47),
  460. new ECB(26, 48))),
  461. new ECBlocks(30, array(new ECB(39, 24),
  462. new ECB(14, 25))),
  463. new ECBlocks(30, array(new ECB(22, 15),
  464. new ECB(41, 16))))),
  465. new Version(36, array(6, 24, 50, 76, 102, 128, 154),
  466. array(new ECBlocks(30, array(new ECB(6, 121),
  467. new ECB(14, 122))),
  468. new ECBlocks(28, array(new ECB(6, 47),
  469. new ECB(34, 48))),
  470. new ECBlocks(30, array(new ECB(46, 24),
  471. new ECB(10, 25))),
  472. new ECBlocks(30, array(new ECB(2, 15),
  473. new ECB(64, 16))))),
  474. new Version(37, array(6, 28, 54, 80, 106, 132, 158),
  475. array(new ECBlocks(30, array(new ECB(17, 122),
  476. new ECB(4, 123))),
  477. new ECBlocks(28, array(new ECB(29, 46),
  478. new ECB(14, 47))),
  479. new ECBlocks(30, array(new ECB(49, 24),
  480. new ECB(10, 25))),
  481. new ECBlocks(30, array(new ECB(24, 15),
  482. new ECB(46, 16))))),
  483. new Version(38, array(6, 32, 58, 84, 110, 136, 162),
  484. array(new ECBlocks(30, array(new ECB(4, 122),
  485. new ECB(18, 123))),
  486. new ECBlocks(28, array(new ECB(13, 46),
  487. new ECB(32, 47))),
  488. new ECBlocks(30, array(new ECB(48, 24),
  489. new ECB(14, 25))),
  490. new ECBlocks(30, array(new ECB(42, 15),
  491. new ECB(32, 16))))),
  492. new Version(39, array(6, 26, 54, 82, 110, 138, 166),
  493. array(new ECBlocks(30, array(new ECB(20, 117),
  494. new ECB(4, 118))),
  495. new ECBlocks(28, array(new ECB(40, 47),
  496. new ECB(7, 48))),
  497. new ECBlocks(30, array(new ECB(43, 24),
  498. new ECB(22, 25))),
  499. new ECBlocks(30, array(new ECB(10, 15),
  500. new ECB(67, 16))))),
  501. new Version(40, array(6, 30, 58, 86, 114, 142, 170),
  502. array(new ECBlocks(30, array(new ECB(19, 118),
  503. new ECB(6, 119))),
  504. new ECBlocks(28, array(new ECB(18, 47),
  505. new ECB(31, 48))),
  506. new ECBlocks(30, array(new ECB(34, 24),
  507. new ECB(34, 25))),
  508. new ECBlocks(30, array(new ECB(20, 15),
  509. new ECB(61, 16)))))
  510. );
  511. }
  512. }
  513. /**
  514. * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
  515. * use blocks of differing sizes within one version, so, this encapsulates the parameters for
  516. * each set of blocks. It also holds the number of error-correction codewords per block since it
  517. * will be the same across all blocks within one version.</p>
  518. */
  519. final class ECBlocks
  520. {
  521. private $ecCodewordsPerBlock;
  522. private $ecBlocks;
  523. function __construct($ecCodewordsPerBlock, $ecBlocks)
  524. {
  525. $this->ecCodewordsPerBlock = $ecCodewordsPerBlock;
  526. $this->ecBlocks = $ecBlocks;
  527. }
  528. public function getECCodewordsPerBlock()
  529. {
  530. return $this->ecCodewordsPerBlock;
  531. }
  532. public function getNumBlocks()
  533. {
  534. $total = 0;
  535. foreach ($this->ecBlocks as $ecBlock) {
  536. $total += $ecBlock->getCount();
  537. }
  538. return $total;
  539. }
  540. public function getTotalECCodewords()
  541. {
  542. return $this->ecCodewordsPerBlock * $this->getNumBlocks();
  543. }
  544. public function getECBlocks()
  545. {
  546. return $this->ecBlocks;
  547. }
  548. }
  549. /**
  550. * <p>Encapsualtes the parameters for one error-correction block in one symbol version.
  551. * This includes the number of data codewords, and the number of times a block with these
  552. * parameters is used consecutively in the QR code version's format.</p>
  553. */
  554. final class ECB
  555. {
  556. private $count;
  557. private $dataCodewords;
  558. function __construct($count, $dataCodewords)
  559. {
  560. $this->count = $count;
  561. $this->dataCodewords = $dataCodewords;
  562. }
  563. public function getCount()
  564. {
  565. return $this->count;
  566. }
  567. public function getDataCodewords()
  568. {
  569. return $this->dataCodewords;
  570. }
  571. //@Override
  572. public function toString()
  573. {
  574. die('Version ECB toString()');
  575. // return parent::$versionNumber;
  576. }
  577. }