qrcode.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. var QR = (function () {
  2. // alignment pattern
  3. var adelta = [
  4. 0,
  5. 11,
  6. 15,
  7. 19,
  8. 23,
  9. 27,
  10. 31, // force 1 pat
  11. 16,
  12. 18,
  13. 20,
  14. 22,
  15. 24,
  16. 26,
  17. 28,
  18. 20,
  19. 22,
  20. 24,
  21. 24,
  22. 26,
  23. 28,
  24. 28,
  25. 22,
  26. 24,
  27. 24,
  28. 26,
  29. 26,
  30. 28,
  31. 28,
  32. 24,
  33. 24,
  34. 26,
  35. 26,
  36. 26,
  37. 28,
  38. 28,
  39. 24,
  40. 26,
  41. 26,
  42. 26,
  43. 28,
  44. 28
  45. ]
  46. // version block
  47. var vpat = [
  48. 0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d, 0x928, 0xb78, 0x45d,
  49. 0xa17, 0x532, 0x9a6, 0x683, 0x8c9, 0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a,
  50. 0x33f, 0xd75, 0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64, 0x541,
  51. 0xc69
  52. ]
  53. // final format bits with mask: level << 3 | mask
  54. var fmtword = [
  55. 0x77c4,
  56. 0x72f3,
  57. 0x7daa,
  58. 0x789d,
  59. 0x662f,
  60. 0x6318,
  61. 0x6c41,
  62. 0x6976, //L
  63. 0x5412,
  64. 0x5125,
  65. 0x5e7c,
  66. 0x5b4b,
  67. 0x45f9,
  68. 0x40ce,
  69. 0x4f97,
  70. 0x4aa0, //M
  71. 0x355f,
  72. 0x3068,
  73. 0x3f31,
  74. 0x3a06,
  75. 0x24b4,
  76. 0x2183,
  77. 0x2eda,
  78. 0x2bed, //Q
  79. 0x1689,
  80. 0x13be,
  81. 0x1ce7,
  82. 0x19d0,
  83. 0x0762,
  84. 0x0255,
  85. 0x0d0c,
  86. 0x083b //H
  87. ]
  88. // 4 per version: number of blocks 1,2; data width; ecc width
  89. var eccblocks = [
  90. 1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17, 1, 0, 34, 10, 1, 0,
  91. 28, 16, 1, 0, 22, 22, 1, 0, 16, 28, 1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17,
  92. 18, 2, 0, 13, 22, 1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16, 1,
  93. 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22, 2, 0, 68, 18, 4, 0,
  94. 27, 16, 4, 0, 19, 24, 4, 0, 15, 28, 2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14,
  95. 18, 4, 1, 13, 26, 2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26, 2,
  96. 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24, 2, 2, 68, 18, 4, 1,
  97. 43, 26, 6, 2, 19, 24, 6, 2, 15, 28, 4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22,
  98. 28, 3, 8, 12, 24, 2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28, 4,
  99. 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22, 3, 1, 115, 30, 4, 5,
  100. 40, 24, 11, 5, 16, 20, 11, 5, 12, 24, 5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24,
  101. 30, 11, 7, 12, 24, 5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
  102. 1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28, 5, 1, 120, 30,
  103. 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28, 3, 4, 113, 28, 3, 11, 44, 26,
  104. 17, 4, 21, 26, 9, 16, 13, 26, 3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30,
  105. 15, 10, 15, 28, 4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
  106. 2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24, 4, 5, 121, 30,
  107. 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30, 6, 4, 117, 30, 6, 14, 45, 28,
  108. 11, 16, 24, 30, 30, 2, 16, 30, 8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30,
  109. 22, 13, 15, 30, 10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
  110. 8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30, 3, 10, 117, 30,
  111. 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30, 7, 7, 116, 30, 21, 7, 45, 28,
  112. 1, 37, 23, 30, 19, 26, 15, 30, 5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24,
  113. 30, 23, 25, 15, 30, 13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28,
  114. 15, 30, 17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30, 17,
  115. 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30, 13, 6, 115, 30,
  116. 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30, 12, 7, 121, 30, 12, 26, 47,
  117. 28, 39, 14, 24, 30, 22, 41, 15, 30, 6, 14, 121, 30, 6, 34, 47, 28, 46, 10,
  118. 24, 30, 2, 64, 15, 30, 17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24,
  119. 46, 15, 30, 4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
  120. 20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30, 19, 6, 118,
  121. 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30
  122. ]
  123. // Galois field log table
  124. var glog = [
  125. 0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee,
  126. 0x1b, 0x68, 0xc7, 0x4b, 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
  127. 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, 0x05, 0x8a, 0x65, 0x2f,
  128. 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
  129. 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78,
  130. 0x4d, 0xe4, 0x72, 0xa6, 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
  131. 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, 0x36, 0xd0, 0x94, 0xce,
  132. 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
  133. 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54,
  134. 0xfa, 0x85, 0xba, 0x3d, 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
  135. 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, 0x07, 0x70, 0xc0, 0xf7,
  136. 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
  137. 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9,
  138. 0x23, 0x20, 0x89, 0x2e, 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
  139. 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, 0xf2, 0x56, 0xd3, 0xab,
  140. 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
  141. 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec,
  142. 0x7f, 0x0c, 0x6f, 0xf6, 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
  143. 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a, 0xcb, 0x59, 0x5f, 0xb0,
  144. 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
  145. 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea,
  146. 0xa8, 0x50, 0x58, 0xaf
  147. ]
  148. // Galios field exponent table
  149. var gexp = [
  150. 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8,
  151. 0xcd, 0x87, 0x13, 0x26, 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
  152. 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x9d, 0x27, 0x4e, 0x9c,
  153. 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
  154. 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2,
  155. 0xb9, 0x6f, 0xde, 0xa1, 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
  156. 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0xfd, 0xe7, 0xd3, 0xbb,
  157. 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
  158. 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68,
  159. 0xd0, 0xbd, 0x67, 0xce, 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
  160. 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85, 0x17, 0x2e, 0x5c,
  161. 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
  162. 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72,
  163. 0xe4, 0xd5, 0xb7, 0x73, 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
  164. 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3, 0xdb, 0xab, 0x4b,
  165. 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
  166. 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0,
  167. 0xdd, 0xa7, 0x53, 0xa6, 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
  168. 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, 0x12, 0x24, 0x48, 0x90,
  169. 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
  170. 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8,
  171. 0xad, 0x47, 0x8e, 0x00
  172. ]
  173. // Working buffers:
  174. // data input and ecc append, image working buffer, fixed part of image, run lengths for badness
  175. var strinbuf = [],
  176. eccbuf = [],
  177. qrframe = [],
  178. framask = [],
  179. rlens = []
  180. // Control values - width is based on version, last 4 are from table.
  181. var version, width, neccblk1, neccblk2, datablkw, eccblkwid
  182. var ecclevel = 2
  183. // set bit to indicate cell in qrframe is immutable. symmetric around diagonal
  184. function setmask(x, y) {
  185. var bt
  186. if (x > y) {
  187. bt = x
  188. x = y
  189. y = bt
  190. }
  191. // y*y = 1+3+5...
  192. bt = y
  193. bt *= y
  194. bt += y
  195. bt >>= 1
  196. bt += x
  197. framask[bt] = 1
  198. }
  199. // enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask)
  200. function putalign(x, y) {
  201. var j
  202. qrframe[x + width * y] = 1
  203. for (j = -2; j < 2; j++) {
  204. qrframe[x + j + width * (y - 2)] = 1
  205. qrframe[x - 2 + width * (y + j + 1)] = 1
  206. qrframe[x + 2 + width * (y + j)] = 1
  207. qrframe[x + j + 1 + width * (y + 2)] = 1
  208. }
  209. for (j = 0; j < 2; j++) {
  210. setmask(x - 1, y + j)
  211. setmask(x + 1, y - j)
  212. setmask(x - j, y - 1)
  213. setmask(x + j, y + 1)
  214. }
  215. }
  216. //========================================================================
  217. // Reed Solomon error correction
  218. // exponentiation mod N
  219. function modnn(x) {
  220. while (x >= 255) {
  221. x -= 255
  222. x = (x >> 8) + (x & 255)
  223. }
  224. return x
  225. }
  226. var genpoly = []
  227. // Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given.
  228. function appendrs(data, dlen, ecbuf, eclen) {
  229. var i, j, fb
  230. for (i = 0; i < eclen; i++) strinbuf[ecbuf + i] = 0
  231. for (i = 0; i < dlen; i++) {
  232. fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]]
  233. if (fb != 255)
  234. /* fb term is non-zero */
  235. for (j = 1; j < eclen; j++)
  236. strinbuf[ecbuf + j - 1] =
  237. strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])]
  238. else for (j = ecbuf; j < ecbuf + eclen; j++) strinbuf[j] = strinbuf[j + 1]
  239. strinbuf[ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])]
  240. }
  241. }
  242. //========================================================================
  243. // Frame data insert following the path rules
  244. // check mask - since symmetrical use half.
  245. function ismasked(x, y) {
  246. var bt
  247. if (x > y) {
  248. bt = x
  249. x = y
  250. y = bt
  251. }
  252. bt = y
  253. bt += y * y
  254. bt >>= 1
  255. bt += x
  256. return framask[bt]
  257. }
  258. //========================================================================
  259. // Apply the selected mask out of the 8.
  260. function applymask(m) {
  261. var x, y, r3x, r3y
  262. switch (m) {
  263. case 0:
  264. for (y = 0; y < width; y++)
  265. for (x = 0; x < width; x++)
  266. if (!((x + y) & 1) && !ismasked(x, y)) qrframe[x + y * width] ^= 1
  267. break
  268. case 1:
  269. for (y = 0; y < width; y++)
  270. for (x = 0; x < width; x++)
  271. if (!(y & 1) && !ismasked(x, y)) qrframe[x + y * width] ^= 1
  272. break
  273. case 2:
  274. for (y = 0; y < width; y++)
  275. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  276. if (r3x == 3) r3x = 0
  277. if (!r3x && !ismasked(x, y)) qrframe[x + y * width] ^= 1
  278. }
  279. break
  280. case 3:
  281. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  282. if (r3y == 3) r3y = 0
  283. for (r3x = r3y, x = 0; x < width; x++, r3x++) {
  284. if (r3x == 3) r3x = 0
  285. if (!r3x && !ismasked(x, y)) qrframe[x + y * width] ^= 1
  286. }
  287. }
  288. break
  289. case 4:
  290. for (y = 0; y < width; y++)
  291. for (r3x = 0, r3y = (y >> 1) & 1, x = 0; x < width; x++, r3x++) {
  292. if (r3x == 3) {
  293. r3x = 0
  294. r3y = !r3y
  295. }
  296. if (!r3y && !ismasked(x, y)) qrframe[x + y * width] ^= 1
  297. }
  298. break
  299. case 5:
  300. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  301. if (r3y == 3) r3y = 0
  302. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  303. if (r3x == 3) r3x = 0
  304. if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y))
  305. qrframe[x + y * width] ^= 1
  306. }
  307. }
  308. break
  309. case 6:
  310. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  311. if (r3y == 3) r3y = 0
  312. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  313. if (r3x == 3) r3x = 0
  314. if (!(((x & y & 1) + (r3x && r3x == r3y)) & 1) && !ismasked(x, y))
  315. qrframe[x + y * width] ^= 1
  316. }
  317. }
  318. break
  319. case 7:
  320. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  321. if (r3y == 3) r3y = 0
  322. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  323. if (r3x == 3) r3x = 0
  324. if (!(((r3x && r3x == r3y) + ((x + y) & 1)) & 1) && !ismasked(x, y))
  325. qrframe[x + y * width] ^= 1
  326. }
  327. }
  328. break
  329. }
  330. return
  331. }
  332. // Badness coefficients.
  333. var N1 = 3,
  334. N2 = 3,
  335. N3 = 40,
  336. N4 = 10
  337. // Using the table of the length of each run, calculate the amount of bad image
  338. // - long runs or those that look like finders; called twice, once each for X and Y
  339. function badruns(length) {
  340. var i
  341. var runsbad = 0
  342. for (i = 0; i <= length; i++)
  343. if (rlens[i] >= 5) runsbad += N1 + rlens[i] - 5
  344. // BwBBBwB as in finder
  345. for (i = 3; i < length - 1; i += 2)
  346. if (
  347. rlens[i - 2] == rlens[i + 2] &&
  348. rlens[i + 2] == rlens[i - 1] &&
  349. rlens[i - 1] == rlens[i + 1] &&
  350. rlens[i - 1] * 3 == rlens[i] &&
  351. // white around the black pattern? Not part of spec
  352. (rlens[i - 3] == 0 || // beginning
  353. i + 3 > length || // end
  354. rlens[i - 3] * 3 >= rlens[i] * 4 ||
  355. rlens[i + 3] * 3 >= rlens[i] * 4)
  356. )
  357. runsbad += N3
  358. return runsbad
  359. }
  360. // Calculate how bad the masked image is - blocks, imbalance, runs, or finders.
  361. function badcheck() {
  362. var x, y, h, b, b1
  363. var thisbad = 0
  364. var bw = 0
  365. // blocks of same color.
  366. for (y = 0; y < width - 1; y++)
  367. for (x = 0; x < width - 1; x++)
  368. if (
  369. (qrframe[x + width * y] &&
  370. qrframe[x + 1 + width * y] &&
  371. qrframe[x + width * (y + 1)] &&
  372. qrframe[x + 1 + width * (y + 1)]) || // all black
  373. !(
  374. qrframe[x + width * y] ||
  375. qrframe[x + 1 + width * y] ||
  376. qrframe[x + width * (y + 1)] ||
  377. qrframe[x + 1 + width * (y + 1)]
  378. )
  379. )
  380. // all white
  381. thisbad += N2
  382. // X runs
  383. for (y = 0; y < width; y++) {
  384. rlens[0] = 0
  385. for (h = b = x = 0; x < width; x++) {
  386. if ((b1 = qrframe[x + width * y]) == b) rlens[h]++
  387. else rlens[++h] = 1
  388. b = b1
  389. bw += b ? 1 : -1
  390. }
  391. thisbad += badruns(h)
  392. }
  393. // black/white imbalance
  394. if (bw < 0) bw = -bw
  395. var big = bw
  396. var count = 0
  397. big += big << 2
  398. big <<= 1
  399. while (big > width * width) (big -= width * width), count++
  400. thisbad += count * N4
  401. // Y runs
  402. for (x = 0; x < width; x++) {
  403. rlens[0] = 0
  404. for (h = b = y = 0; y < width; y++) {
  405. if ((b1 = qrframe[x + width * y]) == b) rlens[h]++
  406. else rlens[++h] = 1
  407. b = b1
  408. }
  409. thisbad += badruns(h)
  410. }
  411. return thisbad
  412. }
  413. function genframe(instring) {
  414. var x, y, k, t, v, i, j, m
  415. // find the smallest version that fits the string
  416. t = instring.length
  417. version = 0
  418. do {
  419. version++
  420. k = (ecclevel - 1) * 4 + (version - 1) * 16
  421. neccblk1 = eccblocks[k++]
  422. neccblk2 = eccblocks[k++]
  423. datablkw = eccblocks[k++]
  424. eccblkwid = eccblocks[k]
  425. k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9)
  426. if (t <= k) break
  427. } while (version < 40)
  428. // FIXME - insure that it fits insted of being truncated
  429. width = 17 + 4 * version
  430. // allocate, clear and setup data structures
  431. v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2
  432. for (t = 0; t < v; t++) eccbuf[t] = 0
  433. strinbuf = instring.slice(0)
  434. for (t = 0; t < width * width; t++) qrframe[t] = 0
  435. for (t = 0; t < (width * (width + 1) + 1) / 2; t++) framask[t] = 0
  436. // insert finders - black to frame, white to mask
  437. for (t = 0; t < 3; t++) {
  438. k = 0
  439. y = 0
  440. if (t == 1) k = width - 7
  441. if (t == 2) y = width - 7
  442. qrframe[y + 3 + width * (k + 3)] = 1
  443. for (x = 0; x < 6; x++) {
  444. qrframe[y + x + width * k] = 1
  445. qrframe[y + width * (k + x + 1)] = 1
  446. qrframe[y + 6 + width * (k + x)] = 1
  447. qrframe[y + x + 1 + width * (k + 6)] = 1
  448. }
  449. for (x = 1; x < 5; x++) {
  450. setmask(y + x, k + 1)
  451. setmask(y + 1, k + x + 1)
  452. setmask(y + 5, k + x)
  453. setmask(y + x + 1, k + 5)
  454. }
  455. for (x = 2; x < 4; x++) {
  456. qrframe[y + x + width * (k + 2)] = 1
  457. qrframe[y + 2 + width * (k + x + 1)] = 1
  458. qrframe[y + 4 + width * (k + x)] = 1
  459. qrframe[y + x + 1 + width * (k + 4)] = 1
  460. }
  461. }
  462. // alignment blocks
  463. if (version > 1) {
  464. t = adelta[version]
  465. y = width - 7
  466. for (;;) {
  467. x = width - 7
  468. while (x > t - 3) {
  469. putalign(x, y)
  470. if (x < t) break
  471. x -= t
  472. }
  473. if (y <= t + 9) break
  474. y -= t
  475. putalign(6, y)
  476. putalign(y, 6)
  477. }
  478. }
  479. // single black
  480. qrframe[8 + width * (width - 8)] = 1
  481. // timing gap - mask only
  482. for (y = 0; y < 7; y++) {
  483. setmask(7, y)
  484. setmask(width - 8, y)
  485. setmask(7, y + width - 7)
  486. }
  487. for (x = 0; x < 8; x++) {
  488. setmask(x, 7)
  489. setmask(x + width - 8, 7)
  490. setmask(x, width - 8)
  491. }
  492. // reserve mask-format area
  493. for (x = 0; x < 9; x++) setmask(x, 8)
  494. for (x = 0; x < 8; x++) {
  495. setmask(x + width - 8, 8)
  496. setmask(8, x)
  497. }
  498. for (y = 0; y < 7; y++) setmask(8, y + width - 7)
  499. // timing row/col
  500. for (x = 0; x < width - 14; x++)
  501. if (x & 1) {
  502. setmask(8 + x, 6)
  503. setmask(6, 8 + x)
  504. } else {
  505. qrframe[8 + x + width * 6] = 1
  506. qrframe[6 + width * (8 + x)] = 1
  507. }
  508. // version block
  509. if (version > 6) {
  510. t = vpat[version - 7]
  511. k = 17
  512. for (x = 0; x < 6; x++)
  513. for (y = 0; y < 3; y++, k--)
  514. if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
  515. qrframe[5 - x + width * (2 - y + width - 11)] = 1
  516. qrframe[2 - y + width - 11 + width * (5 - x)] = 1
  517. } else {
  518. setmask(5 - x, 2 - y + width - 11)
  519. setmask(2 - y + width - 11, 5 - x)
  520. }
  521. }
  522. // sync mask bits - only set above for white spaces, so add in black bits
  523. for (y = 0; y < width; y++)
  524. for (x = 0; x <= y; x++) if (qrframe[x + width * y]) setmask(x, y)
  525. // convert string to bitstream
  526. // 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported)
  527. v = strinbuf.length
  528. // string to array
  529. for (i = 0; i < v; i++) eccbuf[i] = strinbuf.charCodeAt(i)
  530. strinbuf = eccbuf.slice(0)
  531. // calculate max string length
  532. x = datablkw * (neccblk1 + neccblk2) + neccblk2
  533. if (v >= x - 2) {
  534. v = x - 2
  535. if (version > 9) v--
  536. }
  537. // shift and repack to insert length prefix
  538. i = v
  539. if (version > 9) {
  540. strinbuf[i + 2] = 0
  541. strinbuf[i + 3] = 0
  542. while (i--) {
  543. t = strinbuf[i]
  544. strinbuf[i + 3] |= 255 & (t << 4)
  545. strinbuf[i + 2] = t >> 4
  546. }
  547. strinbuf[2] |= 255 & (v << 4)
  548. strinbuf[1] = v >> 4
  549. strinbuf[0] = 0x40 | (v >> 12)
  550. } else {
  551. strinbuf[i + 1] = 0
  552. strinbuf[i + 2] = 0
  553. while (i--) {
  554. t = strinbuf[i]
  555. strinbuf[i + 2] |= 255 & (t << 4)
  556. strinbuf[i + 1] = t >> 4
  557. }
  558. strinbuf[1] |= 255 & (v << 4)
  559. strinbuf[0] = 0x40 | (v >> 4)
  560. }
  561. // fill to end with pad pattern
  562. i = v + 3 - (version < 10)
  563. while (i < x) {
  564. strinbuf[i++] = 0xec
  565. // buffer has room if (i == x) break;
  566. strinbuf[i++] = 0x11
  567. }
  568. // calculate and append ECC
  569. // calculate generator polynomial
  570. genpoly[0] = 1
  571. for (i = 0; i < eccblkwid; i++) {
  572. genpoly[i + 1] = 1
  573. for (j = i; j > 0; j--)
  574. genpoly[j] = genpoly[j]
  575. ? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)]
  576. : genpoly[j - 1]
  577. genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)]
  578. }
  579. for (i = 0; i <= eccblkwid; i++) genpoly[i] = glog[genpoly[i]] // use logs for genpoly[] to save calc step
  580. // append ecc to data buffer
  581. k = x
  582. y = 0
  583. for (i = 0; i < neccblk1; i++) {
  584. appendrs(y, datablkw, k, eccblkwid)
  585. y += datablkw
  586. k += eccblkwid
  587. }
  588. for (i = 0; i < neccblk2; i++) {
  589. appendrs(y, datablkw + 1, k, eccblkwid)
  590. y += datablkw + 1
  591. k += eccblkwid
  592. }
  593. // interleave blocks
  594. y = 0
  595. for (i = 0; i < datablkw; i++) {
  596. for (j = 0; j < neccblk1; j++) eccbuf[y++] = strinbuf[i + j * datablkw]
  597. for (j = 0; j < neccblk2; j++)
  598. eccbuf[y++] = strinbuf[neccblk1 * datablkw + i + j * (datablkw + 1)]
  599. }
  600. for (j = 0; j < neccblk2; j++)
  601. eccbuf[y++] = strinbuf[neccblk1 * datablkw + i + j * (datablkw + 1)]
  602. for (i = 0; i < eccblkwid; i++)
  603. for (j = 0; j < neccblk1 + neccblk2; j++)
  604. eccbuf[y++] = strinbuf[x + i + j * eccblkwid]
  605. strinbuf = eccbuf
  606. // pack bits into frame avoiding masked area.
  607. x = y = width - 1
  608. k = v = 1 // up, minus
  609. /* inteleaved data and ecc codes */
  610. m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2
  611. for (i = 0; i < m; i++) {
  612. t = strinbuf[i]
  613. for (j = 0; j < 8; j++, t <<= 1) {
  614. if (0x80 & t) qrframe[x + width * y] = 1
  615. do {
  616. // find next fill position
  617. if (v) x--
  618. else {
  619. x++
  620. if (k) {
  621. if (y != 0) y--
  622. else {
  623. x -= 2
  624. k = !k
  625. if (x == 6) {
  626. x--
  627. y = 9
  628. }
  629. }
  630. } else {
  631. if (y != width - 1) y++
  632. else {
  633. x -= 2
  634. k = !k
  635. if (x == 6) {
  636. x--
  637. y -= 8
  638. }
  639. }
  640. }
  641. }
  642. v = !v
  643. } while (ismasked(x, y))
  644. }
  645. }
  646. // save pre-mask copy of frame
  647. strinbuf = qrframe.slice(0)
  648. t = 0 // best
  649. y = 30000 // demerit
  650. // for instead of while since in original arduino code
  651. // if an early mask was "good enough" it wouldn't try for a better one
  652. // since they get more complex and take longer.
  653. for (k = 0; k < 8; k++) {
  654. applymask(k) // returns black-white imbalance
  655. x = badcheck()
  656. if (x < y) {
  657. // current mask better than previous best?
  658. y = x
  659. t = k
  660. }
  661. if (t == 7) break // don't increment i to a void redoing mask
  662. qrframe = strinbuf.slice(0) // reset for next pass
  663. }
  664. if (t != k)
  665. // redo best mask - none good enough, last wasn't t
  666. applymask(t)
  667. // add in final mask/ecclevel bytes
  668. y = fmtword[t + ((ecclevel - 1) << 3)]
  669. // low byte
  670. for (k = 0; k < 8; k++, y >>= 1)
  671. if (y & 1) {
  672. qrframe[width - 1 - k + width * 8] = 1
  673. if (k < 6) qrframe[8 + width * k] = 1
  674. else qrframe[8 + width * (k + 1)] = 1
  675. }
  676. // high byte
  677. for (k = 0; k < 7; k++, y >>= 1)
  678. if (y & 1) {
  679. qrframe[8 + width * (width - 7 + k)] = 1
  680. if (k) qrframe[6 - k + width * 8] = 1
  681. else qrframe[7 + width * 8] = 1
  682. }
  683. // return image
  684. return qrframe
  685. }
  686. var _canvas = null,
  687. _size = null
  688. var api = {
  689. get ecclevel() {
  690. return ecclevel
  691. },
  692. set ecclevel(val) {
  693. ecclevel = val
  694. },
  695. get size() {
  696. return _size
  697. },
  698. set size(val) {
  699. _size = val
  700. },
  701. get canvas() {
  702. return _canvas
  703. },
  704. set canvas(el) {
  705. _canvas = el
  706. },
  707. getFrame: function (string) {
  708. return genframe(string)
  709. },
  710. draw: function (string, canvas, size, ecc) {
  711. ecclevel = ecc || ecclevel
  712. canvas = canvas || _canvas
  713. if (!canvas) {
  714. console.warn('No canvas provided to draw QR code in!')
  715. return
  716. }
  717. size = size || _size || Math.min(canvas.width, canvas.height)
  718. var frame = genframe(string),
  719. ctx = canvas.ctx,
  720. px = Math.round(size / (width + 8))
  721. var roundedSize = px * (width + 8),
  722. offset = Math.floor((size - roundedSize) / 2)
  723. size = roundedSize
  724. ctx.clearRect(0, 0, canvas.width, canvas.height)
  725. ctx.setFillStyle('#000000')
  726. for (var i = 0; i < width; i++) {
  727. for (var j = 0; j < width; j++) {
  728. if (frame[j * width + i]) {
  729. ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px)
  730. }
  731. }
  732. }
  733. ctx.draw()
  734. }
  735. }
  736. module.exports = {
  737. api: api
  738. }
  739. })()