qr-1.1.3.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. // [qr.js](http://neocotic.com/qr.js)
  2. // (c) 2014 Alasdair Mercer
  3. // Licensed under the GPL Version 3 license.
  4. // Based on [jsqrencode](http://code.google.com/p/jsqrencode/)
  5. // (c) 2010 tz@execpc.com
  6. // Licensed under the GPL Version 3 license.
  7. // For all details and documentation:
  8. // <http://neocotic.com/qr.js>
  9. (function (root) {
  10. 'use strict';
  11. // Private constants
  12. // -----------------
  13. // Alignment pattern.
  14. var ALIGNMENT_DELTA = [
  15. 0, 11, 15, 19, 23, 27, 31,
  16. 16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
  17. 26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28
  18. ];
  19. // Default MIME type.
  20. var DEFAULT_MIME = 'image/png';
  21. // MIME used to initiate a browser download prompt when `qr.save` is called.
  22. var DOWNLOAD_MIME = 'image/octet-stream';
  23. // There are four elements per version. The first two indicate the number of blocks, then the
  24. // data width, and finally the ECC width.
  25. var ECC_BLOCKS = [
  26. 1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17,
  27. 1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28,
  28. 1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22,
  29. 1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16,
  30. 1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22,
  31. 2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28,
  32. 2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26,
  33. 2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26,
  34. 2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24,
  35. 2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28,
  36. 4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24,
  37. 2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28,
  38. 4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22,
  39. 3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24,
  40. 5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24,
  41. 5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
  42. 1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28,
  43. 5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28,
  44. 3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26,
  45. 3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28,
  46. 4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
  47. 2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24,
  48. 4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30,
  49. 6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30,
  50. 8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30,
  51. 10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
  52. 8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30,
  53. 3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30,
  54. 7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30,
  55. 5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30,
  56. 13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30,
  57. 17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30,
  58. 17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
  59. 13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30,
  60. 12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30,
  61. 6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30,
  62. 17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30,
  63. 4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
  64. 20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30,
  65. 19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30
  66. ];
  67. // Map of human-readable ECC levels.
  68. var ECC_LEVELS = {
  69. L: 1,
  70. M: 2,
  71. Q: 3,
  72. H: 4
  73. };
  74. // Final format bits with mask (level << 3 | mask).
  75. var FINAL_FORMAT = [
  76. 0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, /* L */
  77. 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, /* M */
  78. 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, /* Q */
  79. 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b /* H */
  80. ];
  81. // Galois field exponent table.
  82. var GALOIS_EXPONENT = [
  83. 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
  84. 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
  85. 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
  86. 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
  87. 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
  88. 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
  89. 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
  90. 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
  91. 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
  92. 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
  93. 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
  94. 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
  95. 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
  96. 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
  97. 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
  98. 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00
  99. ];
  100. // Galois field log table.
  101. var GALOIS_LOG = [
  102. 0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
  103. 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
  104. 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
  105. 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
  106. 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
  107. 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
  108. 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
  109. 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
  110. 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
  111. 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
  112. 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
  113. 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
  114. 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
  115. 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
  116. 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
  117. 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
  118. ];
  119. // *Badness* coefficients.
  120. var N1 = 3;
  121. var N2 = 3;
  122. var N3 = 40;
  123. var N4 = 10;
  124. // Version pattern.
  125. var VERSION_BLOCK = [
  126. 0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d, 0x928, 0xb78, 0x45d, 0xa17, 0x532,
  127. 0x9a6, 0x683, 0x8c9, 0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75, 0x250, 0x9d5,
  128. 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64, 0x541, 0xc69
  129. ];
  130. // Mode for node.js file system file writes.
  131. var WRITE_MODE = parseInt('0666', 8);
  132. // Private variables
  133. // -----------------
  134. // Run lengths for badness.
  135. var badBuffer = [];
  136. // Constructor for `canvas` elements in the node.js environment.
  137. var Canvas;
  138. // Data block.
  139. var dataBlock;
  140. // ECC data blocks and tables.
  141. var eccBlock, neccBlock1, neccBlock2;
  142. // ECC buffer.
  143. var eccBuffer = [];
  144. // ECC level (defaults to **L**).
  145. var eccLevel = 1;
  146. // Image buffer.
  147. var frameBuffer = [];
  148. // Fixed part of the image.
  149. var frameMask = [];
  150. // File system within the node.js environment.
  151. var fs;
  152. // Constructor for `img` elements in the node.js environment.
  153. var Image;
  154. // Indicates whether or not this script is running in node.js.
  155. var inNode = false;
  156. // Generator polynomial.
  157. var polynomial = [];
  158. // Save the previous value of the `qr` variable.
  159. var previousQr = root.qr;
  160. // Data input buffer.
  161. var stringBuffer = [];
  162. // Version for the data.
  163. var version;
  164. // Data width is based on `version`.
  165. var width;
  166. // Private functions
  167. // -----------------
  168. // Create a new canvas using `document.createElement` unless script is running in node.js, in
  169. // which case the `canvas` module is used.
  170. function createCanvas() {
  171. return inNode ? new Canvas() : root.document.createElement('canvas');
  172. }
  173. // Create a new image using `document.createElement` unless script is running in node.js, in
  174. // which case the `canvas` module is used.
  175. function createImage() {
  176. return inNode ? new Image() : root.document.createElement('img');
  177. }
  178. // Force the canvas image to be downloaded in the browser.
  179. // Optionally, a `callback` function can be specified which will be called upon completed. Since
  180. // this is not an asynchronous operation, this is merely convenient and helps simplify the
  181. // calling code.
  182. function download(cvs, data, callback) {
  183. var mime = data.mime || DEFAULT_MIME;
  184. root.location.href = cvs.toDataURL(mime).replace(mime, DOWNLOAD_MIME);
  185. if (typeof callback === 'function') callback();
  186. }
  187. // Normalize the `data` that is provided to the main API.
  188. function normalizeData(data) {
  189. if (typeof data === 'string') data = { value: data };
  190. return data || {};
  191. }
  192. // Override the `qr` API methods that require HTML5 canvas support to throw a relevant error.
  193. function overrideAPI(qr) {
  194. var methods = [ 'canvas', 'image', 'save', 'saveSync', 'toDataURL' ];
  195. var i;
  196. function overrideMethod(name) {
  197. qr[name] = function () {
  198. throw new Error(name + ' requires HTML5 canvas element support');
  199. };
  200. }
  201. for (i = 0; i < methods.length; i++) {
  202. overrideMethod(methods[i]);
  203. }
  204. }
  205. // Asynchronously write the data of the rendered canvas to a given file path.
  206. function writeFile(cvs, data, callback) {
  207. if (typeof data.path !== 'string') {
  208. return callback(new TypeError('Invalid path type: ' + typeof data.path));
  209. }
  210. var fd, buff;
  211. // Write the buffer to the open file stream once both prerequisites are met.
  212. function writeBuffer() {
  213. fs.write(fd, buff, 0, buff.length, 0, function (error) {
  214. fs.close(fd);
  215. callback(error);
  216. });
  217. }
  218. // Create a buffer of the canvas' data.
  219. cvs.toBuffer(function (error, _buff) {
  220. if (error) return callback(error);
  221. buff = _buff;
  222. if (fd) {
  223. writeBuffer();
  224. }
  225. });
  226. // Open a stream for the file to be written.
  227. fs.open(data.path, 'w', WRITE_MODE, function (error, _fd) {
  228. if (error) return callback(error);
  229. fd = _fd;
  230. if (buff) {
  231. writeBuffer();
  232. }
  233. });
  234. }
  235. // Write the data of the rendered canvas to a given file path.
  236. function writeFileSync(cvs, data) {
  237. if (typeof data.path !== 'string') {
  238. throw new TypeError('Invalid path type: ' + typeof data.path);
  239. }
  240. var buff = cvs.toBuffer();
  241. var fd = fs.openSync(data.path, 'w', WRITE_MODE);
  242. try {
  243. fs.writeSync(fd, buff, 0, buff.length, 0);
  244. } finally {
  245. fs.closeSync(fd);
  246. }
  247. }
  248. // Set bit to indicate cell in frame is immutable (symmetric around diagonal).
  249. function setMask(x, y) {
  250. var bit;
  251. if (x > y) {
  252. bit = x;
  253. x = y;
  254. y = bit;
  255. }
  256. bit = y;
  257. bit *= y;
  258. bit += y;
  259. bit >>= 1;
  260. bit += x;
  261. frameMask[bit] = 1;
  262. }
  263. // Enter alignment pattern. Foreground colour to frame, background to mask. Frame will be merged
  264. // with mask later.
  265. function addAlignment(x, y) {
  266. var i;
  267. frameBuffer[x + width * y] = 1;
  268. for (i = -2; i < 2; i++) {
  269. frameBuffer[(x + i) + width * (y - 2)] = 1;
  270. frameBuffer[(x - 2) + width * (y + i + 1)] = 1;
  271. frameBuffer[(x + 2) + width * (y + i)] = 1;
  272. frameBuffer[(x + i + 1) + width * (y + 2)] = 1;
  273. }
  274. for (i = 0; i < 2; i++) {
  275. setMask(x - 1, y + i);
  276. setMask(x + 1, y - i);
  277. setMask(x - i, y - 1);
  278. setMask(x + i, y + 1);
  279. }
  280. }
  281. // Exponentiation mod N.
  282. function modN(x) {
  283. while (x >= 255) {
  284. x -= 255;
  285. x = (x >> 8) + (x & 255);
  286. }
  287. return x;
  288. }
  289. // Calculate and append `ecc` data to the `data` block. If block is in the string buffer the
  290. // indices to buffers are used.
  291. function appendData(data, dataLength, ecc, eccLength) {
  292. var bit, i, j;
  293. for (i = 0; i < eccLength; i++) {
  294. stringBuffer[ecc + i] = 0;
  295. }
  296. for (i = 0; i < dataLength; i++) {
  297. bit = GALOIS_LOG[stringBuffer[data + i] ^ stringBuffer[ecc]];
  298. if (bit !== 255) {
  299. for (j = 1; j < eccLength; j++) {
  300. stringBuffer[ecc + j - 1] = stringBuffer[ecc + j] ^
  301. GALOIS_EXPONENT[modN(bit + polynomial[eccLength - j])];
  302. }
  303. } else {
  304. for (j = ecc; j < ecc + eccLength; j++) {
  305. stringBuffer[j] = stringBuffer[j + 1];
  306. }
  307. }
  308. stringBuffer[ecc + eccLength - 1] = bit === 255 ? 0 :
  309. GALOIS_EXPONENT[modN(bit + polynomial[0])];
  310. }
  311. }
  312. // Check mask since symmetricals use half.
  313. function isMasked(x, y) {
  314. var bit;
  315. if (x > y) {
  316. bit = x;
  317. x = y;
  318. y = bit;
  319. }
  320. bit = y;
  321. bit += y * y;
  322. bit >>= 1;
  323. bit += x;
  324. return frameMask[bit] === 1;
  325. }
  326. // Apply the selected mask out of the 8 options.
  327. function applyMask(mask) {
  328. var x, y, r3x, r3y;
  329. switch (mask) {
  330. case 0:
  331. for (y = 0; y < width; y++) {
  332. for (x = 0; x < width; x++) {
  333. if (!((x + y) & 1) && !isMasked(x, y)) {
  334. frameBuffer[x + y * width] ^= 1;
  335. }
  336. }
  337. }
  338. break;
  339. case 1:
  340. for (y = 0; y < width; y++) {
  341. for (x = 0; x < width; x++) {
  342. if (!(y & 1) && !isMasked(x, y)) {
  343. frameBuffer[x + y * width] ^= 1;
  344. }
  345. }
  346. }
  347. break;
  348. case 2:
  349. for (y = 0; y < width; y++) {
  350. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  351. if (r3x === 3) r3x = 0;
  352. if (!r3x && !isMasked(x, y)) {
  353. frameBuffer[x + y * width] ^= 1;
  354. }
  355. }
  356. }
  357. break;
  358. case 3:
  359. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  360. if (r3y === 3) r3y = 0;
  361. for (r3x = r3y, x = 0; x < width; x++, r3x++) {
  362. if (r3x === 3) r3x = 0;
  363. if (!r3x && !isMasked(x, y)) {
  364. frameBuffer[x + y * width] ^= 1;
  365. }
  366. }
  367. }
  368. break;
  369. case 4:
  370. for (y = 0; y < width; y++) {
  371. for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++, r3x++) {
  372. if (r3x === 3) {
  373. r3x = 0;
  374. r3y = !r3y;
  375. }
  376. if (!r3y && !isMasked(x, y)) {
  377. frameBuffer[x + y * width] ^= 1;
  378. }
  379. }
  380. }
  381. break;
  382. case 5:
  383. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  384. if (r3y === 3) r3y = 0;
  385. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  386. if (r3x === 3) r3x = 0;
  387. if (!((x & y & 1) + !(!r3x | !r3y)) && !isMasked(x, y)) {
  388. frameBuffer[x + y * width] ^= 1;
  389. }
  390. }
  391. }
  392. break;
  393. case 6:
  394. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  395. if (r3y === 3) r3y = 0;
  396. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  397. if (r3x === 3) r3x = 0;
  398. if (!(((x & y & 1) + (r3x && (r3x === r3y))) & 1) && !isMasked(x, y)) {
  399. frameBuffer[x + y * width] ^= 1;
  400. }
  401. }
  402. }
  403. break;
  404. case 7:
  405. for (r3y = 0, y = 0; y < width; y++, r3y++) {
  406. if (r3y === 3) r3y = 0;
  407. for (r3x = 0, x = 0; x < width; x++, r3x++) {
  408. if (r3x === 3) r3x = 0;
  409. if (!(((r3x && (r3x === r3y)) + ((x + y) & 1)) & 1) && !isMasked(x, y)) {
  410. frameBuffer[x + y * width] ^= 1;
  411. }
  412. }
  413. }
  414. break;
  415. }
  416. }
  417. // Using the table for the length of each run, calculate the amount of bad image. Long runs or
  418. // those that look like finders are called twice; once for X and Y.
  419. function getBadRuns(length) {
  420. var badRuns = 0;
  421. var i;
  422. for (i = 0; i <= length; i++) {
  423. if (badBuffer[i] >= 5) {
  424. badRuns += N1 + badBuffer[i] - 5;
  425. }
  426. }
  427. // FBFFFBF as in finder.
  428. for (i = 3; i < length - 1; i += 2) {
  429. if (badBuffer[i - 2] === badBuffer[i + 2] &&
  430. badBuffer[i + 2] === badBuffer[i - 1] &&
  431. badBuffer[i - 1] === badBuffer[i + 1] &&
  432. badBuffer[i - 1] * 3 === badBuffer[i] &&
  433. // Background around the foreground pattern? Not part of the specs.
  434. (badBuffer[i - 3] === 0 || i + 3 > length ||
  435. badBuffer[i - 3] * 3 >= badBuffer[i] * 4 ||
  436. badBuffer[i + 3] * 3 >= badBuffer[i] * 4)) {
  437. badRuns += N3;
  438. }
  439. }
  440. return badRuns;
  441. }
  442. // Calculate how bad the masked image is (e.g. blocks, imbalance, runs, or finders).
  443. function checkBadness() {
  444. var b, b1, bad, big, bw, count, h, x, y;
  445. bad = bw = count = 0;
  446. // Blocks of same colour.
  447. for (y = 0; y < width - 1; y++) {
  448. for (x = 0; x < width - 1; x++) {
  449. // All foreground colour.
  450. if ((frameBuffer[x + width * y] &&
  451. frameBuffer[(x + 1) + width * y] &&
  452. frameBuffer[x + width * (y + 1)] &&
  453. frameBuffer[(x + 1) + width * (y + 1)]) ||
  454. // All background colour.
  455. !(frameBuffer[x + width * y] ||
  456. frameBuffer[(x + 1) + width * y] ||
  457. frameBuffer[x + width * (y + 1)] ||
  458. frameBuffer[(x + 1) + width * (y + 1)])) {
  459. bad += N2;
  460. }
  461. }
  462. }
  463. // X runs.
  464. for (y = 0; y < width; y++) {
  465. badBuffer[0] = 0;
  466. for (h = b = x = 0; x < width; x++) {
  467. if ((b1 = frameBuffer[x + width * y]) === b) {
  468. badBuffer[h]++;
  469. } else {
  470. badBuffer[++h] = 1;
  471. }
  472. b = b1;
  473. bw += b ? 1 : -1;
  474. }
  475. bad += getBadRuns(h);
  476. }
  477. if (bw < 0) bw = -bw;
  478. big = bw;
  479. big += big << 2;
  480. big <<= 1;
  481. while (big > width * width) {
  482. big -= width * width;
  483. count++;
  484. }
  485. bad += count * N4;
  486. // Y runs.
  487. for (x = 0; x < width; x++) {
  488. badBuffer[0] = 0;
  489. for (h = b = y = 0; y < width; y++) {
  490. if ((b1 = frameBuffer[x + width * y]) === b) {
  491. badBuffer[h]++;
  492. } else {
  493. badBuffer[++h] = 1;
  494. }
  495. b = b1;
  496. }
  497. bad += getBadRuns(h);
  498. }
  499. return bad;
  500. }
  501. // Generate the encoded QR image for the string provided.
  502. function generateFrame(str) {
  503. var i, j, k, m, t, v, x, y;
  504. // Find the smallest version that fits the string.
  505. t = str.length;
  506. version = 0;
  507. do {
  508. version++;
  509. k = (eccLevel - 1) * 4 + (version - 1) * 16;
  510. neccBlock1 = ECC_BLOCKS[k++];
  511. neccBlock2 = ECC_BLOCKS[k++];
  512. dataBlock = ECC_BLOCKS[k++];
  513. eccBlock = ECC_BLOCKS[k];
  514. k = dataBlock * (neccBlock1 + neccBlock2) + neccBlock2 - 3 + (version <= 9);
  515. if (t <= k) break;
  516. } while (version < 40);
  517. // FIXME: Ensure that it fits insted of being truncated.
  518. width = 17 + 4 * version;
  519. // Allocate, clear and setup data structures.
  520. v = dataBlock + (dataBlock + eccBlock) * (neccBlock1 + neccBlock2) + neccBlock2;
  521. for (t = 0; t < v; t++) {
  522. eccBuffer[t] = 0;
  523. }
  524. stringBuffer = str.slice(0);
  525. for (t = 0; t < width * width; t++) {
  526. frameBuffer[t] = 0;
  527. }
  528. for (t = 0; t < (width * (width + 1) + 1) / 2; t++) {
  529. frameMask[t] = 0;
  530. }
  531. // Insert finders: Foreground colour to frame and background to mask.
  532. for (t = 0; t < 3; t++) {
  533. k = y = 0;
  534. if (t === 1) k = (width - 7);
  535. if (t === 2) y = (width - 7);
  536. frameBuffer[(y + 3) + width * (k + 3)] = 1;
  537. for (x = 0; x < 6; x++) {
  538. frameBuffer[(y + x) + width * k] = 1;
  539. frameBuffer[y + width * (k + x + 1)] = 1;
  540. frameBuffer[(y + 6) + width * (k + x)] = 1;
  541. frameBuffer[(y + x + 1) + width * (k + 6)] = 1;
  542. }
  543. for (x = 1; x < 5; x++) {
  544. setMask(y + x, k + 1);
  545. setMask(y + 1, k + x + 1);
  546. setMask(y + 5, k + x);
  547. setMask(y + x + 1, k + 5);
  548. }
  549. for (x = 2; x < 4; x++) {
  550. frameBuffer[(y + x) + width * (k + 2)] = 1;
  551. frameBuffer[(y + 2) + width * (k + x + 1)] = 1;
  552. frameBuffer[(y + 4) + width * (k + x)] = 1;
  553. frameBuffer[(y + x + 1) + width * (k + 4)] = 1;
  554. }
  555. }
  556. // Alignment blocks.
  557. if (version > 1) {
  558. t = ALIGNMENT_DELTA[version];
  559. y = width - 7;
  560. for (;;) {
  561. x = width - 7;
  562. while (x > t - 3) {
  563. addAlignment(x, y);
  564. if (x < t) break;
  565. x -= t;
  566. }
  567. if (y <= t + 9) break;
  568. y -= t;
  569. addAlignment(6, y);
  570. addAlignment(y, 6);
  571. }
  572. }
  573. // Single foreground cell.
  574. frameBuffer[8 + width * (width - 8)] = 1;
  575. // Timing gap (mask only).
  576. for (y = 0; y < 7; y++) {
  577. setMask(7, y);
  578. setMask(width - 8, y);
  579. setMask(7, y + width - 7);
  580. }
  581. for (x = 0; x < 8; x++) {
  582. setMask(x, 7);
  583. setMask(x + width - 8, 7);
  584. setMask(x, width - 8);
  585. }
  586. // Reserve mask, format area.
  587. for (x = 0; x < 9; x++) {
  588. setMask(x, 8);
  589. }
  590. for (x = 0; x < 8; x++) {
  591. setMask(x + width - 8, 8);
  592. setMask(8, x);
  593. }
  594. for (y = 0; y < 7; y++) {
  595. setMask(8, y + width - 7);
  596. }
  597. // Timing row/column.
  598. for (x = 0; x < width - 14; x++) {
  599. if (x & 1) {
  600. setMask(8 + x, 6);
  601. setMask(6, 8 + x);
  602. } else {
  603. frameBuffer[(8 + x) + width * 6] = 1;
  604. frameBuffer[6 + width * (8 + x)] = 1;
  605. }
  606. }
  607. // Version block.
  608. if (version > 6) {
  609. t = VERSION_BLOCK[version - 7];
  610. k = 17;
  611. for (x = 0; x < 6; x++) {
  612. for (y = 0; y < 3; y++, k--) {
  613. if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
  614. frameBuffer[(5 - x) + width * (2 - y + width - 11)] = 1;
  615. frameBuffer[(2 - y + width - 11) + width * (5 - x)] = 1;
  616. } else {
  617. setMask(5 - x, 2 - y + width - 11);
  618. setMask(2 - y + width - 11, 5 - x);
  619. }
  620. }
  621. }
  622. }
  623. // Sync mask bits. Only set above for background cells, so now add the foreground.
  624. for (y = 0; y < width; y++) {
  625. for (x = 0; x <= y; x++) {
  626. if (frameBuffer[x + width * y]) {
  627. setMask(x, y);
  628. }
  629. }
  630. }
  631. // Convert string to bit stream. 8-bit data to QR-coded 8-bit data (numeric, alphanum, or kanji
  632. // not supported).
  633. v = stringBuffer.length;
  634. // String to array.
  635. for (i = 0; i < v; i++) {
  636. eccBuffer[i] = stringBuffer.charCodeAt(i);
  637. }
  638. stringBuffer = eccBuffer.slice(0);
  639. // Calculate max string length.
  640. x = dataBlock * (neccBlock1 + neccBlock2) + neccBlock2;
  641. if (v >= x - 2) {
  642. v = x - 2;
  643. if (version > 9) v--;
  644. }
  645. // Shift and re-pack to insert length prefix.
  646. i = v;
  647. if (version > 9) {
  648. stringBuffer[i + 2] = 0;
  649. stringBuffer[i + 3] = 0;
  650. while (i--) {
  651. t = stringBuffer[i];
  652. stringBuffer[i + 3] |= 255 & (t << 4);
  653. stringBuffer[i + 2] = t >> 4;
  654. }
  655. stringBuffer[2] |= 255 & (v << 4);
  656. stringBuffer[1] = v >> 4;
  657. stringBuffer[0] = 0x40 | (v >> 12);
  658. } else {
  659. stringBuffer[i + 1] = 0;
  660. stringBuffer[i + 2] = 0;
  661. while (i--) {
  662. t = stringBuffer[i];
  663. stringBuffer[i + 2] |= 255 & (t << 4);
  664. stringBuffer[i + 1] = t >> 4;
  665. }
  666. stringBuffer[1] |= 255 & (v << 4);
  667. stringBuffer[0] = 0x40 | (v >> 4);
  668. }
  669. // Fill to end with pad pattern.
  670. i = v + 3 - (version < 10);
  671. while (i < x) {
  672. stringBuffer[i++] = 0xec;
  673. stringBuffer[i++] = 0x11;
  674. }
  675. // Calculate generator polynomial.
  676. polynomial[0] = 1;
  677. for (i = 0; i < eccBlock; i++) {
  678. polynomial[i + 1] = 1;
  679. for (j = i; j > 0; j--) {
  680. polynomial[j] = polynomial[j] ? polynomial[j - 1] ^
  681. GALOIS_EXPONENT[modN(GALOIS_LOG[polynomial[j]] + i)] : polynomial[j - 1];
  682. }
  683. polynomial[0] = GALOIS_EXPONENT[modN(GALOIS_LOG[polynomial[0]] + i)];
  684. }
  685. // Use logs for generator polynomial to save calculation step.
  686. for (i = 0; i <= eccBlock; i++) {
  687. polynomial[i] = GALOIS_LOG[polynomial[i]];
  688. }
  689. // Append ECC to data buffer.
  690. k = x;
  691. y = 0;
  692. for (i = 0; i < neccBlock1; i++) {
  693. appendData(y, dataBlock, k, eccBlock);
  694. y += dataBlock;
  695. k += eccBlock;
  696. }
  697. for (i = 0; i < neccBlock2; i++) {
  698. appendData(y, dataBlock + 1, k, eccBlock);
  699. y += dataBlock + 1;
  700. k += eccBlock;
  701. }
  702. // Interleave blocks.
  703. y = 0;
  704. for (i = 0; i < dataBlock; i++) {
  705. for (j = 0; j < neccBlock1; j++) {
  706. eccBuffer[y++] = stringBuffer[i + j * dataBlock];
  707. }
  708. for (j = 0; j < neccBlock2; j++) {
  709. eccBuffer[y++] = stringBuffer[(neccBlock1 * dataBlock) + i + (j * (dataBlock + 1))];
  710. }
  711. }
  712. for (j = 0; j < neccBlock2; j++) {
  713. eccBuffer[y++] = stringBuffer[(neccBlock1 * dataBlock) + i + (j * (dataBlock + 1))];
  714. }
  715. for (i = 0; i < eccBlock; i++) {
  716. for (j = 0; j < neccBlock1 + neccBlock2; j++) {
  717. eccBuffer[y++] = stringBuffer[x + i + j * eccBlock];
  718. }
  719. }
  720. stringBuffer = eccBuffer;
  721. // Pack bits into frame avoiding masked area.
  722. x = y = width - 1;
  723. k = v = 1;
  724. // inteleaved data and ECC codes.
  725. m = (dataBlock + eccBlock) * (neccBlock1 + neccBlock2) + neccBlock2;
  726. for (i = 0; i < m; i++) {
  727. t = stringBuffer[i];
  728. for (j = 0; j < 8; j++, t <<= 1) {
  729. if (0x80 & t) {
  730. frameBuffer[x + width * y] = 1;
  731. }
  732. // Find next fill position.
  733. do {
  734. if (v) {
  735. x--;
  736. } else {
  737. x++;
  738. if (k) {
  739. if (y !== 0) {
  740. y--;
  741. } else {
  742. x -= 2;
  743. k = !k;
  744. if (x === 6) {
  745. x--;
  746. y = 9;
  747. }
  748. }
  749. } else {
  750. if (y !== width - 1) {
  751. y++;
  752. } else {
  753. x -= 2;
  754. k = !k;
  755. if (x === 6) {
  756. x--;
  757. y -= 8;
  758. }
  759. }
  760. }
  761. }
  762. v = !v;
  763. } while (isMasked(x, y));
  764. }
  765. }
  766. // Save pre-mask copy of frame.
  767. stringBuffer = frameBuffer.slice(0);
  768. t = 0;
  769. y = 30000;
  770. // Using `for` instead of `while` since in original Arduino code if an early mask was *good
  771. // enough* it wouldn't try for a better one since they get more complex and take longer.
  772. for (k = 0; k < 8; k++) {
  773. // Returns foreground-background imbalance.
  774. applyMask(k);
  775. x = checkBadness();
  776. // Is current mask better than previous best?
  777. if (x < y) {
  778. y = x;
  779. t = k;
  780. }
  781. // Don't increment `i` to a void redoing mask.
  782. if (t === 7) break;
  783. // Reset for next pass.
  784. frameBuffer = stringBuffer.slice(0);
  785. }
  786. // Redo best mask as none were *good enough* (i.e. last wasn't `t`).
  787. if (t !== k) {
  788. applyMask(t);
  789. }
  790. // Add in final mask/ECC level bytes.
  791. y = FINAL_FORMAT[t + ((eccLevel - 1) << 3)];
  792. // Low byte.
  793. for (k = 0; k < 8; k++, y >>= 1) {
  794. if (y & 1) {
  795. frameBuffer[(width - 1 - k) + width * 8] = 1;
  796. if (k < 6) {
  797. frameBuffer[8 + width * k] = 1;
  798. } else {
  799. frameBuffer[8 + width * (k + 1)] = 1;
  800. }
  801. }
  802. }
  803. // High byte.
  804. for (k = 0; k < 7; k++, y >>= 1) {
  805. if (y & 1) {
  806. frameBuffer[8 + width * (width - 7 + k)] = 1;
  807. if (k) {
  808. frameBuffer[(6 - k) + width * 8] = 1;
  809. } else {
  810. frameBuffer[7 + width * 8] = 1;
  811. }
  812. }
  813. }
  814. // Finally, return the image data.
  815. return frameBuffer;
  816. }
  817. // qr.js setup
  818. // -----------
  819. // Build the publicly exposed API.
  820. var qr = {
  821. // Constants
  822. // ---------
  823. // Current version of `qr`.
  824. VERSION: '1.1.3',
  825. // QR functions
  826. // ------------
  827. // Generate the QR code using the data provided and render it on to a `<canvas>` element.
  828. // If no `<canvas>` element is specified in the argument provided a new one will be created and
  829. // used.
  830. // ECC (error correction capacity) determines how many intential errors are contained in the QR
  831. // code.
  832. canvas: function(data) {
  833. data = normalizeData(data);
  834. // Module size of the generated QR code (i.e. 1-10).
  835. var size = data.size >= 1 && data.size <= 10 ? data.size : 4;
  836. // Actual size of the QR code symbol and is scaled to 25 pixels (e.g. 1 = 25px, 3 = 75px).
  837. size *= 25;
  838. // `<canvas>` element used to render the QR code.
  839. var cvs = data.canvas || createCanvas();
  840. // Retreive the 2D context of the canvas.
  841. var c2d = cvs.getContext('2d');
  842. // Ensure the canvas has the correct dimensions.
  843. c2d.canvas.width = size;
  844. c2d.canvas.height = size;
  845. // Fill the canvas with the correct background colour.
  846. c2d.fillStyle = data.background || '#fff';
  847. c2d.fillRect(0, 0, size, size);
  848. // Determine the ECC level to be applied.
  849. eccLevel = ECC_LEVELS[(data.level && data.level.toUpperCase()) || 'L'];
  850. // Generate the image frame for the given `value`.
  851. var frame = generateFrame(data.value || '');
  852. c2d.lineWidth = 1;
  853. // Determine the *pixel* size.
  854. var px = size;
  855. px /= width;
  856. px = Math.floor(px);
  857. // Draw the QR code.
  858. c2d.clearRect(0, 0, size, size);
  859. c2d.fillStyle = data.background || '#fff';
  860. c2d.fillRect(0, 0, px * (width + 8), px * (width + 8));
  861. c2d.fillStyle = data.foreground || '#000';
  862. var i, j;
  863. for (i = 0; i < width; i++) {
  864. for (j = 0; j < width; j++) {
  865. if (frame[j * width + i]) {
  866. c2d.fillRect(px * i, px * j, px, px);
  867. }
  868. }
  869. }
  870. return cvs;
  871. },
  872. // Generate the QR code using the data provided and render it on to a `<img>` element.
  873. // If no `<img>` element is specified in the argument provided a new one will be created and
  874. // used.
  875. // ECC (error correction capacity) determines how many intential errors are contained in the QR
  876. // code.
  877. image: function(data) {
  878. data = normalizeData(data);
  879. // `<canvas>` element only which the QR code is rendered.
  880. var cvs = this.canvas(data);
  881. // `<img>` element used to display the QR code.
  882. var img = data.image || createImage();
  883. // Apply the QR code to `img`.
  884. img.src = cvs.toDataURL(data.mime || DEFAULT_MIME);
  885. img.height = cvs.height;
  886. img.width = cvs.width;
  887. return img;
  888. },
  889. // Generate the QR code using the data provided and render it on to a `<canvas>` element and
  890. // save it as an image file.
  891. // If no `<canvas>` element is specified in the argument provided a new one will be created and
  892. // used.
  893. // ECC (error correction capacity) determines how many intential errors are contained in the QR
  894. // code.
  895. // If called in a browser the `path` property/argument is ignored and will simply prompt the
  896. // user to choose a location and file name. However, if called within node.js the file will be
  897. // saved to specified path.
  898. // A `callback` function must be provided which will be called once the saving process has
  899. // started. If an error occurs it will be passed as the first argument to this function,
  900. // otherwise this argument will be `null`.
  901. save: function(data, path, callback) {
  902. data = normalizeData(data);
  903. switch (typeof path) {
  904. case 'function':
  905. callback = path;
  906. path = null;
  907. break;
  908. case 'string':
  909. data.path = path;
  910. break;
  911. }
  912. // Callback function is required.
  913. if (typeof callback !== 'function') {
  914. throw new TypeError('Invalid callback type: ' + typeof callback);
  915. }
  916. var completed = false;
  917. // `<canvas>` element only which the QR code is rendered.
  918. var cvs = this.canvas(data);
  919. // Simple function to try and ensure that the `callback` function is only called once.
  920. function done(error) {
  921. if (!completed) {
  922. completed = true;
  923. callback(error);
  924. }
  925. }
  926. if (inNode) {
  927. writeFile(cvs, data, done);
  928. } else {
  929. download(cvs, data, done);
  930. }
  931. },
  932. // Generate the QR code using the data provided and render it on to a `<canvas>` element and
  933. // save it as an image file.
  934. // If no `<canvas>` element is specified in the argument provided a new one will be created and
  935. // used.
  936. // ECC (error correction capacity) determines how many intential errors are contained in the QR
  937. // code.
  938. // If called in a browser the `path` property/argument is ignored and will simply prompt the
  939. // user to choose a location and file name. However, if called within node.js the file will be
  940. // saved to specified path.
  941. saveSync: function(data, path) {
  942. data = normalizeData(data);
  943. if (typeof path === 'string') data.path = path;
  944. // `<canvas>` element only which the QR code is rendered.
  945. var cvs = this.canvas(data);
  946. if (inNode) {
  947. writeFileSync(cvs, data);
  948. } else {
  949. download(cvs, data);
  950. }
  951. },
  952. // Generate the QR code using the data provided and render it on to a `<canvas>` element before
  953. // returning its data URI.
  954. // If no `<canvas>` element is specified in the argument provided a new one will be created and
  955. // used.
  956. // ECC (error correction capacity) determines how many intential errors are contained in the QR
  957. // code.
  958. toDataURL: function(data) {
  959. data = normalizeData(data);
  960. return this.canvas(data).toDataURL(data.mime || DEFAULT_MIME);
  961. },
  962. // Utility functions
  963. // -----------------
  964. // Run qr.js in *noConflict* mode, returning the `qr` variable to its previous owner.
  965. // Returns a reference to `qr`.
  966. noConflict: function() {
  967. root.qr = previousQr;
  968. return this;
  969. }
  970. };
  971. // Support
  972. // -------
  973. // Export `qr` for node.js and CommonJS.
  974. if (typeof exports !== 'undefined') {
  975. inNode = true;
  976. if (typeof module !== 'undefined' && module.exports) {
  977. exports = module.exports = qr;
  978. }
  979. exports.qr = qr;
  980. // Import required node.js modules.
  981. Canvas = require('canvas');
  982. Image = Canvas.Image;
  983. fs = require('fs');
  984. } else if (typeof define === 'function' && define.amd) {
  985. define(function () {
  986. return qr;
  987. });
  988. } else {
  989. // In non-HTML5 browser so strip base functionality.
  990. if (!root.HTMLCanvasElement) {
  991. overrideAPI(qr);
  992. }
  993. root.qr = qr;
  994. }
  995. })(this);