qrspec.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /*
  2. * qrencode - QR Code encoder
  3. *
  4. * QR Code specification in convenient format.
  5. * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  6. *
  7. * The following data / specifications are taken from
  8. * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
  9. * or
  10. * "Automatic identification and data capture techniques --
  11. * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
  12. *
  13. * This library is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU Lesser General Public
  15. * License as published by the Free Software Foundation; either
  16. * version 2.1 of the License, or any later version.
  17. *
  18. * This library is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. * Lesser General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Lesser General Public
  24. * License along with this library; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  26. */
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <errno.h>
  31. //#include "config.h"
  32. #include "qrspec.h"
  33. /******************************************************************************
  34. * Version and capacity
  35. *****************************************************************************/
  36. typedef struct {
  37. int width; //< Edge length of the symbol
  38. int words; //< Data capacity (bytes)
  39. int remainder; //< Remainder bit (bits)
  40. int ec[4]; //< Number of ECC code (bytes)
  41. } QRspec_Capacity;
  42. /**
  43. * Table of the capacity of symbols
  44. * See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004.
  45. */
  46. static const QRspec_Capacity qrspecCapacity[QRSPEC_VERSION_MAX + 1] = {
  47. { 0, 0, 0, { 0, 0, 0, 0}},
  48. { 21, 26, 0, { 7, 10, 13, 17}}, // 1
  49. { 25, 44, 7, { 10, 16, 22, 28}},
  50. { 29, 70, 7, { 15, 26, 36, 44}},
  51. { 33, 100, 7, { 20, 36, 52, 64}},
  52. { 37, 134, 7, { 26, 48, 72, 88}}, // 5
  53. { 41, 172, 7, { 36, 64, 96, 112}},
  54. { 45, 196, 0, { 40, 72, 108, 130}},
  55. { 49, 242, 0, { 48, 88, 132, 156}},
  56. { 53, 292, 0, { 60, 110, 160, 192}},
  57. { 57, 346, 0, { 72, 130, 192, 224}}, //10
  58. { 61, 404, 0, { 80, 150, 224, 264}},
  59. { 65, 466, 0, { 96, 176, 260, 308}},
  60. { 69, 532, 0, { 104, 198, 288, 352}},
  61. { 73, 581, 3, { 120, 216, 320, 384}},
  62. { 77, 655, 3, { 132, 240, 360, 432}}, //15
  63. { 81, 733, 3, { 144, 280, 408, 480}},
  64. { 85, 815, 3, { 168, 308, 448, 532}},
  65. { 89, 901, 3, { 180, 338, 504, 588}},
  66. { 93, 991, 3, { 196, 364, 546, 650}},
  67. { 97, 1085, 3, { 224, 416, 600, 700}}, //20
  68. {101, 1156, 4, { 224, 442, 644, 750}},
  69. {105, 1258, 4, { 252, 476, 690, 816}},
  70. {109, 1364, 4, { 270, 504, 750, 900}},
  71. {113, 1474, 4, { 300, 560, 810, 960}},
  72. {117, 1588, 4, { 312, 588, 870, 1050}}, //25
  73. {121, 1706, 4, { 336, 644, 952, 1110}},
  74. {125, 1828, 4, { 360, 700, 1020, 1200}},
  75. {129, 1921, 3, { 390, 728, 1050, 1260}},
  76. {133, 2051, 3, { 420, 784, 1140, 1350}},
  77. {137, 2185, 3, { 450, 812, 1200, 1440}}, //30
  78. {141, 2323, 3, { 480, 868, 1290, 1530}},
  79. {145, 2465, 3, { 510, 924, 1350, 1620}},
  80. {149, 2611, 3, { 540, 980, 1440, 1710}},
  81. {153, 2761, 3, { 570, 1036, 1530, 1800}},
  82. {157, 2876, 0, { 570, 1064, 1590, 1890}}, //35
  83. {161, 3034, 0, { 600, 1120, 1680, 1980}},
  84. {165, 3196, 0, { 630, 1204, 1770, 2100}},
  85. {169, 3362, 0, { 660, 1260, 1860, 2220}},
  86. {173, 3532, 0, { 720, 1316, 1950, 2310}},
  87. {177, 3706, 0, { 750, 1372, 2040, 2430}} //40
  88. };
  89. int QRspec_getDataLength(int version, QRecLevel level)
  90. {
  91. return qrspecCapacity[version].words - qrspecCapacity[version].ec[level];
  92. }
  93. int QRspec_getECCLength(int version, QRecLevel level)
  94. {
  95. return qrspecCapacity[version].ec[level];
  96. }
  97. int QRspec_getMinimumVersion(int size, QRecLevel level)
  98. {
  99. int i;
  100. int words;
  101. for(i=1; i<= QRSPEC_VERSION_MAX; i++) {
  102. words = qrspecCapacity[i].words - qrspecCapacity[i].ec[level];
  103. if(words >= size) return i;
  104. }
  105. return -1;
  106. }
  107. int QRspec_getWidth(int version)
  108. {
  109. return qrspecCapacity[version].width;
  110. }
  111. int QRspec_getRemainder(int version)
  112. {
  113. return qrspecCapacity[version].remainder;
  114. }
  115. /******************************************************************************
  116. * Length indicator
  117. *****************************************************************************/
  118. static const int lengthTableBits[4][3] = {
  119. {10, 12, 14},
  120. { 9, 11, 13},
  121. { 8, 16, 16},
  122. { 8, 10, 12}
  123. };
  124. int QRspec_lengthIndicator(QRencodeMode mode, int version)
  125. {
  126. int l;
  127. if(mode == QR_MODE_STRUCTURE) return 0;
  128. if(version <= 9) {
  129. l = 0;
  130. } else if(version <= 26) {
  131. l = 1;
  132. } else {
  133. l = 2;
  134. }
  135. return lengthTableBits[mode][l];
  136. }
  137. int QRspec_maximumWords(QRencodeMode mode, int version)
  138. {
  139. int l;
  140. int bits;
  141. int words;
  142. if(mode == QR_MODE_STRUCTURE) return 3;
  143. if(version <= 9) {
  144. l = 0;
  145. } else if(version <= 26) {
  146. l = 1;
  147. } else {
  148. l = 2;
  149. }
  150. bits = lengthTableBits[mode][l];
  151. words = (1 << bits) - 1;
  152. if(mode == QR_MODE_KANJI) {
  153. words *= 2; // the number of bytes is required
  154. }
  155. return words;
  156. }
  157. /******************************************************************************
  158. * Error correction code
  159. *****************************************************************************/
  160. /**
  161. * Table of the error correction code (Reed-Solomon block)
  162. * See Table 12-16 (pp.30-36), JIS X0510:2004.
  163. */
  164. static const int eccTable[QRSPEC_VERSION_MAX+1][4][2] = {
  165. {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}},
  166. {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, // 1
  167. {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}},
  168. {{ 1, 0}, { 1, 0}, { 2, 0}, { 2, 0}},
  169. {{ 1, 0}, { 2, 0}, { 2, 0}, { 4, 0}},
  170. {{ 1, 0}, { 2, 0}, { 2, 2}, { 2, 2}}, // 5
  171. {{ 2, 0}, { 4, 0}, { 4, 0}, { 4, 0}},
  172. {{ 2, 0}, { 4, 0}, { 2, 4}, { 4, 1}},
  173. {{ 2, 0}, { 2, 2}, { 4, 2}, { 4, 2}},
  174. {{ 2, 0}, { 3, 2}, { 4, 4}, { 4, 4}},
  175. {{ 2, 2}, { 4, 1}, { 6, 2}, { 6, 2}}, //10
  176. {{ 4, 0}, { 1, 4}, { 4, 4}, { 3, 8}},
  177. {{ 2, 2}, { 6, 2}, { 4, 6}, { 7, 4}},
  178. {{ 4, 0}, { 8, 1}, { 8, 4}, {12, 4}},
  179. {{ 3, 1}, { 4, 5}, {11, 5}, {11, 5}},
  180. {{ 5, 1}, { 5, 5}, { 5, 7}, {11, 7}}, //15
  181. {{ 5, 1}, { 7, 3}, {15, 2}, { 3, 13}},
  182. {{ 1, 5}, {10, 1}, { 1, 15}, { 2, 17}},
  183. {{ 5, 1}, { 9, 4}, {17, 1}, { 2, 19}},
  184. {{ 3, 4}, { 3, 11}, {17, 4}, { 9, 16}},
  185. {{ 3, 5}, { 3, 13}, {15, 5}, {15, 10}}, //20
  186. {{ 4, 4}, {17, 0}, {17, 6}, {19, 6}},
  187. {{ 2, 7}, {17, 0}, { 7, 16}, {34, 0}},
  188. {{ 4, 5}, { 4, 14}, {11, 14}, {16, 14}},
  189. {{ 6, 4}, { 6, 14}, {11, 16}, {30, 2}},
  190. {{ 8, 4}, { 8, 13}, { 7, 22}, {22, 13}}, //25
  191. {{10, 2}, {19, 4}, {28, 6}, {33, 4}},
  192. {{ 8, 4}, {22, 3}, { 8, 26}, {12, 28}},
  193. {{ 3, 10}, { 3, 23}, { 4, 31}, {11, 31}},
  194. {{ 7, 7}, {21, 7}, { 1, 37}, {19, 26}},
  195. {{ 5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30
  196. {{13, 3}, { 2, 29}, {42, 1}, {23, 28}},
  197. {{17, 0}, {10, 23}, {10, 35}, {19, 35}},
  198. {{17, 1}, {14, 21}, {29, 19}, {11, 46}},
  199. {{13, 6}, {14, 23}, {44, 7}, {59, 1}},
  200. {{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35
  201. {{ 6, 14}, { 6, 34}, {46, 10}, { 2, 64}},
  202. {{17, 4}, {29, 14}, {49, 10}, {24, 46}},
  203. {{ 4, 18}, {13, 32}, {48, 14}, {42, 32}},
  204. {{20, 4}, {40, 7}, {43, 22}, {10, 67}},
  205. {{19, 6}, {18, 31}, {34, 34}, {20, 61}},//40
  206. };
  207. void QRspec_getEccSpec(int version, QRecLevel level, int spec[5])
  208. {
  209. int b1, b2;
  210. int data, ecc;
  211. b1 = eccTable[version][level][0];
  212. b2 = eccTable[version][level][1];
  213. data = QRspec_getDataLength(version, level);
  214. ecc = QRspec_getECCLength(version, level);
  215. if(b2 == 0) {
  216. spec[0] = b1;
  217. spec[1] = data / b1;
  218. spec[2] = ecc / b1;
  219. spec[3] = spec[4] = 0;
  220. } else {
  221. spec[0] = b1;
  222. spec[1] = data / (b1 + b2);
  223. spec[2] = ecc / (b1 + b2);
  224. spec[3] = b2;
  225. spec[4] = spec[1] + 1;
  226. }
  227. }
  228. /******************************************************************************
  229. * Alignment pattern
  230. *****************************************************************************/
  231. /**
  232. * Positions of alignment patterns.
  233. * This array includes only the second and the third position of the alignment
  234. * patterns. Rest of them can be calculated from the distance between them.
  235. *
  236. * See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
  237. */
  238. static const int alignmentPattern[QRSPEC_VERSION_MAX+1][2] = {
  239. { 0, 0},
  240. { 0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5
  241. {34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10
  242. {30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15
  243. {26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20
  244. {28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25
  245. {30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30
  246. {30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35
  247. {24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40
  248. };
  249. /**
  250. * Put an alignment marker.
  251. * @param frame
  252. * @param width
  253. * @param ox,oy center coordinate of the pattern
  254. */
  255. static void QRspec_putAlignmentMarker(unsigned char *frame, int width, int ox, int oy)
  256. {
  257. static const unsigned char finder[] = {
  258. 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
  259. 0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
  260. 0xa1, 0xa0, 0xa1, 0xa0, 0xa1,
  261. 0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
  262. 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
  263. };
  264. int x, y;
  265. const unsigned char *s;
  266. frame += (oy - 2) * width + ox - 2;
  267. s = finder;
  268. for(y=0; y<5; y++) {
  269. for(x=0; x<5; x++) {
  270. frame[x] = s[x];
  271. }
  272. frame += width;
  273. s += 5;
  274. }
  275. }
  276. //__STATIC
  277. static void QRspec_putAlignmentPattern(int version, unsigned char *frame, int width)
  278. {
  279. int d, w, x, y, cx, cy;
  280. if(version < 2) return;
  281. d = alignmentPattern[version][1] - alignmentPattern[version][0];
  282. if(d < 0) {
  283. w = 2;
  284. } else {
  285. w = (width - alignmentPattern[version][0]) / d + 2;
  286. }
  287. if(w * w - 3 == 1) {
  288. x = alignmentPattern[version][0];
  289. y = alignmentPattern[version][0];
  290. QRspec_putAlignmentMarker(frame, width, x, y);
  291. return;
  292. }
  293. cx = alignmentPattern[version][0];
  294. for(x=1; x<w - 1; x++) {
  295. QRspec_putAlignmentMarker(frame, width, 6, cx);
  296. QRspec_putAlignmentMarker(frame, width, cx, 6);
  297. cx += d;
  298. }
  299. cy = alignmentPattern[version][0];
  300. for(y=0; y<w-1; y++) {
  301. cx = alignmentPattern[version][0];
  302. for(x=0; x<w-1; x++) {
  303. QRspec_putAlignmentMarker(frame, width, cx, cy);
  304. cx += d;
  305. }
  306. cy += d;
  307. }
  308. }
  309. /******************************************************************************
  310. * Version information pattern
  311. *****************************************************************************/
  312. /**
  313. * Version information pattern (BCH coded).
  314. * See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
  315. */
  316. static const unsigned int versionPattern[QRSPEC_VERSION_MAX - 6] = {
  317. 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
  318. 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
  319. 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
  320. 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
  321. 0x27541, 0x28c69
  322. };
  323. unsigned int QRspec_getVersionPattern(int version)
  324. {
  325. if(version < 7 || version > QRSPEC_VERSION_MAX) return 0;
  326. return versionPattern[version -7];
  327. }
  328. /******************************************************************************
  329. * Format information
  330. *****************************************************************************/
  331. /* See calcFormatInfo in tests/test_qrspec.c */
  332. static const unsigned int formatInfo[4][8] = {
  333. {0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976},
  334. {0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0},
  335. {0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed},
  336. {0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b}
  337. };
  338. unsigned int QRspec_getFormatInfo(int mask, QRecLevel level)
  339. {
  340. if(mask < 0 || mask > 7) return 0;
  341. return formatInfo[level][mask];
  342. }
  343. /******************************************************************************
  344. * Frame
  345. *****************************************************************************/
  346. /**
  347. * Cache of initial frames.
  348. */
  349. /* C99 says that static storage shall be initialized to a null pointer
  350. * by compiler. */
  351. static unsigned char *frames[QRSPEC_VERSION_MAX + 1];
  352. /**
  353. * Put a finder pattern.
  354. * @param frame
  355. * @param width
  356. * @param ox,oy upper-left coordinate of the pattern
  357. */
  358. static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
  359. {
  360. static const unsigned char finder[] = {
  361. 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
  362. 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
  363. 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
  364. 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
  365. 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
  366. 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
  367. 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
  368. };
  369. int x, y;
  370. const unsigned char *s;
  371. frame += oy * width + ox;
  372. s = finder;
  373. for(y=0; y<7; y++) {
  374. for(x=0; x<7; x++) {
  375. frame[x] = s[x];
  376. }
  377. frame += width;
  378. s += 7;
  379. }
  380. }
  381. static unsigned char *QRspec_createFrame(int version)
  382. {
  383. unsigned char *frame, *p, *q;
  384. int width;
  385. int x, y;
  386. unsigned int verinfo, v;
  387. width = qrspecCapacity[version].width;
  388. frame = (unsigned char *)malloc(width * width);
  389. if(frame == NULL) return NULL;
  390. memset(frame, 0, width * width);
  391. /* Finder pattern */
  392. putFinderPattern(frame, width, 0, 0);
  393. putFinderPattern(frame, width, width - 7, 0);
  394. putFinderPattern(frame, width, 0, width - 7);
  395. /* Separator */
  396. p = frame;
  397. q = frame + width * (width - 7);
  398. for(y=0; y<7; y++) {
  399. p[7] = 0xc0;
  400. p[width - 8] = 0xc0;
  401. q[7] = 0xc0;
  402. p += width;
  403. q += width;
  404. }
  405. memset(frame + width * 7, 0xc0, 8);
  406. memset(frame + width * 8 - 8, 0xc0, 8);
  407. memset(frame + width * (width - 8), 0xc0, 8);
  408. /* Mask format information area */
  409. memset(frame + width * 8, 0x84, 9);
  410. memset(frame + width * 9 - 8, 0x84, 8);
  411. p = frame + 8;
  412. for(y=0; y<8; y++) {
  413. *p = 0x84;
  414. p += width;
  415. }
  416. p = frame + width * (width - 7) + 8;
  417. for(y=0; y<7; y++) {
  418. *p = 0x84;
  419. p += width;
  420. }
  421. /* Timing pattern */
  422. p = frame + width * 6 + 8;
  423. q = frame + width * 8 + 6;
  424. for(x=1; x<width-15; x++) {
  425. *p = 0x90 | (x & 1);
  426. *q = 0x90 | (x & 1);
  427. p++;
  428. q += width;
  429. }
  430. /* Alignment pattern */
  431. QRspec_putAlignmentPattern(version, frame, width);
  432. /* Version information */
  433. if(version >= 7) {
  434. verinfo = QRspec_getVersionPattern(version);
  435. p = frame + width * (width - 11);
  436. v = verinfo;
  437. for(x=0; x<6; x++) {
  438. for(y=0; y<3; y++) {
  439. p[width * y + x] = 0x88 | (v & 1);
  440. v = v >> 1;
  441. }
  442. }
  443. p = frame + width - 11;
  444. v = verinfo;
  445. for(y=0; y<6; y++) {
  446. for(x=0; x<3; x++) {
  447. p[x] = 0x88 | (v & 1);
  448. v = v >> 1;
  449. }
  450. p += width;
  451. }
  452. }
  453. /* and a little bit... */
  454. frame[width * (width - 8) + 8] = 0x81;
  455. return frame;
  456. }
  457. unsigned char *QRspec_newFrame(int version)
  458. {
  459. unsigned char *frame;
  460. int width;
  461. if(version < 1 || version > QRSPEC_VERSION_MAX) return NULL;
  462. if(frames[version] == NULL) {
  463. frames[version] = QRspec_createFrame(version);
  464. }
  465. if(frames[version] == NULL) return NULL;
  466. width = qrspecCapacity[version].width;
  467. frame = (unsigned char *)malloc(width * width);
  468. if(frame == NULL) return NULL;
  469. memcpy(frame, frames[version], width * width);
  470. return frame;
  471. }
  472. void QRspec_clearCache(void)
  473. {
  474. int i;
  475. for(i=1; i<=QRSPEC_VERSION_MAX; i++) {
  476. free(frames[i]);
  477. }
  478. }