qr_encode.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  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') return 1;
  44. return 0;
  45. }
  46. static int IsAlphabetData(uint8_t c)
  47. {
  48. if (c >= '0' && c <= '9') return 1;
  49. if (c >= 'A' && c <= 'Z') return 1;
  50. if (c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/' || c == ':') return 1;
  51. return 0;
  52. }
  53. static uint8_t AlphabetToBinary(uint8_t c)
  54. {
  55. if (c >= '0' && c <= '9') return (uint8_t)(c - '0');
  56. if (c >= 'A' && c <= 'Z') return (uint8_t)(c - 'A' + 10);
  57. if (c == ' ') return 36;
  58. if (c == '$') return 37;
  59. if (c == '%') return 38;
  60. if (c == '*') return 39;
  61. if (c == '+') return 40;
  62. if (c == '-') return 41;
  63. if (c == '.') return 42;
  64. if (c == '/') return 43;
  65. return 44; // c == ':'
  66. }
  67. static int SetBitStream(int nIndex, uint16_t wData, int ncData)
  68. {
  69. int i;
  70. if (nIndex == -1 || nIndex + ncData > QR_MAX_DATACODEWORD * 8) return -1;
  71. for (i = 0; i < ncData; i++) {
  72. if (wData & (1 << (ncData - i - 1))) {
  73. m_byDataCodeWord[(nIndex + i) / 8] |= 1 << (7 - ((nIndex + i) % 8));
  74. }
  75. }
  76. return nIndex + ncData;
  77. }
  78. static int GetBitLength(uint8_t nMode, int ncData, int nVerGroup)
  79. {
  80. int ncBits = 0;
  81. switch (nMode) {
  82. case QR_MODE_NUMERAL:
  83. ncBits = 4 + nIndicatorLenNumeral[nVerGroup] + (10 * (ncData / 3));
  84. switch (ncData % 3) {
  85. case 1:
  86. ncBits += 4;
  87. break;
  88. case 2:
  89. ncBits += 7;
  90. break;
  91. default: // case 0:
  92. break;
  93. }
  94. break;
  95. case QR_MODE_ALPHABET:
  96. ncBits = 4 + nIndicatorLenAlphabet[nVerGroup] + (11 * (ncData / 2)) + (6 * (ncData % 2));
  97. break;
  98. default: // case QR_MODE_8BIT:
  99. ncBits = 4 + nIndicatorLen8Bit[nVerGroup] + (8 * ncData);
  100. break;
  101. }
  102. return ncBits;
  103. }
  104. static int EncodeSourceData(const char* lpsSource, int ncLength, int nVerGroup)
  105. {
  106. memset(m_nBlockLength, 0, sizeof(m_nBlockLength));
  107. int i, j;
  108. // Investigate whether continuing characters (bytes) which mode is what
  109. for (m_ncDataBlock = i = 0; i < ncLength; i++) {
  110. uint8_t byMode;
  111. if (IsNumeralData(lpsSource[i])) {
  112. byMode = QR_MODE_NUMERAL;
  113. } else if (IsAlphabetData(lpsSource[i])) {
  114. byMode = QR_MODE_ALPHABET;
  115. } else {
  116. byMode = QR_MODE_8BIT;
  117. }
  118. if (i == 0) {
  119. m_byBlockMode[0] = byMode;
  120. }
  121. if (m_byBlockMode[m_ncDataBlock] != byMode) {
  122. m_byBlockMode[++m_ncDataBlock] = byMode;
  123. }
  124. m_nBlockLength[m_ncDataBlock]++;
  125. }
  126. m_ncDataBlock++;
  127. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  128. // Linked by a sequence of conditional block alphanumeric mode and numeric mode block adjacent
  129. int ncSrcBits, ncDstBits; // The bit length of the block mode if you have over the original bit length and a single alphanumeric
  130. int nBlock = 0;
  131. while (nBlock < m_ncDataBlock - 1) {
  132. int ncJoinFront, ncJoinBehind; // Bit length when combined with 8-bit byte block mode before and after
  133. int nJoinPosition = 0; // Block the binding of 8-bit byte mode: combined with the previous -1 = 0 = do not bind, bind behind a =
  134. // Sort of - "digit alphanumeric" - "or alphanumeric numbers"
  135. if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) ||
  136. (m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL)) {
  137. // If you compare the bit length of alphanumeric characters and a single block mode over the original bit length
  138. ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
  139. GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);
  140. ncDstBits = GetBitLength(QR_MODE_ALPHABET, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);
  141. if (ncSrcBits > ncDstBits) {
  142. // If there is an 8-bit byte block mode back and forth, check whether they favor the binding of
  143. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) {
  144. // There are 8-bit byte block mode before
  145. ncJoinFront = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock], nVerGroup) +
  146. GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);
  147. if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1], nVerGroup)) {
  148. ncJoinFront = 0; // 8-bit byte and block mode does not bind
  149. }
  150. } else {
  151. ncJoinFront = 0;
  152. }
  153. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) {
  154. // There are 8-bit byte mode block behind
  155. ncJoinBehind = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
  156. GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2], nVerGroup);
  157. if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 2], nVerGroup)) {
  158. ncJoinBehind = 0; // 8-bit byte and block mode does not bind
  159. }
  160. } else {
  161. ncJoinBehind = 0;
  162. }
  163. if (ncJoinFront != 0 && ncJoinBehind != 0) {
  164. // If there is a 8-bit byte block mode has priority both before and after the way the data length is shorter
  165. nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1;
  166. } else {
  167. nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0);
  168. }
  169. if (nJoinPosition != 0) {
  170. // Block the binding of 8-bit byte mode
  171. if (nJoinPosition == -1) {
  172. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  173. // The subsequent shift
  174. for (i = nBlock; i < m_ncDataBlock - 1; i++) {
  175. m_byBlockMode[i] = m_byBlockMode[i + 1];
  176. m_nBlockLength[i] = m_nBlockLength[i + 1];
  177. }
  178. } else {
  179. m_byBlockMode[nBlock + 1] = QR_MODE_8BIT;
  180. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  181. // The subsequent shift
  182. for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) {
  183. m_byBlockMode[i] = m_byBlockMode[i + 1];
  184. m_nBlockLength[i] = m_nBlockLength[i + 1];
  185. }
  186. }
  187. m_ncDataBlock--;
  188. } else {
  189. // Block mode integrated into a single alphanumeric string of numbers and alphanumeric
  190. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET) {
  191. // Binding mode of the block followed by alphanumeric block attempts to join
  192. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  193. // The subsequent shift
  194. for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) {
  195. m_byBlockMode[i] = m_byBlockMode[i + 1];
  196. m_nBlockLength[i] = m_nBlockLength[i + 1];
  197. }
  198. m_ncDataBlock--;
  199. }
  200. m_byBlockMode[nBlock] = QR_MODE_ALPHABET;
  201. m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];
  202. // The subsequent shift
  203. for (i = nBlock + 1; i < m_ncDataBlock - 1; i++) {
  204. m_byBlockMode[i] = m_byBlockMode[i + 1];
  205. m_nBlockLength[i] = m_nBlockLength[i + 1];
  206. }
  207. m_ncDataBlock--;
  208. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET) {
  209. // Combined mode of alphanumeric block before the block bound
  210. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  211. // The subsequent shift
  212. for (i = nBlock; i < m_ncDataBlock - 1; i++) {
  213. m_byBlockMode[i] = m_byBlockMode[i + 1];
  214. m_nBlockLength[i] = m_nBlockLength[i + 1];
  215. }
  216. m_ncDataBlock--;
  217. }
  218. }
  219. continue;
  220. // Re-examine the block of the current position
  221. }
  222. }
  223. nBlock++; // Investigate the next block
  224. }
  225. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  226. // 8-bit byte block mode over the short block mode to continuous
  227. nBlock = 0;
  228. while (nBlock < m_ncDataBlock - 1) {
  229. ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup)
  230. + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);
  231. ncDstBits = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);
  232. // If there is a 8-bit byte block mode before, subtract the duplicate indicator minute
  233. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) {
  234. ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
  235. }
  236. // If there is a block behind the 8-bit byte mode, subtract the duplicate indicator minute
  237. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) {
  238. ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
  239. }
  240. if (ncSrcBits > ncDstBits) {
  241. if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) {
  242. // 8-bit byte mode coupling block in front of the block to join
  243. m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];
  244. // The subsequent shift
  245. for (i = nBlock; i < m_ncDataBlock - 1; i++) {
  246. m_byBlockMode[i] = m_byBlockMode[i + 1];
  247. m_nBlockLength[i] = m_nBlockLength[i + 1];
  248. }
  249. m_ncDataBlock--;
  250. nBlock--;
  251. }
  252. if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) {
  253. // 8-bit byte mode coupling block at the back of the block to join
  254. m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];
  255. // The subsequent shift
  256. for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) {
  257. m_byBlockMode[i] = m_byBlockMode[i + 1];
  258. m_nBlockLength[i] = m_nBlockLength[i + 1];
  259. }
  260. m_ncDataBlock--;
  261. }
  262. m_byBlockMode[nBlock] = QR_MODE_8BIT;
  263. m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];
  264. // The subsequent shift
  265. for (i = nBlock + 1; i < m_ncDataBlock - 1; i++) {
  266. m_byBlockMode[i] = m_byBlockMode[i + 1];
  267. m_nBlockLength[i] = m_nBlockLength[i + 1];
  268. }
  269. m_ncDataBlock--;
  270. // Re-examination in front of the block bound
  271. if (nBlock >= 1) {
  272. nBlock--;
  273. }
  274. continue;
  275. }
  276. nBlock++;// Investigate the next block
  277. }
  278. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  279. // Mosquito bit array
  280. int ncComplete = 0; // Data pre-processing counter
  281. uint16_t wBinCode;
  282. m_ncDataCodeWordBit = 0;// Bit counter processing unit
  283. memset(m_byDataCodeWord, 0, sizeof(m_byDataCodeWord));
  284. for (i = 0; i < m_ncDataBlock && m_ncDataCodeWordBit != -1; i++) {
  285. if (m_byBlockMode[i] == QR_MODE_NUMERAL) {
  286. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  287. // Numeric mode
  288. // Indicator (0001b)
  289. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 1, 4);
  290. // Set number of characters
  291. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenNumeral[nVerGroup]);
  292. // Save the bit string
  293. for (j = 0; j < m_nBlockLength[i]; j += 3) {
  294. if (j < m_nBlockLength[i] - 2) {
  295. wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 100) +
  296. ((lpsSource[ncComplete + j + 1] - '0') * 10) +
  297. (lpsSource[ncComplete + j + 2] - '0'));
  298. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 10);
  299. } else
  300. if (j == m_nBlockLength[i] - 2) {
  301. // 2 bytes fraction
  302. wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 10) +
  303. (lpsSource[ncComplete + j + 1] - '0'));
  304. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 7);
  305. } else
  306. if (j == m_nBlockLength[i] - 1) {
  307. // A fraction of bytes
  308. wBinCode = (uint16_t)(lpsSource[ncComplete + j] - '0');
  309. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 4);
  310. }
  311. }
  312. ncComplete += m_nBlockLength[i];
  313. }
  314. else
  315. if (m_byBlockMode[i] == QR_MODE_ALPHABET) {
  316. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  317. // Alphanumeric mode
  318. // Mode indicator (0010b)
  319. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 2, 4);
  320. // Set number of characters
  321. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenAlphabet[nVerGroup]);
  322. // Save the bit string
  323. for (j = 0; j < m_nBlockLength[i]; j += 2) {
  324. if (j < m_nBlockLength[i] - 1) {
  325. wBinCode = (uint16_t)((AlphabetToBinary(lpsSource[ncComplete + j]) * 45) +
  326. AlphabetToBinary(lpsSource[ncComplete + j + 1]));
  327. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 11);
  328. } else {
  329. // A fraction of bytes
  330. wBinCode = (uint16_t)AlphabetToBinary(lpsSource[ncComplete + j]);
  331. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 6);
  332. }
  333. }
  334. ncComplete += m_nBlockLength[i];
  335. }
  336. else { // (m_byBlockMode[i] == QR_MODE_8BIT)
  337. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  338. // 8-bit byte mode
  339. // Mode indicator (0100b)
  340. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 4, 4);
  341. // Set number of characters
  342. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLen8Bit[nVerGroup]);
  343. // Save the bit string
  344. for (j = 0; j < m_nBlockLength[i]; j++) {
  345. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)lpsSource[ncComplete + j], 8);
  346. }
  347. ncComplete += m_nBlockLength[i];
  348. }
  349. }
  350. return (m_ncDataCodeWordBit != -1);
  351. }
  352. // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
  353. // APPLICATIONS: To get the bit length
  354. // Args: data mode type, data length, group version (model number)
  355. // Returns: data bit length
  356. static int GetEncodeVersion(int nVersion, const char* lpsSource, int ncLength)
  357. {
  358. int nVerGroup = nVersion >= 27 ? QR_VERSION_L : (nVersion >= 10 ? QR_VERSION_M : QR_VERSION_S);
  359. int i, j;
  360. for (i = nVerGroup; i <= QR_VERSION_L; i++) {
  361. if (EncodeSourceData(lpsSource, ncLength, i)) {
  362. if (i == QR_VERSION_S) {
  363. for (j = 1; j <= 9; j++) {
  364. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) {
  365. return j;
  366. }
  367. }
  368. }
  369. #if QR_MAX_VERSION >= QR_VERSION_M
  370. else
  371. if (i == QR_VERSION_M) {
  372. for (j = 10; j <= 26; j++) {
  373. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) {
  374. return j;
  375. }
  376. }
  377. }
  378. #endif
  379. #if QR_MAX_VERSION >= QR_VERSION_L
  380. else
  381. if (i == QR_VERSION_L) {
  382. for (j = 27; j <= 40; j++) {
  383. if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) {
  384. return j;
  385. }
  386. }
  387. }
  388. #endif
  389. }
  390. }
  391. return 0;
  392. }
  393. static void GetRSCodeWord(uint8_t* lpbyRSWork, int ncDataCodeWord, int ncRSCodeWord)
  394. {
  395. int i, j;
  396. for (i = 0; i < ncDataCodeWord ; i++) {
  397. if (lpbyRSWork[0] != 0) {
  398. uint8_t nExpFirst = byIntToExp[lpbyRSWork[0]]; // Multiplier coefficient is calculated from the first term
  399. for (j = 0; j < ncRSCodeWord; j++) {
  400. // Add (% 255 ^ 255 = 1) the first term multiplier to multiplier sections
  401. uint8_t nExpElement = (uint8_t)(((int)(byRSExp[ncRSCodeWord][j] + nExpFirst)) % 255);
  402. // Surplus calculated by the exclusive
  403. lpbyRSWork[j] = (uint8_t)(lpbyRSWork[j + 1] ^ byExpToInt[nExpElement]);
  404. }
  405. // Shift the remaining digits
  406. for (j = ncRSCodeWord; j < ncDataCodeWord + ncRSCodeWord - 1; j++) {
  407. lpbyRSWork[j] = lpbyRSWork[j + 1];
  408. }
  409. } else {
  410. // Shift the remaining digits
  411. for (j = 0; j < ncDataCodeWord + ncRSCodeWord - 1; j++) {
  412. lpbyRSWork[j] = lpbyRSWork[j + 1];
  413. }
  414. }
  415. }
  416. }
  417. static void SetFinderPattern(int x, int y)
  418. {
  419. static const uint8_t byPattern[] = { 0x7f, // 1111111b
  420. 0x41, // 1000001b
  421. 0x5d, // 1011101b
  422. 0x5d, // 1011101b
  423. 0x5d, // 1011101b
  424. 0x41, // 1000001b
  425. 0x7f}; // 1111111b
  426. int i, j;
  427. for (i = 0; i < 7; i++) {
  428. for (j = 0; j < 7; j++) {
  429. m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (6 - j))) ? '\x30' : '\x20';
  430. }
  431. }
  432. }
  433. static void SetVersionPattern(void)
  434. {
  435. int i, j;
  436. if (m_nVersion <= 6) {
  437. return;
  438. }
  439. int nVerData = m_nVersion << 12;
  440. // Calculated bit remainder
  441. for (i = 0; i < 6; i++) {
  442. if (nVerData & (1 << (17 - i))) {
  443. nVerData ^= (0x1f25 << (5 - i));
  444. }
  445. }
  446. nVerData += m_nVersion << 12;
  447. for (i = 0; i < 6; i++) {
  448. for (j = 0; j < 3; j++) {
  449. m_byModuleData[m_nSymbleSize - 11 + j][i] = m_byModuleData[i][m_nSymbleSize - 11 + j] =
  450. (nVerData & (1 << (i * 3 + j))) ? '\x30' : '\x20';
  451. }
  452. }
  453. }
  454. static void SetAlignmentPattern(int x, int y)
  455. {
  456. static const uint8_t byPattern[] = { 0x1f, // 11111b
  457. 0x11, // 10001b
  458. 0x15, // 10101b
  459. 0x11, // 10001b
  460. 0x1f}; // 11111b
  461. int i, j;
  462. if (m_byModuleData[x][y] & 0x20) {
  463. return; // Excluded due to overlap with the functional module
  464. }
  465. x -= 2; y -= 2; // Convert the coordinates to the upper left corner
  466. for (i = 0; i < 5; i++) {
  467. for (j = 0; j < 5; j++) {
  468. m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (4 - j))) ? '\x30' : '\x20';
  469. }
  470. }
  471. }
  472. static void SetFunctionModule(void)
  473. {
  474. int i, j;
  475. // Position detection pattern
  476. SetFinderPattern(0, 0);
  477. SetFinderPattern(m_nSymbleSize - 7, 0);
  478. SetFinderPattern(0, m_nSymbleSize - 7);
  479. // Separator pattern position detection
  480. for (i = 0; i < 8; i++) {
  481. m_byModuleData[i][7] = m_byModuleData[7][i] = '\x20';
  482. m_byModuleData[m_nSymbleSize - 8][i] = m_byModuleData[m_nSymbleSize - 8 + i][7] = '\x20';
  483. m_byModuleData[i][m_nSymbleSize - 8] = m_byModuleData[7][m_nSymbleSize - 8 + i] = '\x20';
  484. }
  485. // Registration as part of a functional module position description format information
  486. for (i = 0; i < 9; i++) {
  487. m_byModuleData[i][8] = m_byModuleData[8][i] = '\x20';
  488. }
  489. for (i = 0; i < 8; i++) {
  490. m_byModuleData[m_nSymbleSize - 8 + i][8] = m_byModuleData[8][m_nSymbleSize - 8 + i] = '\x20';
  491. }
  492. // Version information pattern
  493. SetVersionPattern();
  494. // Pattern alignment
  495. for (i = 0; i < QR_VersonInfo[m_nVersion].ncAlignPoint; i++) {
  496. SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], 6);
  497. SetAlignmentPattern(6, QR_VersonInfo[m_nVersion].nAlignPoint[i]);
  498. for (j = 0; j < QR_VersonInfo[m_nVersion].ncAlignPoint; j++) {
  499. SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], QR_VersonInfo[m_nVersion].nAlignPoint[j]);
  500. }
  501. }
  502. // Timing pattern
  503. for (i = 8; i <= m_nSymbleSize - 9; i++) {
  504. m_byModuleData[i][6] = (i % 2) == 0 ? '\x30' : '\x20';
  505. m_byModuleData[6][i] = (i % 2) == 0 ? '\x30' : '\x20';
  506. }
  507. }
  508. static void SetCodeWordPattern(void)
  509. {
  510. int x = m_nSymbleSize;
  511. int y = m_nSymbleSize - 1;
  512. int nCoef_x = 1; // placement orientation axis x
  513. int nCoef_y = 1; // placement orientation axis y
  514. int i, j;
  515. for (i = 0; i < m_ncAllCodeWord; i++) {
  516. for (j = 0; j < 8; j++) {
  517. do {
  518. x += nCoef_x;
  519. nCoef_x *= -1;
  520. if (nCoef_x < 0) {
  521. y += nCoef_y;
  522. if (y < 0 || y == m_nSymbleSize) {
  523. y = (y < 0) ? 0 : m_nSymbleSize - 1;
  524. nCoef_y *= -1;
  525. x -= 2;
  526. if (x == 6) { // Timing pattern
  527. x--;
  528. }
  529. }
  530. }
  531. } while (m_byModuleData[x][y] & 0x20); // Exclude a functional module
  532. m_byModuleData[x][y] = (m_byAllCodeWord[i] & (1 << (7 - j))) ? '\x02' : '\x00';
  533. }
  534. }
  535. }
  536. static void SetMaskingPattern(int nPatternNo)
  537. {
  538. int i, j;
  539. for (i = 0; i < m_nSymbleSize; i++) {
  540. for (j = 0; j < m_nSymbleSize; j++) {
  541. if (! (m_byModuleData[j][i] & 0x20)) { // Exclude a functional module
  542. int bMask;
  543. switch (nPatternNo) {
  544. case 0:
  545. bMask = ((i + j) % 2 == 0);
  546. break;
  547. case 1:
  548. bMask = (i % 2 == 0);
  549. break;
  550. case 2:
  551. bMask = (j % 3 == 0);
  552. break;
  553. case 3:
  554. bMask = ((i + j) % 3 == 0);
  555. break;
  556. case 4:
  557. bMask = (((i / 2) + (j / 3)) % 2 == 0);
  558. break;
  559. case 5:
  560. bMask = (((i * j) % 2) + ((i * j) % 3) == 0);
  561. break;
  562. case 6:
  563. bMask = ((((i * j) % 2) + ((i * j) % 3)) % 2 == 0);
  564. break;
  565. default: // case 7:
  566. bMask = ((((i * j) % 3) + ((i + j) % 2)) % 2 == 0);
  567. break;
  568. }
  569. m_byModuleData[j][i] = (uint8_t)((m_byModuleData[j][i] & 0xfe) | (((m_byModuleData[j][i] & 0x02) > 1) ^ bMask));
  570. }
  571. }
  572. }
  573. }
  574. static void SetFormatInfoPattern(int nPatternNo)
  575. {
  576. int nFormatInfo;
  577. int i;
  578. switch (m_nLevel) {
  579. case QR_LEVEL_L:
  580. nFormatInfo = 0x08; // 01nnnb
  581. break;
  582. case QR_LEVEL_M:
  583. nFormatInfo = 0x00; // 00nnnb
  584. break;
  585. case QR_LEVEL_Q:
  586. nFormatInfo = 0x18; // 11nnnb
  587. break;
  588. default: // case QR_LEVEL_H:
  589. nFormatInfo = 0x10; // 10nnnb
  590. break;
  591. }
  592. nFormatInfo += nPatternNo;
  593. int nFormatData = nFormatInfo << 10;
  594. // Calculated bit remainder
  595. for (i = 0; i < 5; i++) {
  596. if (nFormatData & (1 << (14 - i))) {
  597. nFormatData ^= (0x0537 << (4 - i)); // 10100110111b
  598. }
  599. }
  600. nFormatData += nFormatInfo << 10;
  601. // Masking
  602. nFormatData ^= 0x5412; // 101010000010010b
  603. // Position detection patterns located around the upper left
  604. for (i = 0; i <= 5; i++) {
  605. m_byModuleData[8][i] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  606. }
  607. m_byModuleData[8][7] = (nFormatData & (1 << 6)) ? '\x30' : '\x20';
  608. m_byModuleData[8][8] = (nFormatData & (1 << 7)) ? '\x30' : '\x20';
  609. m_byModuleData[7][8] = (nFormatData & (1 << 8)) ? '\x30' : '\x20';
  610. for (i = 9; i <= 14; i++) {
  611. m_byModuleData[14 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  612. }
  613. // Position detection patterns located under the upper right corner
  614. for (i = 0; i <= 7; i++) {
  615. m_byModuleData[m_nSymbleSize - 1 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  616. }
  617. // Right lower left position detection patterns located
  618. m_byModuleData[8][m_nSymbleSize - 8] = '\x30'; // Module fixed dark
  619. for (i = 8; i <= 14; i++) {
  620. m_byModuleData[8][m_nSymbleSize - 15 + i] = (nFormatData & (1 << i)) ? '\x30' : '\x20';
  621. }
  622. }
  623. static int CountPenalty(void)
  624. {
  625. int nPenalty = 0;
  626. int i, j, k;
  627. // Column of the same color adjacent module
  628. for (i = 0; i < m_nSymbleSize; i++) {
  629. for (j = 0; j < m_nSymbleSize - 4; j++) {
  630. int nCount = 1;
  631. for (k = j + 1; k < m_nSymbleSize; k++) {
  632. if (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][k] & 0x11) == 0)) {
  633. nCount++;
  634. } else {
  635. break;
  636. }
  637. }
  638. if (nCount >= 5) {
  639. nPenalty += 3 + (nCount - 5);
  640. }
  641. j = k - 1;
  642. }
  643. }
  644. // Adjacent module line of the same color
  645. for (i = 0; i < m_nSymbleSize; i++) {
  646. for (j = 0; j < m_nSymbleSize - 4; j++) {
  647. int nCount = 1;
  648. for (k = j + 1; k < m_nSymbleSize; k++) {
  649. if (((m_byModuleData[j][i] & 0x11) == 0) == ((m_byModuleData[k][i] & 0x11) == 0)) {
  650. nCount++;
  651. } else {
  652. break;
  653. }
  654. }
  655. if (nCount >= 5) {
  656. nPenalty += 3 + (nCount - 5);
  657. }
  658. j = k - 1;
  659. }
  660. }
  661. // Modules of the same color block (2 ~ 2)
  662. for (i = 0; i < m_nSymbleSize - 1; i++) {
  663. for (j = 0; j < m_nSymbleSize - 1; j++) {
  664. if ((((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j] & 0x11) == 0)) &&
  665. (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i] [j + 1] & 0x11) == 0)) &&
  666. (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j + 1] & 0x11) == 0))) {
  667. nPenalty += 3;
  668. }
  669. }
  670. }
  671. // Pattern (dark dark: light: dark: light) ratio 1:1:3:1:1 in the same column
  672. for (i = 0; i < m_nSymbleSize; i++) {
  673. for (j = 0; j < m_nSymbleSize - 6; j++) {
  674. if (((j == 0) || (! (m_byModuleData[i][j - 1] & 0x11))) &&
  675. ( m_byModuleData[i][j ] & 0x11) &&
  676. (! (m_byModuleData[i][j + 1] & 0x11)) &&
  677. ( m_byModuleData[i][j + 2] & 0x11) &&
  678. ( m_byModuleData[i][j + 3] & 0x11) &&
  679. ( m_byModuleData[i][j + 4] & 0x11) &&
  680. (! (m_byModuleData[i][j + 5] & 0x11)) &&
  681. ( m_byModuleData[i][j + 6] & 0x11) &&
  682. ((j == m_nSymbleSize - 7) || (! (m_byModuleData[i][j + 7] & 0x11)))) {
  683. // Clear pattern of four or more before or after
  684. if (((j < 2 || ! (m_byModuleData[i][j - 2] & 0x11)) &&
  685. (j < 3 || ! (m_byModuleData[i][j - 3] & 0x11)) &&
  686. (j < 4 || ! (m_byModuleData[i][j - 4] & 0x11))) ||
  687. ((j >= m_nSymbleSize - 8 || ! (m_byModuleData[i][j + 8] & 0x11)) &&
  688. (j >= m_nSymbleSize - 9 || ! (m_byModuleData[i][j + 9] & 0x11)) &&
  689. (j >= m_nSymbleSize - 10 || ! (m_byModuleData[i][j + 10] & 0x11)))) {
  690. nPenalty += 40;
  691. }
  692. }
  693. }
  694. }
  695. // Pattern (dark dark: light: dark: light) in the same line ratio 1:1:3:1:1
  696. for (i = 0; i < m_nSymbleSize; i++) {
  697. for (j = 0; j < m_nSymbleSize - 6; j++) {
  698. if (((j == 0) || (! (m_byModuleData[j - 1][i] & 0x11))) &&
  699. ( m_byModuleData[j ] [i] & 0x11) &&
  700. (! (m_byModuleData[j + 1][i] & 0x11)) &&
  701. ( m_byModuleData[j + 2][i] & 0x11) &&
  702. ( m_byModuleData[j + 3][i] & 0x11) &&
  703. ( m_byModuleData[j + 4][i] & 0x11) &&
  704. (! (m_byModuleData[j + 5][i] & 0x11)) &&
  705. ( m_byModuleData[j + 6][i] & 0x11) &&
  706. ((j == m_nSymbleSize - 7) || (! (m_byModuleData[j + 7][i] & 0x11)))) {
  707. // Clear pattern of four or more before or after
  708. if (((j < 2 || ! (m_byModuleData[j - 2][i] & 0x11)) &&
  709. (j < 3 || ! (m_byModuleData[j - 3][i] & 0x11)) &&
  710. (j < 4 || ! (m_byModuleData[j - 4][i] & 0x11))) ||
  711. ((j >= m_nSymbleSize - 8 || ! (m_byModuleData[j + 8][i] & 0x11)) &&
  712. (j >= m_nSymbleSize - 9 || ! (m_byModuleData[j + 9][i] & 0x11)) &&
  713. (j >= m_nSymbleSize - 10 || ! (m_byModuleData[j + 10][i] & 0x11)))) {
  714. nPenalty += 40;
  715. }
  716. }
  717. }
  718. }
  719. // The proportion of modules for the entire dark
  720. int nCount = 0;
  721. for (i = 0; i < m_nSymbleSize; i++) {
  722. for (j = 0; j < m_nSymbleSize; j++) {
  723. if (! (m_byModuleData[i][j] & 0x11)) {
  724. nCount++;
  725. }
  726. }
  727. }
  728. nPenalty += (abs(50 - ((nCount * 100) / (m_nSymbleSize * m_nSymbleSize))) / 5) * 10;
  729. return nPenalty;
  730. }
  731. static void FormatModule(void)
  732. {
  733. int i, j;
  734. memset(m_byModuleData, 0, sizeof(m_byModuleData));
  735. // Function module placement
  736. SetFunctionModule();
  737. // Data placement
  738. SetCodeWordPattern();
  739. if (m_nMaskingNo == -1) {
  740. // Select the best pattern masking
  741. m_nMaskingNo = 0;
  742. SetMaskingPattern(m_nMaskingNo); // Masking
  743. SetFormatInfoPattern(m_nMaskingNo); // Placement pattern format information
  744. int nMinPenalty = CountPenalty();
  745. for (i = 1; i <= 7; i++) {
  746. SetMaskingPattern(i); // Masking
  747. SetFormatInfoPattern(i); // Placement pattern format information
  748. int nPenalty = CountPenalty();
  749. if (nPenalty < nMinPenalty) {
  750. nMinPenalty = nPenalty;
  751. m_nMaskingNo = i;
  752. }
  753. }
  754. }
  755. SetMaskingPattern(m_nMaskingNo); // Masking
  756. SetFormatInfoPattern(m_nMaskingNo); // Placement pattern format information
  757. // The module pattern converted to a Boolean value
  758. for (i = 0; i < m_nSymbleSize; i++) {
  759. for (j = 0; j < m_nSymbleSize; j++) {
  760. m_byModuleData[i][j] = (uint8_t)((m_byModuleData[i][j] & 0x11) != 0);
  761. }
  762. }
  763. }
  764. static void putBitToPos(uint32_t pos, int bw, uint8_t *bits)
  765. {
  766. if (bw == 0) return;
  767. uint32_t tmp;
  768. uint32_t bitpos[8] = {128, 64, 32, 16, 8, 4, 2, 1};
  769. if (pos % 8 == 0) {
  770. tmp = (pos / 8) - 1;
  771. bits[tmp] = bits[tmp] ^ bitpos[7];
  772. } else {
  773. tmp = pos / 8;
  774. bits[tmp] = bits[tmp] ^ bitpos[pos % 8 - 1];
  775. }
  776. }
  777. int qr_encode(int level, int version, const char *source, size_t source_len, uint8_t *result)
  778. {
  779. int i, j;
  780. const bool auto_extent = 0;
  781. m_nLevel = level;
  782. m_nMaskingNo = -1;
  783. memset(result, 0, QR_MAX_BITDATA);
  784. // If the data length is not specified, acquired by lstrlen
  785. size_t ncLength = source_len > 0 ? source_len : strlen(source);
  786. if (ncLength == 0) {
  787. return -1; // No data
  788. }
  789. // Check version (model number)
  790. nEncodeVersion = GetEncodeVersion(version, source, ncLength);
  791. if (nEncodeVersion == 0) {
  792. return -1; // Over-capacity
  793. }
  794. if (version == 0) {
  795. // Auto Part
  796. m_nVersion = nEncodeVersion;
  797. } else {
  798. if (nEncodeVersion <= version) {
  799. m_nVersion = version;
  800. } else {
  801. if (auto_extent) {
  802. m_nVersion = nEncodeVersion; // Automatic extended version (model number)
  803. } else {
  804. return -1; // Over-capacity
  805. }
  806. }
  807. }
  808. // Terminator addition code "0000"
  809. int ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[level];
  810. int ncTerminater = (ncDataCodeWord * 8) - m_ncDataCodeWordBit;
  811. if (ncTerminater < 4) {
  812. ncTerminater = 4;
  813. }
  814. if (ncTerminater > 0) {
  815. m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 0, ncTerminater);
  816. }
  817. // Additional padding code "11101100, 00010001"
  818. uint8_t byPaddingCode = 0xec;
  819. for (i = (m_ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; i++) {
  820. m_byDataCodeWord[i] = byPaddingCode;
  821. byPaddingCode = (uint8_t)(byPaddingCode == 0xec ? 0x11 : 0xec);
  822. }
  823. // Calculated the total clear area code word
  824. m_ncAllCodeWord = QR_VersonInfo[m_nVersion].ncAllCodeWord;
  825. memset(m_byAllCodeWord, 0, sizeof(m_byAllCodeWord));
  826. int nDataCwIndex = 0; // Position data processing code word
  827. // Division number data block
  828. int ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncRSBlock;
  829. int ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncRSBlock;
  830. int ncBlockSum = ncBlock1 + ncBlock2;
  831. int nBlockNo = 0; // Block number in the process
  832. // The number of data code words by block
  833. int ncDataCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncDataCodeWord;
  834. int ncDataCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncDataCodeWord;
  835. // Code word interleaving data placement
  836. for (i = 0; i < ncBlock1; i++) {
  837. for (j = 0; j < ncDataCw1; j++) {
  838. m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
  839. }
  840. nBlockNo++;
  841. }
  842. for (i = 0; i < ncBlock2; i++) {
  843. for (j = 0; j < ncDataCw2; j++) {
  844. if (j < ncDataCw1) {
  845. m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
  846. } else {
  847. // 2 minute fraction block placement event
  848. m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] = m_byDataCodeWord[nDataCwIndex++];
  849. }
  850. }
  851. nBlockNo++;
  852. }
  853. // RS code words by block number (currently the same number)
  854. int ncRSCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncAllCodeWord - ncDataCw1;
  855. int ncRSCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncAllCodeWord - ncDataCw2;
  856. // RS code word is calculated
  857. nDataCwIndex = 0;
  858. nBlockNo = 0;
  859. for (i = 0; i < ncBlock1; i++) {
  860. memset(m_byRSWork, 0, sizeof(m_byRSWork));
  861. memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw1);
  862. GetRSCodeWord(m_byRSWork, ncDataCw1, ncRSCw1);
  863. // RS code word placement
  864. for (j = 0; j < ncRSCw1; j++) {
  865. m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
  866. }
  867. nDataCwIndex += ncDataCw1;
  868. nBlockNo++;
  869. }
  870. for (i = 0; i < ncBlock2; i++) {
  871. memset(m_byRSWork, 0, sizeof(m_byRSWork));
  872. memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw2);
  873. GetRSCodeWord(m_byRSWork, ncDataCw2, ncRSCw2);
  874. // RS code word placement
  875. for (j = 0; j < ncRSCw2; j++) {
  876. m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
  877. }
  878. nDataCwIndex += ncDataCw2;
  879. nBlockNo++;
  880. }
  881. m_nSymbleSize = m_nVersion * 4 + 17;
  882. // Module placement
  883. FormatModule();
  884. for (i = 0; i < m_nSymbleSize; i++) {
  885. for (j = 0; j < m_nSymbleSize; j++) {
  886. if (!m_byModuleData[i][j]) {
  887. putBitToPos((j * m_nSymbleSize) + i + 1, 0, result);
  888. } else {
  889. putBitToPos((j * m_nSymbleSize) + i + 1, 1, result);
  890. }
  891. }
  892. }
  893. return m_nSymbleSize;
  894. }