qr_encode.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275
  1. /*
  2. * Copyright (c) 2010 Psytec Inc.
  3. * Copyright (c) 2012 Alexey Mednyy <swexru@gmail.com>
  4. * Copyright (c) 2012-2014 Pavol Rusnak <stick@gk2.sk>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE.
  23. */
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <stdbool.h>
  27. #include "qr_encode.h"
  28. #include "qr_consts.h"
  29. static int m_nLevel;
  30. static int m_nVersion;
  31. static int m_nMaskingNo;
  32. static int m_ncDataCodeWordBit, m_ncAllCodeWord, nEncodeVersion;
  33. static int m_ncDataBlock;
  34. static int m_nSymbleSize;
  35. static int m_nBlockLength[QR_MAX_DATACODEWORD];
  36. static uint8_t m_byModuleData[QR_MAX_MODULESIZE][QR_MAX_MODULESIZE]; // [x][y]
  37. static uint8_t m_byAllCodeWord[QR_MAX_ALLCODEWORD];
  38. static uint8_t m_byBlockMode[QR_MAX_DATACODEWORD];
  39. static uint8_t m_byDataCodeWord[QR_MAX_DATACODEWORD];
  40. static uint8_t m_byRSWork[QR_MAX_CODEBLOCK];
  41. static int IsNumeralData(uint8_t c)
  42. {
  43. if (c >= '0' && c <= '9')
  44. return 1;
  45. return 0;
  46. }
  47. static int IsAlphabetData(uint8_t c)
  48. {
  49. if (c >= '0' && c <= '9')
  50. return 1;
  51. if (c >= 'A' && c <= 'Z')
  52. return 1;
  53. if (c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/' || c == ':')
  54. return 1;
  55. return 0;
  56. }
  57. static uint8_t AlphabetToBinary(uint8_t c)
  58. {
  59. if (c >= '0' && c <= '9')
  60. return (uint8_t)(c - '0');
  61. if (c >= 'A' && c <= 'Z')
  62. return (uint8_t)(c - 'A' + 10);
  63. if (c == ' ')
  64. return 36;
  65. if (c == '$')
  66. return 37;
  67. if (c == '%')
  68. return 38;
  69. if (c == '*')
  70. return 39;
  71. if (c == '+')
  72. return 40;
  73. if (c == '-')
  74. return 41;
  75. if (c == '.')
  76. return 42;
  77. if (c == '/')
  78. return 43;
  79. return 44; // c == ':'
  80. }
  81. static int SetBitStream(int nIndex, uint16_t wData, int ncData)
  82. {
  83. int i;
  84. if (nIndex == -1 || nIndex + ncData > QR_MAX_DATACODEWORD * 8)
  85. return -1;
  86. for (i = 0; i < ncData; i++)
  87. {
  88. if (wData & (1 << (ncData - i - 1)))
  89. {
  90. m_byDataCodeWord[(nIndex + i) / 8] |= 1 << (7 - ((nIndex + i) % 8));
  91. }
  92. }
  93. return nIndex + ncData;
  94. }
  95. static int GetBitLength(uint8_t nMode, int ncData, int nVerGroup)
  96. {
  97. int ncBits = 0;
  98. switch (nMode)
  99. {
  100. case QR_MODE_NUMERAL:
  101. ncBits = 4 + nIndicatorLenNumeral[nVerGroup] + (10 * (ncData / 3));
  102. switch (ncData % 3)
  103. {
  104. case 1:
  105. ncBits += 4;
  106. break;
  107. case 2:
  108. ncBits += 7;
  109. break;
  110. default: // case 0:
  111. break;
  112. }
  113. break;
  114. case QR_MODE_ALPHABET:
  115. ncBits = 4 + nIndicatorLenAlphabet[nVerGroup] + (11 * (ncData / 2)) + (6 * (ncData % 2));
  116. break;
  117. default: // case QR_MODE_8BIT:
  118. ncBits = 4 + nIndicatorLen8Bit[nVerGroup] + (8 * ncData);
  119. break;
  120. }
  121. return ncBits;
  122. }
  123. static int EncodeSourceData(const char *lpsSource, int ncLength, int nVerGroup)
  124. {
  125. memset(m_nBlockLength, 0, sizeof(m_nBlockLength));
  126. int i, j;
  127. // Investigate whether continuing characters (bytes) which mode is what
  128. for (m_ncDataBlock = i = 0; i < ncLength; i++)
  129. {
  130. uint8_t byMode;
  131. if (IsNumeralData(lpsSource[i]))
  132. {
  133. byMode = QR_MODE_NUMERAL;
  134. }
  135. else if (IsAlphabetData(lpsSource[i]))
  136. {
  137. byMode = QR_MODE_ALPHABET;
  138. }
  139. else
  140. {
  141. byMode = QR_MODE_8BIT;
  142. }
  143. if (i == 0)
  144. {
  145. m_byBlockMode[0] = byMode;
  146. }
  147. if (m_byBlockMode[m_ncDataBlock] != byMode)
  148. {
  149. m_byBlockMode[++m_ncDataBlock] = byMode;
  150. }
  151. m_nBlockLength[m_ncDataBlock]++;
  152. }
  153. m_ncDataBlock++;
  154. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  155. // Linked by a sequence of conditional block alphanumeric mode and numeric mode block adjacent
  156. int ncSrcBits, ncDstBits; // The bit length of the block mode if you have over the original bit length and a single alphanumeric
  157. int nBlock = 0;
  158. while (nBlock < m_ncDataBlock - 1)
  159. {
  160. int ncJoinFront, ncJoinBehind; // Bit length when combined with 8-bit byte block mode before and after
  161. int nJoinPosition = 0; // Block the binding of 8-bit byte mode: combined with the previous -1 = 0 = do not bind, bind behind a =
  162. // Sort of - "digit alphanumeric" - "or alphanumeric numbers"
  163. if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) ||
  164. (m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL))
  165. {
  166. // If you compare the bit length of alphanumeric characters and a single block mode over the original bit length
  167. ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
  168. GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);
  169. ncDstBits = GetBitLength(QR_MODE_ALPHABET, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);
  170. if (ncSrcBits > ncDstBits)
  171. {
  172. // If there is an 8-bit byte block mode back and forth, check whether they favor the binding of
  173. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
  174. {
  175. // There are 8-bit byte block mode before
  176. ncJoinFront = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock], nVerGroup) +
  177. GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);
  178. if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1], nVerGroup))
  179. {
  180. ncJoinFront = 0; // 8-bit byte and block mode does not bind
  181. }
  182. }
  183. else
  184. {
  185. ncJoinFront = 0;
  186. }
  187. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
  188. {
  189. // There are 8-bit byte mode block behind
  190. ncJoinBehind = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
  191. GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2], nVerGroup);
  192. if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 2], nVerGroup))
  193. {
  194. ncJoinBehind = 0; // 8-bit byte and block mode does not bind
  195. }
  196. }
  197. else
  198. {
  199. ncJoinBehind = 0;
  200. }
  201. if (ncJoinFront != 0 && ncJoinBehind != 0)
  202. {
  203. // If there is a 8-bit byte block mode has priority both before and after the way the data length is shorter
  204. nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1;
  205. }
  206. else
  207. {
  208. nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0);
  209. }
  210. if (nJoinPosition != 0)
  211. {
  212. // Block the binding of 8-bit byte mode
  213. if (nJoinPosition == -1)
  214. {
  215. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  216. // The subsequent shift
  217. for (i = nBlock; i < m_ncDataBlock - 1; i++)
  218. {
  219. m_byBlockMode[i] = m_byBlockMode[i + 1];
  220. m_nBlockLength[i] = m_nBlockLength[i + 1];
  221. }
  222. }
  223. else
  224. {
  225. m_byBlockMode[nBlock + 1] = QR_MODE_8BIT;
  226. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  227. // The subsequent shift
  228. for (i = nBlock + 2; i < m_ncDataBlock - 1; i++)
  229. {
  230. m_byBlockMode[i] = m_byBlockMode[i + 1];
  231. m_nBlockLength[i] = m_nBlockLength[i + 1];
  232. }
  233. }
  234. m_ncDataBlock--;
  235. }
  236. else
  237. {
  238. // Block mode integrated into a single alphanumeric string of numbers and alphanumeric
  239. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET)
  240. {
  241. // Binding mode of the block followed by alphanumeric block attempts to join
  242. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  243. // The subsequent shift
  244. for (i = nBlock + 2; i < m_ncDataBlock - 1; i++)
  245. {
  246. m_byBlockMode[i] = m_byBlockMode[i + 1];
  247. m_nBlockLength[i] = m_nBlockLength[i + 1];
  248. }
  249. m_ncDataBlock--;
  250. }
  251. m_byBlockMode[nBlock] = QR_MODE_ALPHABET;
  252. m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];
  253. // The subsequent shift
  254. for (i = nBlock + 1; i < m_ncDataBlock - 1; i++)
  255. {
  256. m_byBlockMode[i] = m_byBlockMode[i + 1];
  257. m_nBlockLength[i] = m_nBlockLength[i + 1];
  258. }
  259. m_ncDataBlock--;
  260. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET)
  261. {
  262. // Combined mode of alphanumeric block before the block bound
  263. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  264. // The subsequent shift
  265. for (i = nBlock; i < m_ncDataBlock - 1; i++)
  266. {
  267. m_byBlockMode[i] = m_byBlockMode[i + 1];
  268. m_nBlockLength[i] = m_nBlockLength[i + 1];
  269. }
  270. m_ncDataBlock--;
  271. }
  272. }
  273. continue;
  274. // Re-examine the block of the current position
  275. }
  276. }
  277. nBlock++; // Investigate the next block
  278. }
  279. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  280. // 8-bit byte block mode over the short block mode to continuous
  281. nBlock = 0;
  282. while (nBlock < m_ncDataBlock - 1)
  283. {
  284. ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);
  285. ncDstBits = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);
  286. // If there is a 8-bit byte block mode before, subtract the duplicate indicator minute
  287. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
  288. {
  289. ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
  290. }
  291. // If there is a block behind the 8-bit byte mode, subtract the duplicate indicator minute
  292. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
  293. {
  294. ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
  295. }
  296. if (ncSrcBits > ncDstBits)
  297. {
  298. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
  299. {
  300. // 8-bit byte mode coupling block in front of the block to join
  301. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  302. // The subsequent shift
  303. for (i = nBlock; i < m_ncDataBlock - 1; i++)
  304. {
  305. m_byBlockMode[i] = m_byBlockMode[i + 1];
  306. m_nBlockLength[i] = m_nBlockLength[i + 1];
  307. }
  308. m_ncDataBlock--;
  309. nBlock--;
  310. }
  311. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
  312. {
  313. // 8-bit byte mode coupling block at the back of the block to join
  314. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  315. // The subsequent shift
  316. for (i = nBlock + 2; i < m_ncDataBlock - 1; i++)
  317. {
  318. m_byBlockMode[i] = m_byBlockMode[i + 1];
  319. m_nBlockLength[i] = m_nBlockLength[i + 1];
  320. }
  321. m_ncDataBlock--;
  322. }
  323. m_byBlockMode[nBlock] = QR_MODE_8BIT;
  324. m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];
  325. // The subsequent shift
  326. for (i = nBlock + 1; i < m_ncDataBlock - 1; i++)
  327. {
  328. m_byBlockMode[i] = m_byBlockMode[i + 1];
  329. m_nBlockLength[i] = m_nBlockLength[i + 1];
  330. }
  331. m_ncDataBlock--;
  332. // Re-examination in front of the block bound
  333. if (nBlock >= 1)
  334. {
  335. nBlock--;
  336. }
  337. continue;
  338. }
  339. nBlock++; // Investigate the next block
  340. }
  341. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  342. // Mosquito bit array
  343. int ncComplete = 0; // Data pre-processing counter
  344. uint16_t wBinCode;
  345. m_ncDataCodeWordBit = 0; // Bit counter processing unit
  346. memset(m_byDataCodeWord, 0, sizeof(m_byDataCodeWord));
  347. for (i = 0; i < m_ncDataBlock && m_ncDataCodeWordBit != -1; i++)
  348. {
  349. if (m_byBlockMode[i] == QR_MODE_NUMERAL)
  350. {
  351. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  352. // Numeric mode
  353. // Indicator (0001b)
  354. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 1, 4);
  355. // Set number of characters
  356. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenNumeral[nVerGroup]);
  357. // Save the bit string
  358. for (j = 0; j < m_nBlockLength[i]; j += 3)
  359. {
  360. if (j < m_nBlockLength[i] - 2)
  361. {
  362. wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 100) +
  363. ((lpsSource[ncComplete + j + 1] - '0') * 10) +
  364. (lpsSource[ncComplete + j + 2] - '0'));
  365. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 10);
  366. }
  367. else if (j == m_nBlockLength[i] - 2)
  368. {
  369. // 2 bytes fraction
  370. wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 10) +
  371. (lpsSource[ncComplete + j + 1] - '0'));
  372. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 7);
  373. }
  374. else if (j == m_nBlockLength[i] - 1)
  375. {
  376. // A fraction of bytes
  377. wBinCode = (uint16_t)(lpsSource[ncComplete + j] - '0');
  378. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 4);
  379. }
  380. }
  381. ncComplete += m_nBlockLength[i];
  382. }
  383. else if (m_byBlockMode[i] == QR_MODE_ALPHABET)
  384. {
  385. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  386. // Alphanumeric mode
  387. // Mode indicator (0010b)
  388. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 2, 4);
  389. // Set number of characters
  390. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenAlphabet[nVerGroup]);
  391. // Save the bit string
  392. for (j = 0; j < m_nBlockLength[i]; j += 2)
  393. {
  394. if (j < m_nBlockLength[i] - 1)
  395. {
  396. wBinCode = (uint16_t)((AlphabetToBinary(lpsSource[ncComplete + j]) * 45) +
  397. AlphabetToBinary(lpsSource[ncComplete + j + 1]));
  398. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 11);
  399. }
  400. else
  401. {
  402. // A fraction of bytes
  403. wBinCode = (uint16_t)AlphabetToBinary(lpsSource[ncComplete + j]);
  404. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 6);
  405. }
  406. }
  407. ncComplete += m_nBlockLength[i];
  408. }
  409. else
  410. { // (m_byBlockMode[i] == QR_MODE_8BIT)
  411. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  412. // 8-bit byte mode
  413. // Mode indicator (0100b)
  414. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 4, 4);
  415. // Set number of characters
  416. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLen8Bit[nVerGroup]);
  417. // Save the bit string
  418. for (j = 0; j < m_nBlockLength[i]; j++)
  419. {
  420. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)lpsSource[ncComplete + j], 8);
  421. }
  422. ncComplete += m_nBlockLength[i];
  423. }
  424. }
  425. return (m_ncDataCodeWordBit != -1);
  426. }
  427. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  428. // APPLICATIONS: To get the bit length
  429. // Args: data mode type, data length, group version (model number)
  430. // Returns: data bit length
  431. static int GetEncodeVersion(int nVersion, const char *lpsSource, int ncLength)
  432. {
  433. int nVerGroup = nVersion >= 27 ? QR_VERSION_L : (nVersion >= 10 ? QR_VERSION_M : QR_VERSION_S);
  434. int i, j;
  435. for (i = nVerGroup; i <= QR_VERSION_L; i++)
  436. {
  437. if (EncodeSourceData(lpsSource, ncLength, i))
  438. {
  439. if (i == QR_VERSION_S)
  440. {
  441. for (j = 1; j <= 9; j++)
  442. {
  443. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel])
  444. {
  445. return j;
  446. }
  447. }
  448. }
  449. #if QR_MAX_VERSION >= QR_VERSION_M
  450. else if (i == QR_VERSION_M)
  451. {
  452. for (j = 10; j <= 26; j++)
  453. {
  454. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel])
  455. {
  456. return j;
  457. }
  458. }
  459. }
  460. #endif
  461. #if QR_MAX_VERSION >= QR_VERSION_L
  462. else if (i == QR_VERSION_L)
  463. {
  464. for (j = 27; j <= 40; j++)
  465. {
  466. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel])
  467. {
  468. return j;
  469. }
  470. }
  471. }
  472. #endif
  473. }
  474. }
  475. return 0;
  476. }
  477. static void GetRSCodeWord(uint8_t *lpbyRSWork, int ncDataCodeWord, int ncRSCodeWord)
  478. {
  479. int i, j;
  480. for (i = 0; i < ncDataCodeWord; i++)
  481. {
  482. if (lpbyRSWork[0] != 0)
  483. {
  484. uint8_t nExpFirst = byIntToExp[lpbyRSWork[0]]; // Multiplier coefficient is calculated from the first term
  485. for (j = 0; j < ncRSCodeWord; j++)
  486. {
  487. // Add (% 255 ^ 255 = 1) the first term multiplier to multiplier sections
  488. uint8_t nExpElement = (uint8_t)(((int)(byRSExp[ncRSCodeWord][j] + nExpFirst)) % 255);
  489. // Surplus calculated by the exclusive
  490. lpbyRSWork[j] = (uint8_t)(lpbyRSWork[j + 1] ^ byExpToInt[nExpElement]);
  491. }
  492. // Shift the remaining digits
  493. for (j = ncRSCodeWord; j < ncDataCodeWord + ncRSCodeWord - 1; j++)
  494. {
  495. lpbyRSWork[j] = lpbyRSWork[j + 1];
  496. }
  497. }
  498. else
  499. {
  500. // Shift the remaining digits
  501. for (j = 0; j < ncDataCodeWord + ncRSCodeWord - 1; j++)
  502. {
  503. lpbyRSWork[j] = lpbyRSWork[j + 1];
  504. }
  505. }
  506. }
  507. }
  508. static void SetFinderPattern(int x, int y)
  509. {
  510. static const uint8_t byPattern[] = {0x7f, // 1111111b
  511. 0x41, // 1000001b
  512. 0x5d, // 1011101b
  513. 0x5d, // 1011101b
  514. 0x5d, // 1011101b
  515. 0x41, // 1000001b
  516. 0x7f}; // 1111111b
  517. int i, j;
  518. for (i = 0; i < 7; i++)
  519. {
  520. for (j = 0; j < 7; j++)
  521. {
  522. m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (6 - j))) ? '\x30' : '\x20';
  523. }
  524. }
  525. }
  526. static void SetVersionPattern(void)
  527. {
  528. int i, j;
  529. if (m_nVersion <= 6)
  530. {
  531. return;
  532. }
  533. int nVerData = m_nVersion << 12;
  534. // Calculated bit remainder
  535. for (i = 0; i < 6; i++)
  536. {
  537. if (nVerData & (1 << (17 - i)))
  538. {
  539. nVerData ^= (0x1f25 << (5 - i));
  540. }
  541. }
  542. nVerData += m_nVersion << 12;
  543. for (i = 0; i < 6; i++)
  544. {
  545. for (j = 0; j < 3; j++)
  546. {
  547. m_byModuleData[m_nSymbleSize - 11 + j][i] = m_byModuleData[i][m_nSymbleSize - 11 + j] =
  548. (nVerData & (1 << (i * 3 + j))) ? '\x30' : '\x20';
  549. }
  550. }
  551. }
  552. static void SetAlignmentPattern(int x, int y)
  553. {
  554. static const uint8_t byPattern[] = {0x1f, // 11111b
  555. 0x11, // 10001b
  556. 0x15, // 10101b
  557. 0x11, // 10001b
  558. 0x1f}; // 11111b
  559. int i, j;
  560. if (m_byModuleData[x][y] & 0x20)
  561. {
  562. return; // Excluded due to overlap with the functional module
  563. }
  564. x -= 2;
  565. y -= 2; // Convert the coordinates to the upper left corner
  566. for (i = 0; i < 5; i++)
  567. {
  568. for (j = 0; j < 5; j++)
  569. {
  570. m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (4 - j))) ? '\x30' : '\x20';
  571. }
  572. }
  573. }
  574. static void SetFunctionModule(void)
  575. {
  576. int i, j;
  577. // Position detection pattern
  578. SetFinderPattern(0, 0);
  579. SetFinderPattern(m_nSymbleSize - 7, 0);
  580. SetFinderPattern(0, m_nSymbleSize - 7);
  581. // Separator pattern position detection
  582. for (i = 0; i < 8; i++)
  583. {
  584. m_byModuleData[i][7] = m_byModuleData[7][i] = '\x20';
  585. m_byModuleData[m_nSymbleSize - 8][i] = m_byModuleData[m_nSymbleSize - 8 + i][7] = '\x20';
  586. m_byModuleData[i][m_nSymbleSize - 8] = m_byModuleData[7][m_nSymbleSize - 8 + i] = '\x20';
  587. }
  588. // Registration as part of a functional module position description format information
  589. for (i = 0; i < 9; i++)
  590. {
  591. m_byModuleData[i][8] = m_byModuleData[8][i] = '\x20';
  592. }
  593. for (i = 0; i < 8; i++)
  594. {
  595. m_byModuleData[m_nSymbleSize - 8 + i][8] = m_byModuleData[8][m_nSymbleSize - 8 + i] = '\x20';
  596. }
  597. // Version information pattern
  598. SetVersionPattern();
  599. // Pattern alignment
  600. for (i = 0; i < QR_VersonInfo[m_nVersion].ncAlignPoint; i++)
  601. {
  602. SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], 6);
  603. SetAlignmentPattern(6, QR_VersonInfo[m_nVersion].nAlignPoint[i]);
  604. for (j = 0; j < QR_VersonInfo[m_nVersion].ncAlignPoint; j++)
  605. {
  606. SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], QR_VersonInfo[m_nVersion].nAlignPoint[j]);
  607. }
  608. }
  609. // Timing pattern
  610. for (i = 8; i <= m_nSymbleSize - 9; i++)
  611. {
  612. m_byModuleData[i][6] = (i % 2) == 0 ? '\x30' : '\x20';
  613. m_byModuleData[6][i] = (i % 2) == 0 ? '\x30' : '\x20';
  614. }
  615. }
  616. static void SetCodeWordPattern(void)
  617. {
  618. int x = m_nSymbleSize;
  619. int y = m_nSymbleSize - 1;
  620. int nCoef_x = 1; // placement orientation axis x
  621. int nCoef_y = 1; // placement orientation axis y
  622. int i, j;
  623. for (i = 0; i < m_ncAllCodeWord; i++)
  624. {
  625. for (j = 0; j < 8; j++)
  626. {
  627. do
  628. {
  629. x += nCoef_x;
  630. nCoef_x *= -1;
  631. if (nCoef_x < 0)
  632. {
  633. y += nCoef_y;
  634. if (y < 0 || y == m_nSymbleSize)
  635. {
  636. y = (y < 0) ? 0 : m_nSymbleSize - 1;
  637. nCoef_y *= -1;
  638. x -= 2;
  639. if (x == 6)
  640. { // Timing pattern
  641. x--;
  642. }
  643. }
  644. }
  645. } while (m_byModuleData[x][y] & 0x20); // Exclude a functional module
  646. m_byModuleData[x][y] = (m_byAllCodeWord[i] & (1 << (7 - j))) ? '\x02' : '\x00';
  647. }
  648. }
  649. }
  650. static void SetMaskingPattern(int nPatternNo)
  651. {
  652. int i, j;
  653. for (i = 0; i < m_nSymbleSize; i++)
  654. {
  655. for (j = 0; j < m_nSymbleSize; j++)
  656. {
  657. if (!(m_byModuleData[j][i] & 0x20))
  658. { // Exclude a functional module
  659. int bMask;
  660. switch (nPatternNo)
  661. {
  662. case 0:
  663. bMask = ((i + j) % 2 == 0);
  664. break;
  665. case 1:
  666. bMask = (i % 2 == 0);
  667. break;
  668. case 2:
  669. bMask = (j % 3 == 0);
  670. break;
  671. case 3:
  672. bMask = ((i + j) % 3 == 0);
  673. break;
  674. case 4:
  675. bMask = (((i / 2) + (j / 3)) % 2 == 0);
  676. break;
  677. case 5:
  678. bMask = (((i * j) % 2) + ((i * j) % 3) == 0);
  679. break;
  680. case 6:
  681. bMask = ((((i * j) % 2) + ((i * j) % 3)) % 2 == 0);
  682. break;
  683. default: // case 7:
  684. bMask = ((((i * j) % 3) + ((i + j) % 2)) % 2 == 0);
  685. break;
  686. }
  687. m_byModuleData[j][i] = (uint8_t)((m_byModuleData[j][i] & 0xfe) | (((m_byModuleData[j][i] & 0x02) > 1) ^ bMask));
  688. }
  689. }
  690. }
  691. }
  692. static void SetFormatInfoPattern(int nPatternNo)
  693. {
  694. int nFormatInfo;
  695. int i;
  696. switch (m_nLevel)
  697. {
  698. case QR_LEVEL_L:
  699. nFormatInfo = 0x08; // 01nnnb
  700. break;
  701. case QR_LEVEL_M:
  702. nFormatInfo = 0x00; // 00nnnb
  703. break;
  704. case QR_LEVEL_Q:
  705. nFormatInfo = 0x18; // 11nnnb
  706. break;
  707. default: // case QR_LEVEL_H:
  708. nFormatInfo = 0x10; // 10nnnb
  709. break;
  710. }
  711. nFormatInfo += nPatternNo;
  712. int nFormatData = nFormatInfo << 10;
  713. // Calculated bit remainder
  714. for (i = 0; i < 5; i++)
  715. {
  716. if (nFormatData & (1 << (14 - i)))
  717. {
  718. nFormatData ^= (0x0537 << (4 - i)); // 10100110111b
  719. }
  720. }
  721. nFormatData += nFormatInfo << 10;
  722. // Masking
  723. nFormatData ^= 0x5412; // 101010000010010b
  724. // Position detection patterns located around the upper left
  725. for (i = 0; i <= 5; i++)
  726. {
  727. m_byModuleData[8][i] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  728. }
  729. m_byModuleData[8][7] = (nFormatData & (1 << 6)) ? '\x30' : '\x20';
  730. m_byModuleData[8][8] = (nFormatData & (1 << 7)) ? '\x30' : '\x20';
  731. m_byModuleData[7][8] = (nFormatData & (1 << 8)) ? '\x30' : '\x20';
  732. for (i = 9; i <= 14; i++)
  733. {
  734. m_byModuleData[14 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  735. }
  736. // Position detection patterns located under the upper right corner
  737. for (i = 0; i <= 7; i++)
  738. {
  739. m_byModuleData[m_nSymbleSize - 1 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  740. }
  741. // Right lower left position detection patterns located
  742. m_byModuleData[8][m_nSymbleSize - 8] = '\x30'; // Module fixed dark
  743. for (i = 8; i <= 14; i++)
  744. {
  745. m_byModuleData[8][m_nSymbleSize - 15 + i] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  746. }
  747. }
  748. static int CountPenalty(void)
  749. {
  750. int nPenalty = 0;
  751. int i, j, k;
  752. // Column of the same color adjacent module
  753. for (i = 0; i < m_nSymbleSize; i++)
  754. {
  755. for (j = 0; j < m_nSymbleSize - 4; j++)
  756. {
  757. int nCount = 1;
  758. for (k = j + 1; k < m_nSymbleSize; k++)
  759. {
  760. if (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][k] & 0x11) == 0))
  761. {
  762. nCount++;
  763. }
  764. else
  765. {
  766. break;
  767. }
  768. }
  769. if (nCount >= 5)
  770. {
  771. nPenalty += 3 + (nCount - 5);
  772. }
  773. j = k - 1;
  774. }
  775. }
  776. // Adjacent module line of the same color
  777. for (i = 0; i < m_nSymbleSize; i++)
  778. {
  779. for (j = 0; j < m_nSymbleSize - 4; j++)
  780. {
  781. int nCount = 1;
  782. for (k = j + 1; k < m_nSymbleSize; k++)
  783. {
  784. if (((m_byModuleData[j][i] & 0x11) == 0) == ((m_byModuleData[k][i] & 0x11) == 0))
  785. {
  786. nCount++;
  787. }
  788. else
  789. {
  790. break;
  791. }
  792. }
  793. if (nCount >= 5)
  794. {
  795. nPenalty += 3 + (nCount - 5);
  796. }
  797. j = k - 1;
  798. }
  799. }
  800. // Modules of the same color block (2 ~ 2)
  801. for (i = 0; i < m_nSymbleSize - 1; i++)
  802. {
  803. for (j = 0; j < m_nSymbleSize - 1; j++)
  804. {
  805. if ((((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j] & 0x11) == 0)) &&
  806. (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][j + 1] & 0x11) == 0)) &&
  807. (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j + 1] & 0x11) == 0)))
  808. {
  809. nPenalty += 3;
  810. }
  811. }
  812. }
  813. // Pattern (dark dark: light: dark: light) ratio 1:1:3:1:1 in the same column
  814. for (i = 0; i < m_nSymbleSize; i++)
  815. {
  816. for (j = 0; j < m_nSymbleSize - 6; j++)
  817. {
  818. if (((j == 0) || (!(m_byModuleData[i][j - 1] & 0x11))) &&
  819. (m_byModuleData[i][j] & 0x11) &&
  820. (!(m_byModuleData[i][j + 1] & 0x11)) &&
  821. (m_byModuleData[i][j + 2] & 0x11) &&
  822. (m_byModuleData[i][j + 3] & 0x11) &&
  823. (m_byModuleData[i][j + 4] & 0x11) &&
  824. (!(m_byModuleData[i][j + 5] & 0x11)) &&
  825. (m_byModuleData[i][j + 6] & 0x11) &&
  826. ((j == m_nSymbleSize - 7) || (!(m_byModuleData[i][j + 7] & 0x11))))
  827. {
  828. // Clear pattern of four or more before or after
  829. if (((j < 2 || !(m_byModuleData[i][j - 2] & 0x11)) &&
  830. (j < 3 || !(m_byModuleData[i][j - 3] & 0x11)) &&
  831. (j < 4 || !(m_byModuleData[i][j - 4] & 0x11))) ||
  832. ((j >= m_nSymbleSize - 8 || !(m_byModuleData[i][j + 8] & 0x11)) &&
  833. (j >= m_nSymbleSize - 9 || !(m_byModuleData[i][j + 9] & 0x11)) &&
  834. (j >= m_nSymbleSize - 10 || !(m_byModuleData[i][j + 10] & 0x11))))
  835. {
  836. nPenalty += 40;
  837. }
  838. }
  839. }
  840. }
  841. // Pattern (dark dark: light: dark: light) in the same line ratio 1:1:3:1:1
  842. for (i = 0; i < m_nSymbleSize; i++)
  843. {
  844. for (j = 0; j < m_nSymbleSize - 6; j++)
  845. {
  846. if (((j == 0) || (!(m_byModuleData[j - 1][i] & 0x11))) &&
  847. (m_byModuleData[j][i] & 0x11) &&
  848. (!(m_byModuleData[j + 1][i] & 0x11)) &&
  849. (m_byModuleData[j + 2][i] & 0x11) &&
  850. (m_byModuleData[j + 3][i] & 0x11) &&
  851. (m_byModuleData[j + 4][i] & 0x11) &&
  852. (!(m_byModuleData[j + 5][i] & 0x11)) &&
  853. (m_byModuleData[j + 6][i] & 0x11) &&
  854. ((j == m_nSymbleSize - 7) || (!(m_byModuleData[j + 7][i] & 0x11))))
  855. {
  856. // Clear pattern of four or more before or after
  857. if (((j < 2 || !(m_byModuleData[j - 2][i] & 0x11)) &&
  858. (j < 3 || !(m_byModuleData[j - 3][i] & 0x11)) &&
  859. (j < 4 || !(m_byModuleData[j - 4][i] & 0x11))) ||
  860. ((j >= m_nSymbleSize - 8 || !(m_byModuleData[j + 8][i] & 0x11)) &&
  861. (j >= m_nSymbleSize - 9 || !(m_byModuleData[j + 9][i] & 0x11)) &&
  862. (j >= m_nSymbleSize - 10 || !(m_byModuleData[j + 10][i] & 0x11))))
  863. {
  864. nPenalty += 40;
  865. }
  866. }
  867. }
  868. }
  869. // The proportion of modules for the entire dark
  870. int nCount = 0;
  871. for (i = 0; i < m_nSymbleSize; i++)
  872. {
  873. for (j = 0; j < m_nSymbleSize; j++)
  874. {
  875. if (!(m_byModuleData[i][j] & 0x11))
  876. {
  877. nCount++;
  878. }
  879. }
  880. }
  881. nPenalty += (abs(50 - ((nCount * 100) / (m_nSymbleSize * m_nSymbleSize))) / 5) * 10;
  882. return nPenalty;
  883. }
  884. static void FormatModule(void)
  885. {
  886. int i, j;
  887. memset(m_byModuleData, 0, sizeof(m_byModuleData));
  888. // Function module placement
  889. SetFunctionModule();
  890. // Data placement
  891. SetCodeWordPattern();
  892. if (m_nMaskingNo == -1)
  893. {
  894. // Select the best pattern masking
  895. m_nMaskingNo = 0;
  896. SetMaskingPattern(m_nMaskingNo); // Masking
  897. SetFormatInfoPattern(m_nMaskingNo); // Placement pattern format information
  898. int nMinPenalty = CountPenalty();
  899. for (i = 1; i <= 7; i++)
  900. {
  901. SetMaskingPattern(i); // Masking
  902. SetFormatInfoPattern(i); // Placement pattern format information
  903. int nPenalty = CountPenalty();
  904. if (nPenalty < nMinPenalty)
  905. {
  906. nMinPenalty = nPenalty;
  907. m_nMaskingNo = i;
  908. }
  909. }
  910. }
  911. SetMaskingPattern(m_nMaskingNo); // Masking
  912. SetFormatInfoPattern(m_nMaskingNo); // Placement pattern format information
  913. // The module pattern converted to a Boolean value
  914. for (i = 0; i < m_nSymbleSize; i++)
  915. {
  916. for (j = 0; j < m_nSymbleSize; j++)
  917. {
  918. m_byModuleData[i][j] = (uint8_t)((m_byModuleData[i][j] & 0x11) != 0);
  919. }
  920. }
  921. }
  922. static void putBitToPos(uint32_t pos, int bw, uint8_t *bits)
  923. {
  924. if (bw == 0)
  925. return;
  926. uint32_t tmp;
  927. uint32_t bitpos[8] = {128, 64, 32, 16, 8, 4, 2, 1};
  928. if (pos % 8 == 0)
  929. {
  930. tmp = (pos / 8) - 1;
  931. bits[tmp] = bits[tmp] ^ bitpos[7];
  932. }
  933. else
  934. {
  935. tmp = pos / 8;
  936. bits[tmp] = bits[tmp] ^ bitpos[pos % 8 - 1];
  937. }
  938. }
  939. int qr_encode(int level, int version, const char *source, size_t source_len, uint8_t *result)
  940. {
  941. int i, j;
  942. const bool auto_extent = 0;
  943. m_nLevel = level;
  944. m_nMaskingNo = -1;
  945. memset(result, 0, QR_MAX_BITDATA);
  946. // If the data length is not specified, acquired by lstrlen
  947. size_t ncLength = source_len > 0 ? source_len : strlen(source);
  948. if (ncLength == 0)
  949. {
  950. return -1; // No data
  951. }
  952. // Check version (model number)
  953. nEncodeVersion = GetEncodeVersion(version, source, ncLength);
  954. if (nEncodeVersion == 0)
  955. {
  956. return -1; // Over-capacity
  957. }
  958. if (version == 0)
  959. {
  960. // Auto Part
  961. m_nVersion = nEncodeVersion;
  962. }
  963. else
  964. {
  965. if (nEncodeVersion <= version)
  966. {
  967. m_nVersion = version;
  968. }
  969. else
  970. {
  971. if (auto_extent)
  972. {
  973. m_nVersion = nEncodeVersion; // Automatic extended version (model number)
  974. }
  975. else
  976. {
  977. return -1; // Over-capacity
  978. }
  979. }
  980. }
  981. // Terminator addition code "0000"
  982. int ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[level];
  983. int ncTerminater = (ncDataCodeWord * 8) - m_ncDataCodeWordBit;
  984. if (ncTerminater < 4)
  985. {
  986. ncTerminater = 4;
  987. }
  988. if (ncTerminater > 0)
  989. {
  990. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 0, ncTerminater);
  991. }
  992. // Additional padding code "11101100, 00010001"
  993. uint8_t byPaddingCode = 0xec;
  994. for (i = (m_ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; i++)
  995. {
  996. m_byDataCodeWord[i] = byPaddingCode;
  997. byPaddingCode = (uint8_t)(byPaddingCode == 0xec ? 0x11 : 0xec);
  998. }
  999. // Calculated the total clear area code word
  1000. m_ncAllCodeWord = QR_VersonInfo[m_nVersion].ncAllCodeWord;
  1001. memset(m_byAllCodeWord, 0, sizeof(m_byAllCodeWord));
  1002. int nDataCwIndex = 0; // Position data processing code word
  1003. // Division number data block
  1004. int ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncRSBlock;
  1005. int ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncRSBlock;
  1006. int ncBlockSum = ncBlock1 + ncBlock2;
  1007. int nBlockNo = 0; // Block number in the process
  1008. // The number of data code words by block
  1009. int ncDataCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncDataCodeWord;
  1010. int ncDataCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncDataCodeWord;
  1011. // Code word interleaving data placement
  1012. for (i = 0; i < ncBlock1; i++)
  1013. {
  1014. for (j = 0; j < ncDataCw1; j++)
  1015. {
  1016. m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
  1017. }
  1018. nBlockNo++;
  1019. }
  1020. for (i = 0; i < ncBlock2; i++)
  1021. {
  1022. for (j = 0; j < ncDataCw2; j++)
  1023. {
  1024. if (j < ncDataCw1)
  1025. {
  1026. m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
  1027. }
  1028. else
  1029. {
  1030. // 2 minute fraction block placement event
  1031. m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] = m_byDataCodeWord[nDataCwIndex++];
  1032. }
  1033. }
  1034. nBlockNo++;
  1035. }
  1036. // RS code words by block number (currently the same number)
  1037. int ncRSCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncAllCodeWord - ncDataCw1;
  1038. int ncRSCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncAllCodeWord - ncDataCw2;
  1039. // RS code word is calculated
  1040. nDataCwIndex = 0;
  1041. nBlockNo = 0;
  1042. for (i = 0; i < ncBlock1; i++)
  1043. {
  1044. memset(m_byRSWork, 0, sizeof(m_byRSWork));
  1045. memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw1);
  1046. GetRSCodeWord(m_byRSWork, ncDataCw1, ncRSCw1);
  1047. // RS code word placement
  1048. for (j = 0; j < ncRSCw1; j++)
  1049. {
  1050. m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
  1051. }
  1052. nDataCwIndex += ncDataCw1;
  1053. nBlockNo++;
  1054. }
  1055. for (i = 0; i < ncBlock2; i++)
  1056. {
  1057. memset(m_byRSWork, 0, sizeof(m_byRSWork));
  1058. memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw2);
  1059. GetRSCodeWord(m_byRSWork, ncDataCw2, ncRSCw2);
  1060. // RS code word placement
  1061. for (j = 0; j < ncRSCw2; j++)
  1062. {
  1063. m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
  1064. }
  1065. nDataCwIndex += ncDataCw2;
  1066. nBlockNo++;
  1067. }
  1068. m_nSymbleSize = m_nVersion * 4 + 17;
  1069. // Module placement
  1070. FormatModule();
  1071. for (i = 0; i < m_nSymbleSize; i++)
  1072. {
  1073. for (j = 0; j < m_nSymbleSize; j++)
  1074. {
  1075. if (!m_byModuleData[i][j])
  1076. {
  1077. putBitToPos((j * m_nSymbleSize) + i + 1, 0, result);
  1078. }
  1079. else
  1080. {
  1081. putBitToPos((j * m_nSymbleSize) + i + 1, 1, result);
  1082. }
  1083. }
  1084. }
  1085. return m_nSymbleSize;
  1086. }