PageRenderTime 74ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/backend/qr.c

https://github.com/Pastor/zint
C | 2171 lines | 1691 code | 335 blank | 145 comment | 711 complexity | ca082b3d676fcf085fc073a5cc4d7c4b MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* qr.c Handles QR Code */
  2. /*
  3. libzint - the open source barcode library
  4. Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License along
  14. with this program; if not, write to the Free Software Foundation, Inc.,
  15. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  16. */
  17. #include <string.h>
  18. #include "common.h"
  19. #include <stdio.h>
  20. #include "sjis.h"
  21. #include "qr.h"
  22. #include "reedsol.h"
  23. int in_alpha(int glyph) {
  24. /* Returns true if input glyph is in the Alphanumeric set */
  25. int retval = 0;
  26. char cglyph = (char) glyph;
  27. if((cglyph >= '0') && (cglyph <= '9')) {
  28. retval = 1;
  29. }
  30. if((cglyph >= 'A') && (cglyph <= 'Z')) {
  31. retval = 1;
  32. }
  33. switch (cglyph) {
  34. case ' ':
  35. case '$':
  36. case '%':
  37. case '*':
  38. case '+':
  39. case '-':
  40. case '.':
  41. case '/':
  42. case ':':
  43. retval = 1;
  44. break;
  45. }
  46. return retval;
  47. }
  48. void define_mode(char mode[], int jisdata[], int length, int gs1)
  49. {
  50. /* Values placed into mode[] are: K = Kanji, B = Binary, A = Alphanumeric, N = Numeric */
  51. int i, mlen, j;
  52. for(i = 0; i < length; i++) {
  53. if(jisdata[i] > 0xff) {
  54. mode[i] = 'K';
  55. } else {
  56. mode[i] = 'B';
  57. if(in_alpha(jisdata[i])) { mode[i] = 'A'; }
  58. if(gs1 && (jisdata[i] == '[')) { mode[i] = 'A'; }
  59. if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { mode[i] = 'N'; }
  60. }
  61. }
  62. /* If less than 6 numeric digits together then don't use numeric mode */
  63. for(i = 0; i < length; i++) {
  64. if(mode[i] == 'N') {
  65. if(((i != 0) && (mode[i - 1] != 'N')) || (i == 0)) {
  66. mlen = 0;
  67. while (((mlen + i) < length) && (mode[mlen + i] == 'N')) {
  68. mlen++;
  69. };
  70. if(mlen < 6) {
  71. for(j = 0; j < mlen; j++) {
  72. mode[i + j] = 'A';
  73. }
  74. }
  75. }
  76. }
  77. }
  78. /* If less than 4 alphanumeric characters together then don't use alphanumeric mode */
  79. for(i = 0; i < length; i++) {
  80. if(mode[i] == 'A') {
  81. if(((i != 0) && (mode[i - 1] != 'A')) || (i == 0)) {
  82. mlen = 0;
  83. while (((mlen + i) < length) && (mode[mlen + i] == 'A')) {
  84. mlen++;
  85. };
  86. if(mlen < 6) {
  87. for(j = 0; j < mlen; j++) {
  88. mode[i + j] = 'B';
  89. }
  90. }
  91. }
  92. }
  93. }
  94. }
  95. int estimate_binary_length(char mode[], int length, int gs1)
  96. {
  97. /* Make an estimate (worst case scenario) of how long the binary string will be */
  98. int i, count = 0;
  99. char current = 0;
  100. int a_count = 0;
  101. int n_count = 0;
  102. if(gs1) { count += 4; }
  103. for(i = 0; i < length; i++) {
  104. if(mode[i] != current) {
  105. switch(mode[i]) {
  106. case 'K': count += 12 + 4; current = 'K'; break;
  107. case 'B': count += 16 + 4; current = 'B'; break;
  108. case 'A': count += 13 + 4; current = 'A'; a_count = 0; break;
  109. case 'N': count += 14 + 4; current = 'N'; n_count = 0; break;
  110. }
  111. }
  112. switch(mode[i]) {
  113. case 'K': count += 13; break;
  114. case 'B': count += 8; break;
  115. case 'A':
  116. a_count++;
  117. if((a_count & 1) == 0) {
  118. count += 5; // 11 in total
  119. a_count = 0;
  120. }
  121. else
  122. count += 6;
  123. break;
  124. case 'N':
  125. n_count++;
  126. if((n_count % 3) == 0) {
  127. count += 3; // 10 in total
  128. n_count = 0;
  129. }
  130. else if ((n_count & 1) == 0)
  131. count += 3; // 7 in total
  132. else
  133. count += 4;
  134. break;
  135. }
  136. }
  137. return count;
  138. }
  139. void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int est_binlen)
  140. {
  141. /* Convert input data to a binary stream and add padding */
  142. int position = 0, debug = 0;
  143. int short_data_block_length, i, scheme = 1;
  144. char data_block, padbits;
  145. int current_binlen, current_bytes;
  146. int toggle, percent;
  147. char binary[est_binlen + 12];
  148. strcpy(binary, "");
  149. if(gs1) {
  150. concat(binary, "0101"); /* FNC1 */
  151. }
  152. if(version <= 9) {
  153. scheme = 1;
  154. } else if((version >= 10) && (version <= 26)) {
  155. scheme = 2;
  156. } else if(version >= 27) {
  157. scheme = 3;
  158. }
  159. if(debug) {
  160. for(i = 0; i < length; i++) {
  161. printf("%c", mode[i]);
  162. }
  163. printf("\n");
  164. }
  165. percent = 0;
  166. do {
  167. data_block = mode[position];
  168. short_data_block_length = 0;
  169. do {
  170. short_data_block_length++;
  171. } while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block));
  172. switch(data_block) {
  173. case 'K':
  174. /* Kanji mode */
  175. /* Mode indicator */
  176. concat(binary, "1000");
  177. /* Character count indicator */
  178. bscan(binary, short_data_block_length, 0x20 << (scheme*2)); /* scheme = 1..3 */
  179. if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); }
  180. /* Character representation */
  181. for(i = 0; i < short_data_block_length; i++) {
  182. int jis = jisdata[position + i];
  183. int msb, lsb, prod;
  184. if(jis > 0x9fff) { jis -= 0xc140; }
  185. msb = (jis & 0xff00) >> 4;
  186. lsb = (jis & 0xff);
  187. prod = (msb * 0xc0) + lsb;
  188. bscan(binary, prod, 0x1000);
  189. if(debug) { printf("0x%4X ", prod); }
  190. }
  191. if(debug) { printf("\n"); }
  192. break;
  193. case 'B':
  194. /* Byte mode */
  195. /* Mode indicator */
  196. concat(binary, "0100");
  197. /* Character count indicator */
  198. bscan(binary, short_data_block_length, scheme > 1 ? 0x8000 : 0x80); /* scheme = 1..3 */
  199. if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); }
  200. /* Character representation */
  201. for(i = 0; i < short_data_block_length; i++) {
  202. int byte = jisdata[position + i];
  203. if(gs1 && (byte == '[')) {
  204. byte = 0x1d; /* FNC1 */
  205. }
  206. bscan(binary, byte, 0x80);
  207. if(debug) { printf("0x%2X(%d) ", byte, byte); }
  208. }
  209. if(debug) { printf("\n"); }
  210. break;
  211. case 'A':
  212. /* Alphanumeric mode */
  213. /* Mode indicator */
  214. concat(binary, "0010");
  215. /* Character count indicator */
  216. bscan(binary, short_data_block_length, 0x40 << (2 * scheme)); /* scheme = 1..3 */
  217. if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); }
  218. /* Character representation */
  219. i = 0;
  220. while ( i < short_data_block_length ) {
  221. int count;
  222. int first = 0, second = 0, prod;
  223. if(percent == 0) {
  224. if(gs1 && (jisdata[position + i] == '%')) {
  225. first = posn(RHODIUM, '%');
  226. second = posn(RHODIUM, '%');
  227. count = 2;
  228. prod = (first * 45) + second;
  229. i++;
  230. } else {
  231. if(gs1 && (jisdata[position + i] == '[')) {
  232. first = posn(RHODIUM, '%'); /* FNC1 */
  233. } else {
  234. first = posn(RHODIUM, (char) jisdata[position + i]);
  235. }
  236. count = 1;
  237. i++;
  238. prod = first;
  239. if(mode[position + i] == 'A') {
  240. if(gs1 && (jisdata[position + i] == '%')) {
  241. second = posn(RHODIUM, '%');
  242. count = 2;
  243. prod = (first * 45) + second;
  244. percent = 1;
  245. } else {
  246. if(gs1 && (jisdata[position + i] == '[')) {
  247. second = posn(RHODIUM, '%'); /* FNC1 */
  248. } else {
  249. second = posn(RHODIUM, (char) jisdata[position + i]);
  250. }
  251. count = 2;
  252. i++;
  253. prod = (first * 45) + second;
  254. }
  255. }
  256. }
  257. } else {
  258. first = posn(RHODIUM, '%');
  259. count = 1;
  260. i++;
  261. prod = first;
  262. percent = 0;
  263. if(mode[position + i] == 'A') {
  264. if(gs1 && (jisdata[position + i] == '%')) {
  265. second = posn(RHODIUM, '%');
  266. count = 2;
  267. prod = (first * 45) + second;
  268. percent = 1;
  269. } else {
  270. if(gs1 && (jisdata[position + i] == '[')) {
  271. second = posn(RHODIUM, '%'); /* FNC1 */
  272. } else {
  273. second = posn(RHODIUM, (char) jisdata[position + i]);
  274. }
  275. count = 2;
  276. i++;
  277. prod = (first * 45) + second;
  278. }
  279. }
  280. }
  281. bscan(binary, prod, count == 2 ? 0x400 : 0x20); /* count = 1..2 */
  282. if(debug) { printf("0x%4X ", prod); }
  283. };
  284. if(debug) { printf("\n"); }
  285. break;
  286. case 'N':
  287. /* Numeric mode */
  288. /* Mode indicator */
  289. concat(binary, "0001");
  290. /* Character count indicator */
  291. bscan(binary, short_data_block_length, 0x80 << (2 * scheme)); /* scheme = 1..3 */
  292. if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); }
  293. /* Character representation */
  294. i = 0;
  295. while ( i < short_data_block_length ) {
  296. int count;
  297. int first = 0, second = 0, third = 0, prod;
  298. first = posn(NEON, (char) jisdata[position + i]);
  299. count = 1;
  300. prod = first;
  301. if(mode[position + i + 1] == 'N') {
  302. second = posn(NEON, (char) jisdata[position + i + 1]);
  303. count = 2;
  304. prod = (prod * 10) + second;
  305. if(mode[position + i + 2] == 'N') {
  306. third = posn(NEON, (char) jisdata[position + i + 2]);
  307. count = 3;
  308. prod = (prod * 10) + third;
  309. }
  310. }
  311. bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */
  312. if(debug) { printf("0x%4X (%d)", prod, prod); }
  313. i += count;
  314. };
  315. if(debug) { printf("\n"); }
  316. break;
  317. }
  318. position += short_data_block_length;
  319. } while (position < length) ;
  320. /* Terminator */
  321. concat(binary, "0000");
  322. current_binlen = strlen(binary);
  323. padbits = 8 - (current_binlen % 8);
  324. if(padbits == 8) { padbits = 0; }
  325. current_bytes = (current_binlen + padbits) / 8;
  326. /* Padding bits */
  327. for(i = 0; i < padbits; i++) {
  328. concat(binary, "0");
  329. }
  330. /* Put data into 8-bit codewords */
  331. for(i = 0; i < current_bytes; i++) {
  332. datastream[i] = 0x00;
  333. if(binary[i * 8] == '1') { datastream[i] += 0x80; }
  334. if(binary[i * 8 + 1] == '1') { datastream[i] += 0x40; }
  335. if(binary[i * 8 + 2] == '1') { datastream[i] += 0x20; }
  336. if(binary[i * 8 + 3] == '1') { datastream[i] += 0x10; }
  337. if(binary[i * 8 + 4] == '1') { datastream[i] += 0x08; }
  338. if(binary[i * 8 + 5] == '1') { datastream[i] += 0x04; }
  339. if(binary[i * 8 + 6] == '1') { datastream[i] += 0x02; }
  340. if(binary[i * 8 + 7] == '1') { datastream[i] += 0x01; }
  341. }
  342. /* Add pad codewords */
  343. toggle = 0;
  344. for(i = current_bytes; i < target_binlen; i++) {
  345. if(toggle == 0) {
  346. datastream[i] = 0xec;
  347. toggle = 1;
  348. } else {
  349. datastream[i] = 0x11;
  350. toggle = 0;
  351. }
  352. }
  353. if(debug) {
  354. printf("Resulting codewords:\n\t");
  355. for(i = 0; i < target_binlen; i++) {
  356. printf("0x%2X ", datastream[i]);
  357. }
  358. printf("\n");
  359. }
  360. }
  361. void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int blocks)
  362. {
  363. /* Split data into blocks, add error correction and then interleave the blocks and error correction data */
  364. int ecc_cw = qr_total_codewords[version - 1] - data_cw;
  365. int short_data_block_length = data_cw / blocks;
  366. int qty_long_blocks = data_cw % blocks;
  367. int qty_short_blocks = blocks - qty_long_blocks;
  368. int ecc_block_length = ecc_cw / blocks;
  369. int i, j, length_this_block, posn, debug = 0;
  370. unsigned char data_block[short_data_block_length + 2];
  371. unsigned char ecc_block[ecc_block_length + 2];
  372. int interleaved_data[data_cw + 2];
  373. int interleaved_ecc[ecc_cw + 2];
  374. posn = 0;
  375. for(i = 0; i < blocks; i++) {
  376. if(i < qty_short_blocks) { length_this_block = short_data_block_length; } else { length_this_block = short_data_block_length + 1; }
  377. for(j = 0; j < ecc_block_length; j++) {
  378. ecc_block[j] = 0;
  379. }
  380. for(j = 0; j < length_this_block; j++) {
  381. data_block[j] = (unsigned char) datastream[posn + j];
  382. }
  383. rs_init_gf(0x11d);
  384. rs_init_code(ecc_block_length, 0);
  385. rs_encode(length_this_block, data_block, ecc_block);
  386. rs_free();
  387. if(debug) {
  388. printf("Block %d: ", i + 1);
  389. for(j = 0; j < length_this_block; j++) {
  390. printf("%2X ", data_block[j]);
  391. }
  392. if(i < qty_short_blocks) {
  393. printf(" ");
  394. }
  395. printf(" // ");
  396. for(j = 0; j < ecc_block_length; j++) {
  397. printf("%2X ", ecc_block[ecc_block_length - j - 1]);
  398. }
  399. printf("\n");
  400. }
  401. for(j = 0; j < short_data_block_length; j++) {
  402. interleaved_data[(j * blocks) + i] = (int) data_block[j];
  403. }
  404. if(i >= qty_short_blocks){
  405. interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = (int) data_block[short_data_block_length];
  406. }
  407. for(j = 0; j < ecc_block_length; j++) {
  408. interleaved_ecc[(j * blocks) + i] = (int) ecc_block[ecc_block_length - j - 1];
  409. }
  410. posn += length_this_block;
  411. }
  412. for(j = 0; j < data_cw; j++) {
  413. fullstream[j] = interleaved_data[j];
  414. }
  415. for(j = 0; j < ecc_cw; j++) {
  416. fullstream[j + data_cw] = interleaved_ecc[j];
  417. }
  418. if(debug) {
  419. printf("\nData Stream: \n");
  420. for(j = 0; j < (data_cw + ecc_cw); j++) {
  421. printf("%2X ", fullstream[j]);
  422. }
  423. printf("\n");
  424. }
  425. }
  426. void place_finder(unsigned char grid[], int size, int x, int y)
  427. {
  428. int xp, yp;
  429. int finder[] = {
  430. 1, 1, 1, 1, 1, 1, 1,
  431. 1, 0, 0, 0, 0, 0, 1,
  432. 1, 0, 1, 1, 1, 0, 1,
  433. 1, 0, 1, 1, 1, 0, 1,
  434. 1, 0, 1, 1, 1, 0, 1,
  435. 1, 0, 0, 0, 0, 0, 1,
  436. 1, 1, 1, 1, 1, 1, 1
  437. };
  438. for(xp = 0; xp < 7; xp++) {
  439. for(yp = 0; yp < 7; yp++) {
  440. if (finder[xp + (7 * yp)] == 1) {
  441. grid[((yp + y) * size) + (xp + x)] = 0x11;
  442. } else {
  443. grid[((yp + y) * size) + (xp + x)] = 0x10;
  444. }
  445. }
  446. }
  447. }
  448. void place_align(unsigned char grid[], int size, int x, int y)
  449. {
  450. int xp, yp;
  451. int alignment[] = {
  452. 1, 1, 1, 1, 1,
  453. 1, 0, 0, 0, 1,
  454. 1, 0, 1, 0, 1,
  455. 1, 0, 0, 0, 1,
  456. 1, 1, 1, 1, 1
  457. };
  458. x -= 2;
  459. y -= 2; /* Input values represent centre of pattern */
  460. for(xp = 0; xp < 5; xp++) {
  461. for(yp = 0; yp < 5; yp++) {
  462. if (alignment[xp + (5 * yp)] == 1) {
  463. grid[((yp + y) * size) + (xp + x)] = 0x11;
  464. } else {
  465. grid[((yp + y) * size) + (xp + x)] = 0x10;
  466. }
  467. }
  468. }
  469. }
  470. void setup_grid(unsigned char* grid, int size, int version)
  471. {
  472. int toggle = 1;
  473. int loopsize, x, y, xcoord, ycoord;
  474. /* Add timing patterns */
  475. for(int i = 0; i < size; i++) {
  476. if(toggle == 1) {
  477. grid[(6 * size) + i] = 0x21;
  478. grid[(i * size) + 6] = 0x21;
  479. toggle = 0;
  480. } else {
  481. grid[(6 * size) + i] = 0x20;
  482. grid[(i * size) + 6] = 0x20;
  483. toggle = 1;
  484. }
  485. }
  486. /* Add finder patterns */
  487. place_finder(grid, size, 0, 0);
  488. place_finder(grid, size, 0, size - 7);
  489. place_finder(grid, size, size - 7, 0);
  490. /* Add separators */
  491. for(int i = 0; i < 7; i++) {
  492. grid[(7 * size) + i] = 0x10;
  493. grid[(i * size) + 7] = 0x10;
  494. grid[(7 * size) + (size - 1 - i)] = 0x10;
  495. grid[(i * size) + (size - 8)] = 0x10;
  496. grid[((size - 8) * size) + i] = 0x10;
  497. grid[((size - 1 - i) * size) + 7] = 0x10;
  498. }
  499. grid[(7 * size) + 7] = 0x10;
  500. grid[(7 * size) + (size - 8)] = 0x10;
  501. grid[((size - 8) * size) + 7] = 0x10;
  502. /* Add alignment patterns */
  503. if(version != 1) {
  504. /* Version 1 does not have alignment patterns */
  505. loopsize = qr_align_loopsize[version - 1];
  506. for(x = 0; x < loopsize; x++) {
  507. for(y = 0; y < loopsize; y++) {
  508. xcoord = qr_table_e1[((version - 2) * 7) + x];
  509. ycoord = qr_table_e1[((version - 2) * 7) + y];
  510. if(!(grid[(ycoord * size) + xcoord] & 0x10)) {
  511. place_align(grid, size, xcoord, ycoord);
  512. }
  513. }
  514. }
  515. }
  516. /* Reserve space for format information */
  517. for(int i = 0; i < 8; i++) {
  518. grid[(8 * size) + i] += 0x20;
  519. grid[(i * size) + 8] += 0x20;
  520. grid[(8 * size) + (size - 1 - i)] = 0x20;
  521. grid[((size - 1 - i) * size) + 8] = 0x20;
  522. }
  523. grid[(8 * size) + 8] += 20;
  524. grid[((size - 1 - 7) * size) + 8] = 0x21; /* Dark Module from Figure 25 */
  525. /* Reserve space for version information */
  526. if (version >= 7) {
  527. for (int i = 0; i < 6; i++) {
  528. grid[((size - 9) * size) + i] = 0x20;
  529. grid[((size - 10) * size) + i] = 0x20;
  530. grid[((size - 11) * size) + i] = 0x20;
  531. grid[(i * size) + (size - 9)] = 0x20;
  532. grid[(i * size) + (size - 10)] = 0x20;
  533. grid[(i * size) + (size - 11)] = 0x20;
  534. }
  535. }
  536. }
  537. int cwbit(int* datastream, int i) {
  538. int word = i >> 3;
  539. int bit = 7 - (i & 7);
  540. return (datastream[word] >> bit) & 1;
  541. }
  542. void populate_grid(unsigned char* grid, int size, int* datastream, int cw)
  543. {
  544. int direction = 1; /* up */
  545. int row = 0; /* right hand side */
  546. int i, n, x, y;
  547. n = cw * 8;
  548. y = size - 1;
  549. i = 0;
  550. do {
  551. x = (size - 2) - (row * 2);
  552. if(x < 6)
  553. x--; /* skip over vertical timing pattern */
  554. if(!(grid[(y * size) + (x + 1)] & 0xf0)) {
  555. if (cwbit(datastream, i)) {
  556. grid[(y * size) + (x + 1)] = 0x01;
  557. } else {
  558. grid[(y * size) + (x + 1)] = 0x00;
  559. }
  560. i++;
  561. }
  562. if(i < n) {
  563. if(!(grid[(y * size) + x] & 0xf0)) {
  564. if (cwbit(datastream, i)) {
  565. grid[(y * size) + x] = 0x01;
  566. } else {
  567. grid[(y * size) + x] = 0x00;
  568. }
  569. i++;
  570. }
  571. }
  572. if(direction) { y--; } else { y++; }
  573. if(y == -1) {
  574. /* reached the top */
  575. row++;
  576. y = 0;
  577. direction = 0;
  578. }
  579. if(y == size) {
  580. /* reached the bottom */
  581. row++;
  582. y = size - 1;
  583. direction = 1;
  584. }
  585. } while (i < n);
  586. }
  587. int evaluate(unsigned char *grid, int size, int pattern)
  588. {
  589. int x, y, block;
  590. int result = 0;
  591. char state;
  592. int p;
  593. int dark_mods;
  594. int percentage, k;
  595. char local[size * size];
  596. for(x = 0; x < size; x++) {
  597. for(y = 0; y < size; y++) {
  598. switch(pattern) {
  599. case 0: if (grid[(y * size) + x] & 0x01) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  600. case 1: if (grid[(y * size) + x] & 0x02) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  601. case 2: if (grid[(y * size) + x] & 0x04) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  602. case 3: if (grid[(y * size) + x] & 0x08) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  603. case 4: if (grid[(y * size) + x] & 0x10) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  604. case 5: if (grid[(y * size) + x] & 0x20) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  605. case 6: if (grid[(y * size) + x] & 0x40) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  606. case 7: if (grid[(y * size) + x] & 0x80) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break;
  607. }
  608. }
  609. }
  610. /* Test 1: Adjacent modules in row/column in same colour */
  611. /* Vertical */
  612. for(x = 0; x < size; x++) {
  613. state = local[x];
  614. block = 0;
  615. for(y = 0; y < size; y++) {
  616. if(local[(y * size) + x] == state) {
  617. block++;
  618. } else {
  619. if(block > 5) {
  620. result += (3 + block);
  621. }
  622. block = 0;
  623. state = local[(y * size) + x];
  624. }
  625. }
  626. if(block > 5) {
  627. result += (3 + block);
  628. }
  629. }
  630. /* Horizontal */
  631. for(y = 0; y < size; y++) {
  632. state = local[y * size];
  633. block = 0;
  634. for(x = 0; x < size; x++) {
  635. if(local[(y * size) + x] == state) {
  636. block++;
  637. } else {
  638. if(block > 5) {
  639. result += (3 + block);
  640. }
  641. block = 0;
  642. state = local[(y * size) + x];
  643. }
  644. }
  645. if(block > 5) {
  646. result += (3 + block);
  647. }
  648. }
  649. /* Test 2 is not implimented */
  650. /* Test 3: 1:1:3:1:1 ratio pattern in row/column */
  651. /* Vertical */
  652. for(x = 0; x < size; x++) {
  653. for(y = 0; y < (size - 7); y++) {
  654. p = 0;
  655. if(local[(y * size) + x] == '1') { p += 0x40; }
  656. if(local[((y + 1) * size) + x] == '1') { p += 0x20; }
  657. if(local[((y + 2) * size) + x] == '1') { p += 0x10; }
  658. if(local[((y + 3) * size) + x] == '1') { p += 0x08; }
  659. if(local[((y + 4) * size) + x] == '1') { p += 0x04; }
  660. if(local[((y + 5) * size) + x] == '1') { p += 0x02; }
  661. if(local[((y + 6) * size) + x] == '1') { p += 0x01; }
  662. if(p == 0x5d) {
  663. result += 40;
  664. }
  665. }
  666. }
  667. /* Horizontal */
  668. for(y = 0; y < size; y++) {
  669. for(x = 0; x < (size - 7); x++) {
  670. p = 0;
  671. if(local[(y * size) + x] == '1') { p += 0x40; }
  672. if(local[(y * size) + x + 1] == '1') { p += 0x20; }
  673. if(local[(y * size) + x + 2] == '1') { p += 0x10; }
  674. if(local[(y * size) + x + 3] == '1') { p += 0x08; }
  675. if(local[(y * size) + x + 4] == '1') { p += 0x04; }
  676. if(local[(y * size) + x + 5] == '1') { p += 0x02; }
  677. if(local[(y * size) + x + 6] == '1') { p += 0x01; }
  678. if(p == 0x5d) {
  679. result += 40;
  680. }
  681. }
  682. }
  683. /* Test 4: Proportion of dark modules in entire symbol */
  684. dark_mods = 0;
  685. for(x = 0; x < size; x++) {
  686. for(y = 0; y < size; y++) {
  687. if(local[(y * size) + x] == '1') {
  688. dark_mods++;
  689. }
  690. }
  691. }
  692. percentage = 100 * (dark_mods / (size * size));
  693. if(percentage <= 50) {
  694. k = ((100 - percentage) - 50) / 5;
  695. } else {
  696. k = (percentage - 50) / 5;
  697. }
  698. result += 10 * k;
  699. return result;
  700. }
  701. int apply_bitmask(unsigned char *grid, int size)
  702. {
  703. int x, y;
  704. unsigned char p;
  705. int pattern, penalty[8];
  706. int best_val, best_pattern;
  707. int bit;
  708. unsigned char mask[size * size];
  709. unsigned char eval[size * size];
  710. /* Perform data masking */
  711. for(x = 0; x < size; x++) {
  712. for(y = 0; y < size; y++) {
  713. mask[(y * size) + x] = 0x00;
  714. if (!(grid[(y * size) + x] & 0xf0)) {
  715. if(((y + x) & 1) == 0) { mask[(y * size) + x] += 0x01; }
  716. if((y & 1) == 0) { mask[(y * size) + x] += 0x02; }
  717. if((x % 3) == 0) { mask[(y * size) + x] += 0x04; }
  718. if(((y + x) % 3) == 0) { mask[(y * size) + x] += 0x08; }
  719. if((((y / 2) + (x / 3)) & 1) == 0) { mask[(y * size) + x] += 0x10; }
  720. if((((y * x) & 1) + ((y * x) % 3)) == 0) { mask[(y * size) + x] += 0x20; }
  721. if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x40; }
  722. if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x80; }
  723. }
  724. }
  725. }
  726. for(x = 0; x < size; x++) {
  727. for(y = 0; y < size; y++) {
  728. if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; }
  729. eval[(y * size) + x] = mask[(y * size) + x] ^ p;
  730. }
  731. }
  732. /* Evaluate result */
  733. for(pattern = 0; pattern < 8; pattern++) {
  734. penalty[pattern] = evaluate(eval, size, pattern);
  735. }
  736. best_pattern = 0;
  737. best_val = penalty[0];
  738. for(pattern = 1; pattern < 8; pattern++) {
  739. if(penalty[pattern] < best_val) {
  740. best_pattern = pattern;
  741. best_val = penalty[pattern];
  742. }
  743. }
  744. /* Apply mask */
  745. for(x = 0; x < size; x++) {
  746. for(y = 0; y < size; y++) {
  747. bit = 0;
  748. switch(best_pattern) {
  749. case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break;
  750. case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break;
  751. case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break;
  752. case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break;
  753. case 4: if(mask[(y * size) + x] & 0x10) { bit = 1; } break;
  754. case 5: if(mask[(y * size) + x] & 0x20) { bit = 1; } break;
  755. case 6: if(mask[(y * size) + x] & 0x40) { bit = 1; } break;
  756. case 7: if(mask[(y * size) + x] & 0x80) { bit = 1; } break;
  757. }
  758. if(bit == 1) {
  759. if(grid[(y * size) + x] & 0x01) {
  760. grid[(y * size) + x] = 0x00;
  761. } else {
  762. grid[(y * size) + x] = 0x01;
  763. }
  764. }
  765. }
  766. }
  767. return best_pattern;
  768. }
  769. void add_format_info(unsigned char *grid, int size, int ecc_level, int pattern)
  770. {
  771. /* Add format information to grid */
  772. int format = pattern;
  773. unsigned int seq;
  774. int i;
  775. switch(ecc_level) {
  776. case LEVEL_L: format += 0x08; break;
  777. case LEVEL_Q: format += 0x18; break;
  778. case LEVEL_H: format += 0x10; break;
  779. }
  780. seq = qr_annex_c[format];
  781. for(i = 0; i < 6; i++) {
  782. grid[(i * size) + 8] += (seq >> i) & 0x01;
  783. }
  784. for(i = 0; i < 8; i++) {
  785. grid[(8 * size) + (size - i - 1)] += (seq >> i) & 0x01;
  786. }
  787. for(i = 0; i < 6; i++) {
  788. grid[(8 * size) + (5 - i)] += (seq >> (i + 9)) & 0x01;
  789. }
  790. for(i = 0; i < 7; i++) {
  791. grid[(((size - 7) + i) * size) + 8] += (seq >> (i + 8)) & 0x01;
  792. }
  793. grid[(7 * size) + 8] += (seq >> 6) & 0x01;
  794. grid[(8 * size) + 8] += (seq >> 7) & 0x01;
  795. grid[(8 * size) + 7] += (seq >> 8) & 0x01;
  796. }
  797. void add_version_info(unsigned char *grid, int size, int version)
  798. {
  799. /* Add version information */
  800. int i;
  801. long int version_data = qr_annex_d[version - 7];
  802. for(i = 0; i < 6; i++) {
  803. grid[((size - 11) * size) + i] += (version_data >> (i * 3)) & 0x01;
  804. grid[((size - 10) * size) + i] += (version_data >> ((i * 3) + 1)) & 0x01;
  805. grid[((size - 9) * size) + i] += (version_data >> ((i * 3) + 2)) & 0x01;
  806. grid[(i * size) + (size - 11)] += (version_data >> (i * 3)) & 0x01;
  807. grid[(i * size) + (size - 10)] += (version_data >> ((i * 3) + 1)) & 0x01;
  808. grid[(i * size) + (size - 9)] += (version_data >> ((i * 3) + 2)) & 0x01;
  809. }
  810. }
  811. int qr_code(struct zint_symbol *symbol, unsigned char source[], int length)
  812. {
  813. int error_number, glyph, est_binlen;
  814. int ecc_level, autosize, version, max_cw, target_binlen, blocks, size;
  815. int bitmask, gs1;
  816. int utfdata[length + 1];
  817. int jisdata[length + 1];
  818. char mode[length + 1];
  819. gs1 = (symbol->input_mode == GS1_MODE);
  820. switch(symbol->input_mode) {
  821. case DATA_MODE:
  822. for(int i = 0; i < length; i++) {
  823. jisdata[i] = (int)source[i];
  824. }
  825. break;
  826. default:
  827. /* Convert Unicode input to Shift-JIS */
  828. error_number = utf8toutf16(symbol, source, utfdata, &length);
  829. if(error_number != 0) { return error_number; }
  830. for(int i = 0; i < length; i++) {
  831. if(utfdata[i] <= 0xff) {
  832. jisdata[i] = utfdata[i];
  833. } else {
  834. int j = 0;
  835. glyph = 0;
  836. do {
  837. if(sjis_lookup[j * 2] == utfdata[i]) {
  838. glyph = sjis_lookup[(j * 2) + 1];
  839. }
  840. j++;
  841. } while ((j < 6843) && (glyph == 0));
  842. if(glyph == 0) {
  843. strcpy(symbol->errtxt, "Invalid character in input data");
  844. return ZERROR_INVALID_DATA;
  845. }
  846. jisdata[i] = glyph;
  847. }
  848. }
  849. break;
  850. }
  851. define_mode(mode, jisdata, length, gs1);
  852. est_binlen = estimate_binary_length(mode, length, gs1);
  853. ecc_level = LEVEL_L;
  854. max_cw = 2956;
  855. if((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) {
  856. switch (symbol->option_1) {
  857. case 1: ecc_level = LEVEL_L; max_cw = 2956; break;
  858. case 2: ecc_level = LEVEL_M; max_cw = 2334; break;
  859. case 3: ecc_level = LEVEL_Q; max_cw = 1666; break;
  860. case 4: ecc_level = LEVEL_H; max_cw = 1276; break;
  861. }
  862. }
  863. if(est_binlen > (8 * max_cw)) {
  864. strcpy(symbol->errtxt, "Input too long for selected error correction level");
  865. return ZERROR_TOO_LONG;
  866. }
  867. autosize = 40;
  868. for(int i = 39; i >= 0; i--) {
  869. switch(ecc_level) {
  870. case LEVEL_L:
  871. if ((8 * qr_data_codewords_L[i]) >= est_binlen) {
  872. autosize = i + 1;
  873. }
  874. break;
  875. case LEVEL_M:
  876. if ((8 * qr_data_codewords_M[i]) >= est_binlen) {
  877. autosize = i + 1;
  878. }
  879. break;
  880. case LEVEL_Q:
  881. if ((8 * qr_data_codewords_Q[i]) >= est_binlen) {
  882. autosize = i + 1;
  883. }
  884. break;
  885. case LEVEL_H:
  886. if ((8 * qr_data_codewords_H[i]) >= est_binlen) {
  887. autosize = i + 1;
  888. }
  889. break;
  890. }
  891. }
  892. if((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) {
  893. if (symbol->option_2 > autosize) {
  894. version = symbol->option_2;
  895. } else {
  896. version = autosize;
  897. }
  898. } else {
  899. version = autosize;
  900. }
  901. /* Ensure maxium error correction capacity */
  902. if(est_binlen <= qr_data_codewords_M[version - 1]) { ecc_level = LEVEL_M; }
  903. if(est_binlen <= qr_data_codewords_Q[version - 1]) { ecc_level = LEVEL_Q; }
  904. if(est_binlen <= qr_data_codewords_H[version - 1]) { ecc_level = LEVEL_H; }
  905. target_binlen = qr_data_codewords_L[version - 1]; blocks = qr_blocks_L[version - 1];
  906. switch(ecc_level) {
  907. case LEVEL_M: target_binlen = qr_data_codewords_M[version - 1]; blocks = qr_blocks_M[version - 1]; break;
  908. case LEVEL_Q: target_binlen = qr_data_codewords_Q[version - 1]; blocks = qr_blocks_Q[version - 1]; break;
  909. case LEVEL_H: target_binlen = qr_data_codewords_H[version - 1]; blocks = qr_blocks_H[version - 1]; break;
  910. }
  911. int datastream[target_binlen + 1];
  912. int fullstream[qr_total_codewords[version - 1] + 1];
  913. qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, est_binlen);
  914. add_ecc(fullstream, datastream, version, target_binlen, blocks);
  915. size = qr_sizes[version - 1];
  916. unsigned char grid[size * size];
  917. for (int i = 0; i < size; i++) {
  918. for(int j = 0; j < size; j++) {
  919. grid[(i * size) + j] = 0;
  920. }
  921. }
  922. setup_grid(grid, size, version);
  923. populate_grid(grid, size, fullstream, qr_total_codewords[version - 1]);
  924. bitmask = apply_bitmask(grid, size);
  925. add_format_info(grid, size, ecc_level, bitmask);
  926. if (version >= 7) {
  927. add_version_info(grid, size, version);
  928. }
  929. symbol->width = size;
  930. symbol->rows = size;
  931. for (int i = 0; i < size; i++) {
  932. for (int j = 0; j < size; j++) {
  933. if (grid[(i * size) + j] & 0x01) {
  934. set_module(symbol, i, j);
  935. }
  936. }
  937. symbol->row_height[i] = 1;
  938. }
  939. return 0;
  940. }
  941. /* NOTE: From this point forward concerns Micro QR Code only */
  942. int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, int *kanji_used, int *alphanum_used, int *byte_used)
  943. {
  944. /* Convert input data to an "intermediate stage" where data is binary encoded but
  945. control information is not */
  946. int position = 0, debug = 0;
  947. int short_data_block_length, i;
  948. char data_block;
  949. char buffer[2];
  950. strcpy(binary, "");
  951. if(debug) {
  952. for(i = 0; i < length; i++) {
  953. printf("%c", mode[i]);
  954. }
  955. printf("\n");
  956. }
  957. do {
  958. if(strlen(binary) > 128) {
  959. return ZERROR_TOO_LONG;
  960. }
  961. data_block = mode[position];
  962. short_data_block_length = 0;
  963. do {
  964. short_data_block_length++;
  965. } while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block));
  966. switch(data_block) {
  967. case 'K':
  968. /* Kanji mode */
  969. /* Mode indicator */
  970. concat(binary, "K");
  971. *kanji_used = 1;
  972. /* Character count indicator */
  973. buffer[0] = short_data_block_length;
  974. buffer[1] = '\0';
  975. concat(binary, buffer);
  976. if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); }
  977. /* Character representation */
  978. for(i = 0; i < short_data_block_length; i++) {
  979. int jis = jisdata[position + i];
  980. int msb, lsb, prod;
  981. if(jis > 0x9fff) { jis -= 0xc140; }
  982. msb = (jis & 0xff00) >> 4;
  983. lsb = (jis & 0xff);
  984. prod = (msb * 0xc0) + lsb;
  985. bscan(binary, prod, 0x1000);
  986. if(debug) { printf("0x%4X ", prod); }
  987. if(strlen(binary) > 128) {
  988. return ZERROR_TOO_LONG;
  989. }
  990. }
  991. if(debug) { printf("\n"); }
  992. break;
  993. case 'B':
  994. /* Byte mode */
  995. /* Mode indicator */
  996. concat(binary, "B");
  997. *byte_used = 1;
  998. /* Character count indicator */
  999. buffer[0] = short_data_block_length;
  1000. buffer[1] = '\0';
  1001. concat(binary, buffer);
  1002. if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); }
  1003. /* Character representation */
  1004. for(i = 0; i < short_data_block_length; i++) {
  1005. int byte = jisdata[position + i];
  1006. bscan(binary, byte, 0x80);
  1007. if(debug) { printf("0x%4X ", byte); }
  1008. if(strlen(binary) > 128) {
  1009. return ZERROR_TOO_LONG;
  1010. }
  1011. }
  1012. if(debug) { printf("\n"); }
  1013. break;
  1014. case 'A':
  1015. /* Alphanumeric mode */
  1016. /* Mode indicator */
  1017. concat(binary, "A");
  1018. *alphanum_used = 1;
  1019. /* Character count indicator */
  1020. buffer[0] = short_data_block_length;
  1021. buffer[1] = '\0';
  1022. concat(binary, buffer);
  1023. if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); }
  1024. /* Character representation */
  1025. i = 0;
  1026. while ( i < short_data_block_length ) {
  1027. int count;
  1028. int first = 0, second = 0, prod;
  1029. first = posn(RHODIUM, (char) jisdata[position + i]);
  1030. count = 1;
  1031. prod = first;
  1032. if(mode[position + i + 1] == 'A') {
  1033. second = posn(RHODIUM, (char) jisdata[position + i + 1]);
  1034. count = 2;
  1035. prod = (first * 45) + second;
  1036. }
  1037. bscan(binary, prod, 1 << (5 * count)); /* count = 1..2 */
  1038. if(debug) { printf("0x%4X ", prod); }
  1039. if(strlen(binary) > 128) {
  1040. return ZERROR_TOO_LONG;
  1041. }
  1042. i += 2;
  1043. };
  1044. if(debug) { printf("\n"); }
  1045. break;
  1046. case 'N':
  1047. /* Numeric mode */
  1048. /* Mode indicator */
  1049. concat(binary, "N");
  1050. /* Character count indicator */
  1051. buffer[0] = short_data_block_length;
  1052. buffer[1] = '\0';
  1053. concat(binary, buffer);
  1054. if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); }
  1055. /* Character representation */
  1056. i = 0;
  1057. while ( i < short_data_block_length ) {
  1058. int count;
  1059. int first = 0, second = 0, third = 0, prod;
  1060. first = posn(NEON, (char) jisdata[position + i]);
  1061. count = 1;
  1062. prod = first;
  1063. if(mode[position + i + 1] == 'N') {
  1064. second = posn(NEON, (char) jisdata[position + i + 1]);
  1065. count = 2;
  1066. prod = (prod * 10) + second;
  1067. }
  1068. if(mode[position + i + 2] == 'N') {
  1069. third = posn(NEON, (char) jisdata[position + i + 2]);
  1070. count = 3;
  1071. prod = (prod * 10) + third;
  1072. }
  1073. bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */
  1074. if(debug) { printf("0x%4X (%d)", prod, prod); }
  1075. if(strlen(binary) > 128) {
  1076. return ZERROR_TOO_LONG;
  1077. }
  1078. i += 3;
  1079. };
  1080. if(debug) { printf("\n"); }
  1081. break;
  1082. }
  1083. position += short_data_block_length;
  1084. } while (position < length - 1) ;
  1085. return 0;
  1086. }
  1087. void get_bitlength(int count[], char stream[]) {
  1088. int length, i;
  1089. length = strlen(stream);
  1090. for(i = 0; i < 4; i++) {
  1091. count[i] = 0;
  1092. }
  1093. i = 0;
  1094. do {
  1095. if((stream[i] == '0') || (stream[i] == '1')) {
  1096. count[0]++;
  1097. count[1]++;
  1098. count[2]++;
  1099. count[3]++;
  1100. i++;
  1101. } else {
  1102. switch(stream[i]) {
  1103. case 'K':
  1104. count[2] += 5;
  1105. count[3] += 7;
  1106. i += 2;
  1107. break;
  1108. case 'B':
  1109. count[2] += 6;
  1110. count[3] += 8;
  1111. i += 2;
  1112. break;
  1113. case 'A':
  1114. count[1] += 4;
  1115. count[2] += 6;
  1116. count[3] += 8;
  1117. i += 2;
  1118. break;
  1119. case 'N':
  1120. count[0] += 3;
  1121. count[1] += 5;
  1122. count[2] += 7;
  1123. count[3] += 9;
  1124. i += 2;
  1125. break;
  1126. }
  1127. }
  1128. } while (i < length);
  1129. }
  1130. void microqr_expand_binary(char binary_stream[], char full_stream[], int version)
  1131. {
  1132. int i, length;
  1133. length = strlen(binary_stream);
  1134. i = 0;
  1135. do {
  1136. switch(binary_stream[i]) {
  1137. case '1': concat(full_stream, "1"); i++; break;
  1138. case '0': concat(full_stream, "0"); i++; break;
  1139. case 'N':
  1140. /* Numeric Mode */
  1141. /* Mode indicator */
  1142. switch(version) {
  1143. case 1: concat(full_stream, "0"); break;
  1144. case 2: concat(full_stream, "00"); break;
  1145. case 3: concat(full_stream, "000"); break;
  1146. }
  1147. /* Character count indicator */
  1148. bscan(full_stream, binary_stream[i + 1], 4 << version); /* version = 0..3 */
  1149. i += 2;
  1150. break;
  1151. case 'A':
  1152. /* Alphanumeric Mode */
  1153. /* Mode indicator */
  1154. switch(version) {
  1155. case 1: concat(full_stream, "1"); break;
  1156. case 2: concat(full_stream, "01"); break;
  1157. case 3: concat(full_stream, "001"); break;
  1158. }
  1159. /* Character count indicator */
  1160. bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 1..3 */
  1161. i += 2;
  1162. break;
  1163. case 'B':
  1164. /* Byte Mode */
  1165. /* Mode indicator */
  1166. switch(version) {
  1167. case 2: concat(full_stream, "10"); break;
  1168. case 3: concat(full_stream, "010"); break;
  1169. }
  1170. /* Character count indicator */
  1171. bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 2..3 */
  1172. i += 2;
  1173. break;
  1174. case 'K':
  1175. /* Kanji Mode */
  1176. /* Mode indicator */
  1177. switch(version) {
  1178. case 2: concat(full_stream, "11"); break;
  1179. case 3: concat(full_stream, "011"); break;
  1180. }
  1181. /* Character count indicator */
  1182. bscan(full_stream, binary_stream[i + 1], 1 << version); /* version = 2..3 */
  1183. i += 2;
  1184. break;
  1185. }
  1186. } while (i < length);
  1187. }
  1188. void micro_qr_m1(char binary_data[])
  1189. {
  1190. int i, latch;
  1191. int bits_total, bits_left, remainder;
  1192. int data_codewords, ecc_codewords;
  1193. unsigned char data_blocks[4], ecc_blocks[3];
  1194. bits_total = 20;
  1195. latch = 0;
  1196. /* Add terminator */
  1197. bits_left = bits_total - strlen(binary_data);
  1198. if(bits_left <= 3) {
  1199. for(i = 0; i < bits_left; i++) {
  1200. concat(binary_data, "0");
  1201. }
  1202. latch = 1;
  1203. } else {
  1204. concat(binary_data, "000");
  1205. }
  1206. if(latch == 0) {
  1207. /* Manage last (4-bit) block */
  1208. bits_left = bits_total - strlen(binary_data);
  1209. if(bits_left <= 4) {
  1210. for(i = 0; i < bits_left; i++) {
  1211. concat(binary_data, "0");
  1212. }
  1213. latch = 1;
  1214. }
  1215. }
  1216. if(latch == 0) {
  1217. /* Complete current byte */
  1218. remainder = 8 - (strlen(binary_data) % 8);
  1219. if(remainder == 8) { remainder = 0; }
  1220. for(i = 0; i < remainder; i++) {
  1221. concat(binary_data, "0");
  1222. }
  1223. /* Add padding */
  1224. bits_left = bits_total - strlen(binary_data);
  1225. if(bits_left > 4) {
  1226. remainder = (bits_left - 4) / 8;
  1227. for(i = 0; i < remainder; i++) {
  1228. concat(binary_data, i & 1 ? "00010001" : "11101100");
  1229. }
  1230. }
  1231. concat(binary_data, "0000");
  1232. }
  1233. data_codewords = 3;
  1234. ecc_codewords = 2;
  1235. /* Copy data into codewords */
  1236. for(i = 0; i < (data_codewords - 1); i++) {
  1237. data_blocks[i] = 0;
  1238. if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
  1239. if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
  1240. if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
  1241. if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
  1242. if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
  1243. if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
  1244. if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
  1245. if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
  1246. }
  1247. data_blocks[2] = 0;
  1248. if(binary_data[16] == '1') { data_blocks[2] += 0x08; }
  1249. if(binary_data[17] == '1') { data_blocks[2] += 0x04; }
  1250. if(binary_data[18] == '1') { data_blocks[2] += 0x02; }
  1251. if(binary_data[19] == '1') { data_blocks[2] += 0x01; }
  1252. /* Calculate Reed-Solomon error codewords */
  1253. rs_init_gf(0x11d);
  1254. rs_init_code(ecc_codewords, 0);
  1255. rs_encode(data_codewords,data_blocks,ecc_blocks);
  1256. rs_free();
  1257. /* Add Reed-Solomon codewords to binary data */
  1258. for(i = 0; i < ecc_codewords; i++) {
  1259. bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
  1260. }
  1261. }
  1262. void micro_qr_m2(char binary_data[], int ecc_mode)
  1263. {
  1264. int i, latch;
  1265. int bits_total, bits_left, remainder;
  1266. int data_codewords, ecc_codewords;
  1267. unsigned char data_blocks[6], ecc_blocks[7];
  1268. latch = 0;
  1269. if(ecc_mode == LEVEL_L) { bits_total = 40; }
  1270. if(ecc_mode == LEVEL_M) { bits_total = 32; }
  1271. /* Add terminator */
  1272. bits_left = bits_total - strlen(binary_data);
  1273. if(bits_left <= 5) {
  1274. for(i = 0; i < bits_left; i++) {
  1275. concat(binary_data, "0");
  1276. }
  1277. latch = 1;
  1278. } else {
  1279. concat(binary_data, "00000");
  1280. }
  1281. if(latch == 0) {
  1282. /* Complete current byte */
  1283. remainder = 8 - (strlen(binary_data) % 8);
  1284. if(remainder == 8) { remainder = 0; }
  1285. for(i = 0; i < remainder; i++) {
  1286. concat(binary_data, "0");
  1287. }
  1288. /* Add padding */
  1289. bits_left = bits_total - strlen(binary_data);
  1290. remainder = bits_left / 8;
  1291. for(i = 0; i < remainder; i++) {
  1292. concat(binary_data, i & 1 ? "00010001" : "11101100");
  1293. }
  1294. }
  1295. if(ecc_mode == LEVEL_L) { data_codewords = 5; ecc_codewords = 5; }
  1296. if(ecc_mode == LEVEL_M) { data_codewords = 4; ecc_codewords = 6; }
  1297. /* Copy data into codewords */
  1298. for(i = 0; i < data_codewords; i++) {
  1299. data_blocks[i] = 0;
  1300. if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
  1301. if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
  1302. if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
  1303. if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
  1304. if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
  1305. if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
  1306. if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
  1307. if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
  1308. }
  1309. /* Calculate Reed-Solomon error codewords */
  1310. rs_init_gf(0x11d);
  1311. rs_init_code(ecc_codewords, 0);
  1312. rs_encode(data_codewords,data_blocks,ecc_blocks);
  1313. rs_free();
  1314. /* Add Reed-Solomon codewords to binary data */
  1315. for(i = 0; i < ecc_codewords; i++) {
  1316. bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
  1317. }
  1318. return;
  1319. }
  1320. void micro_qr_m3(char binary_data[], int ecc_mode)
  1321. {
  1322. int i, latch;
  1323. int bits_total, bits_left, remainder;
  1324. int data_codewords, ecc_codewords;
  1325. unsigned char data_blocks[12], ecc_blocks[9];
  1326. latch = 0;
  1327. if(ecc_mode == LEVEL_L) { bits_total = 84; }
  1328. if(ecc_mode == LEVEL_M) { bits_total = 68; }
  1329. /* Add terminator */
  1330. bits_left = bits_total - strlen(binary_data);
  1331. if(bits_left <= 7) {
  1332. for(i = 0; i < bits_left; i++) {
  1333. concat(binary_data, "0");
  1334. }
  1335. latch = 1;
  1336. } else {
  1337. concat(binary_data, "0000000");
  1338. }
  1339. if(latch == 0) {
  1340. /* Manage last (4-bit) block */
  1341. bits_left = bits_total - strlen(binary_data);
  1342. if(bits_left <= 4) {
  1343. for(i = 0; i < bits_left; i++) {
  1344. concat(binary_data, "0");
  1345. }
  1346. latch = 1;
  1347. }
  1348. }
  1349. if(latch == 0) {
  1350. /* Complete current byte */
  1351. remainder = 8 - (strlen(binary_data) % 8);
  1352. if(remainder == 8) { remainder = 0; }
  1353. for(i = 0; i < remainder; i++) {
  1354. concat(binary_data, "0");
  1355. }
  1356. /* Add padding */
  1357. bits_left = bits_total - strlen(binary_data);
  1358. if(bits_left > 4) {
  1359. remainder = (bits_left - 4) / 8;
  1360. for(i = 0; i < remainder; i++) {
  1361. concat(binary_data, i & 1 ? "00010001" : "11101100");
  1362. }
  1363. }
  1364. concat(binary_data, "0000");
  1365. }
  1366. if(ecc_mode == LEVEL_L) { data_codewords = 11; ecc_codewords = 6; }
  1367. if(ecc_mode == LEVEL_M) { data_codewords = 9; ecc_codewords = 8; }
  1368. /* Copy data into codewords */
  1369. for(i = 0; i < (data_codewords - 1); i++) {
  1370. data_blocks[i] = 0;
  1371. if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
  1372. if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
  1373. if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
  1374. if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
  1375. if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
  1376. if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
  1377. if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
  1378. if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
  1379. }
  1380. if(ecc_mode == LEVEL_L) {
  1381. data_blocks[11] = 0;
  1382. if(binary_data[80] == '1') { data_blocks[2] += 0x08; }
  1383. if(binary_data[81] == '1') { data_blocks[2] += 0x04; }
  1384. if(binary_data[82] == '1') { data_blocks[2] += 0x02; }
  1385. if(binary_data[83] == '1') { data_blocks[2] += 0x01; }
  1386. }
  1387. if(ecc_mode == LEVEL_M) {
  1388. data_blocks[9] = 0;
  1389. if(binary_data[64] == '1') { data_blocks[2] += 0x08; }
  1390. if(binary_data[65] == '1') { data_blocks[2] += 0x04; }
  1391. if(binary_data[66] == '1') { data_blocks[2] += 0x02; }
  1392. if(binary_data[67] == '1') { data_blocks[2] += 0x01; }
  1393. }
  1394. /* Calculate Reed-Solomon error codewords */
  1395. rs_init_gf(0x11d);
  1396. rs_init_code(ecc_codewords, 0);
  1397. rs_encode(data_codewords,data_blocks,ecc_blocks);
  1398. rs_free();
  1399. /* Add Reed-Solomon codewords to binary data */
  1400. for(i = 0; i < ecc_codewords; i++) {
  1401. bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
  1402. }
  1403. return;
  1404. }
  1405. void micro_qr_m4(char binary_data[], int ecc_mode)
  1406. {
  1407. int i, latch;
  1408. int bits_total, bits_left, remainder;
  1409. int data_codewords, ecc_codewords;
  1410. unsigned char data_blocks[17], ecc_blocks[15];
  1411. latch = 0;
  1412. if(ecc_mode == LEVEL_L) { bits_total = 128; }
  1413. if(ecc_mode == LEVEL_M) { bits_total = 112; }
  1414. if(ecc_mode == LEVEL_Q) { bits_total = 80; }
  1415. /* Add terminator */
  1416. bits_left = bits_total - strlen(binary_data);
  1417. if(bits_left <= 9) {
  1418. for(i = 0; i < bits_left; i++) {
  1419. concat(binary_data, "0");
  1420. }
  1421. latch = 1;
  1422. } else {
  1423. concat(binary_data, "000000000");
  1424. }
  1425. if(latch == 0) {
  1426. /* Complete current byte */
  1427. remainder = 8 - (strlen(binary_data) % 8);
  1428. if(remainder == 8) { remainder = 0; }
  1429. for(i = 0; i < remainder; i++) {
  1430. concat(binary_data, "0");
  1431. }
  1432. /* Add padding */
  1433. bits_left = bits_total - strlen(binary_data);
  1434. remainder = bits_left / 8;
  1435. for(i = 0; i < remainder; i++) {
  1436. concat(binary_data, i & 1 ? "00010001" : "11101100");
  1437. }
  1438. }
  1439. if(ecc_mode == LEVEL_L) { data_codewords = 16; ecc_codewords = 8; }
  1440. if(ecc_mode == LEVEL_M) { data_codewords = 14; ecc_codewords = 10; }
  1441. if(ecc_mode == LEVEL_Q) { data_codewords = 10; ecc_codewords = 14; }
  1442. /* Copy data into codewords */
  1443. for(i = 0; i < data_codewords; i++) {
  1444. data_blocks[i] = 0;
  1445. if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; }
  1446. if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; }
  1447. if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; }
  1448. if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; }
  1449. if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; }
  1450. if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; }
  1451. if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; }
  1452. if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; }
  1453. }
  1454. /* Calculate Reed-Solomon error codewords */
  1455. rs_init_gf(0x11d);
  1456. rs_init_code(ecc_codewords, 0);
  1457. rs_encode(data_codewords,data_blocks,ecc_blocks);
  1458. rs_free();
  1459. /* Add Reed-Solomon codewords to binary data */
  1460. for(i = 0; i < ecc_codewords; i++) {
  1461. bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
  1462. }
  1463. }
  1464. void micro_setup_grid(unsigned char* grid, int size)
  1465. {
  1466. int i, toggle = 1;
  1467. /* Add timing patterns */
  1468. for(i = 0; i < size; i++) {
  1469. if(toggle == 1) {
  1470. grid[i] = 0x21;
  1471. grid[(i * size)] = 0x21;
  1472. toggle = 0;
  1473. } else {
  1474. grid[i] = 0x20;
  1475. grid[(i * size)] = 0x20;
  1476. toggle = 1;
  1477. }
  1478. }
  1479. /* Add finder patterns */
  1480. place_finder(grid, size, 0, 0);
  1481. /* Add separators */
  1482. for(i = 0; i < 7; i++) {
  1483. grid[(7 * size) + i] = 0x10;
  1484. grid[(i * size) + 7] = 0x10;
  1485. }
  1486. grid[(7 * size) + 7] = 0x10;
  1487. /* Reserve space for format information */
  1488. for(i = 0; i < 8; i++) {
  1489. grid[(8 * size) + i] += 0x20;
  1490. grid[(i * size) + 8] += 0x20;
  1491. }
  1492. grid[(8 * size) + 8] += 20;
  1493. }
  1494. void micro_populate_grid(unsigned char* grid, int size, char full_stream[])
  1495. {
  1496. int direction = 1; /* up */
  1497. int row = 0; /* right hand side */
  1498. int i, n, x, y;
  1499. n = strlen(full_stream);
  1500. y = size - 1;
  1501. i = 0;
  1502. do {
  1503. x = (size - 2) - (row * 2);
  1504. if(!(grid[(y * size) + (x + 1)] & 0xf0)) {
  1505. if (full_stream[i] == '1') {
  1506. grid[(y * size) + (x + 1)] = 0x01;
  1507. } else {
  1508. grid[(y * size) + (x + 1)] = 0x00;
  1509. }
  1510. i++;
  1511. }
  1512. if(i < n) {
  1513. if(!(grid[(y * size) + x] & 0xf0)) {
  1514. if (full_stream[i] == '1') {
  1515. grid[(y * size) + x] = 0x01;
  1516. } else {
  1517. grid[(y * size) + x] = 0x00;
  1518. }
  1519. i++;
  1520. }
  1521. }
  1522. if(direction) { y--; } else { y++; }
  1523. if(y == 0) {
  1524. /* reached the top */
  1525. row++;
  1526. y = 1;
  1527. direction = 0;
  1528. }
  1529. if(y == size) {
  1530. /* reached the bottom */
  1531. row++;
  1532. y = size - 1;
  1533. direction = 1;
  1534. }
  1535. } while (i < n);
  1536. }
  1537. int micro_evaluate(unsigned char *grid, int size, int pattern)
  1538. {
  1539. int sum1, sum2, i, filter = 0, retval;
  1540. switch(pattern) {
  1541. case 0: filter = 0x01; break;
  1542. case 1: filter = 0x02; break;
  1543. case 2: filter = 0x04; break;
  1544. case 3: filter = 0x08; break;
  1545. }
  1546. sum1 = 0;
  1547. sum2 = 0;
  1548. for(i = 1; i < size; i++) {
  1549. if(grid[(i * size) + size - 1] & filter) { sum1++; }
  1550. if(grid[((size - 1) * size) + i] & filter) { sum2++; }
  1551. }
  1552. if(sum1 <= sum2) { retval = (sum1 * 16) + sum2; } else { retval = (sum2 * 16) + sum1; }
  1553. return retval;
  1554. }
  1555. int micro_apply_bitmask(unsigned char *grid, int size)
  1556. {
  1557. int x, y;
  1558. unsigned char p;
  1559. int pattern, value[8];
  1560. int best_val, best_pattern;
  1561. int bit;
  1562. unsigned char mask[size * size];
  1563. unsigned char eval[size * size];
  1564. /* Perform data masking */
  1565. for(x = 0; x < size; x++) {
  1566. for(y = 0; y < size; y++) {
  1567. mask[(y * size) + x] = 0x00;
  1568. if (!(grid[(y * size) + x] & 0xf0)) {
  1569. if((y & 1) == 0) {
  1570. mask[(y * size) + x] += 0x01;
  1571. }
  1572. if((((y / 2) + (x / 3)) & 1) == 0) {
  1573. mask[(y * size) + x] += 0x02;
  1574. }
  1575. if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) {
  1576. mask[(y * size) + x] += 0x04;
  1577. }
  1578. if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) {
  1579. mask[(y * size) + x] += 0x08;
  1580. }
  1581. }
  1582. }
  1583. }
  1584. for(x = 0; x < size; x++) {
  1585. for(y = 0; y < size; y++) {
  1586. if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; }
  1587. eval[(y * size) + x] = mask[(y * size) + x] ^ p;
  1588. }
  1589. }
  1590. /* Evaluate result */
  1591. for(pattern = 0; pattern < 8; pattern++) {
  1592. value[pattern] = micro_evaluate(eval, size, pattern);
  1593. }
  1594. best_pattern = 0;
  1595. best_val = value[0];
  1596. for(pattern = 1; pattern < 4; pattern++) {
  1597. if(value[pattern] > best_val) {
  1598. best_pattern = pattern;
  1599. best_val = value[pattern];
  1600. }
  1601. }
  1602. /* Apply mask */
  1603. for(x = 0; x < size; x++) {
  1604. for(y = 0; y < size; y++) {
  1605. bit = 0;
  1606. switch(best_pattern) {
  1607. case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break;
  1608. case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break;
  1609. case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break;
  1610. case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break;
  1611. }
  1612. if(bit == 1) {
  1613. if(grid[(y * size) + x] & 0x01) {
  1614. grid[(y * size) + x] = 0x00;
  1615. } else {
  1616. grid[(y * size) + x] = 0x01;
  1617. }
  1618. }
  1619. }
  1620. }
  1621. return best_pattern;
  1622. }
  1623. int microqr(struct zint_symbol *symbol, unsigned char source[], int length)
  1624. {
  1625. int glyph, size;
  1626. char binary_stream[200];
  1627. char full_stream[200];
  1628. int utfdata[40];
  1629. int jisdata[40];
  1630. char mode[40];
  1631. int error_number, kanji_used = 0, alphanum_used = 0, byte_used = 0;
  1632. int version_valid[4];
  1633. int binary_count[4];
  1634. int ecc_level, autoversion, version;
  1635. int n_count, a_count, bitmask, format, format_full;
  1636. if(length > 35) {
  1637. strcpy(symbol->errtxt, "Input data too long");
  1638. return ZERROR_TOO_LONG;
  1639. }
  1640. for(int i = 0; i < 4; i++) {
  1641. version_valid[i] = 1;
  1642. }
  1643. switch(symbol->input_mode) {
  1644. case DATA_MODE:
  1645. for(int i = 0; i < length; i++) {
  1646. jisdata[i] = (int)source[i];
  1647. }
  1648. break;
  1649. default:
  1650. /* Convert Unicode input to Shift-JIS */
  1651. error_number = utf8toutf16(symbol, source, utfdata, &length);
  1652. if(error_number != 0) { return error_number; }
  1653. for(int i = 0; i < length; i++) {
  1654. if(utfdata[i] <= 0xff) {
  1655. jisdata[i] = utfdata[i];
  1656. } else {
  1657. int j = 0;
  1658. glyph = 0;
  1659. do {
  1660. if(sjis_lookup[j * 2] == utfdata[i]) {
  1661. glyph = sjis_lookup[(j * 2) + 1];
  1662. }
  1663. j++;
  1664. } while ((j < 6843) && (glyph == 0));
  1665. if(glyph == 0) {
  1666. strcpy(symbol->errtxt, "Invalid character in input data");
  1667. return ZERROR_INVALID_DATA;
  1668. }
  1669. jisdata[i] = glyph;
  1670. }
  1671. }
  1672. break;
  1673. }
  1674. define_mode(mode, jisdata, length, 0);
  1675. n_count = 0;
  1676. a_count = 0;
  1677. for (int i = 0; i < length; i++) {
  1678. if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { n_count++; }
  1679. if(in_alpha(jisdata[i])) { a_count++; }
  1680. }
  1681. if (a_count == length) {
  1682. /* All data can be encoded in Alphanumeric mode */
  1683. for (int i = 0; i < length; i++) {
  1684. mode[i] = 'A';
  1685. }
  1686. }
  1687. if (n_count == length) {
  1688. /* All data can be encoded in Numeric mode */
  1689. for (int i = 0; i < length; i++) {
  1690. mode[i] = 'N';
  1691. }
  1692. }
  1693. error_number = micr

Large files files are truncated, but you can click here to view the full file