| 1 | // The QR specification's tables, versions 1–6. |
| 2 | // |
| 3 | // Separated from qr.js because they are data, not logic: nothing here is |
| 4 | // derived or clever, and a mistake in it is a transcription mistake rather |
| 5 | // than a reasoning one. Both kinds happen, and they are found differently — |
| 6 | // these numbers are checked by comparing whole symbols against another |
| 7 | // encoder (test/qr.test.mjs), which is the only way to catch a wrong row. |
| 8 | |
| 9 | export const ALNUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; |
| 10 | |
| 11 | // EC level codes as they appear in the format information. |
| 12 | export const EC_LEVELS = { L: 0b01, M: 0b00, Q: 0b11, H: 0b10 }; |
| 13 | |
| 14 | // [total codewords, ec codewords per block, [blocks, data codewords]...] |
| 15 | export const BLOCKS = { |
| 16 | 1: { L: [26, 7, [[1, 19]]], M: [26, 10, [[1, 16]]], Q: [26, 13, [[1, 13]]], H: [26, 17, [[1, 9]]] }, |
| 17 | 2: { L: [44, 10, [[1, 34]]], M: [44, 16, [[1, 28]]], Q: [44, 22, [[1, 22]]], H: [44, 28, [[1, 16]]] }, |
| 18 | 3: { L: [70, 15, [[1, 55]]], M: [70, 26, [[1, 44]]], Q: [70, 18, [[2, 17]]], H: [70, 22, [[2, 13]]] }, |
| 19 | 4: { L: [100, 20, [[1, 80]]], M: [100, 18, [[2, 32]]], Q: [100, 26, [[2, 24]]], H: [100, 16, [[4, 9]]] }, |
| 20 | 5: { L: [134, 26, [[1, 108]]], M: [134, 24, [[2, 43]]], Q: [134, 18, [[2, 15], [2, 16]]], H: [134, 22, [[2, 11], [2, 12]]] }, |
| 21 | 6: { L: [172, 18, [[2, 68]]], M: [172, 16, [[4, 27]]], Q: [172, 24, [[4, 19]]], H: [172, 28, [[4, 15]]] }, |
| 22 | }; |
| 23 | |
| 24 | // Alignment pattern centres. Version 1 has none. |
| 25 | export const ALIGNMENT = { 1: [], 2: [6, 18], 3: [6, 22], 4: [6, 26], 5: [6, 30], 6: [6, 34] }; |
| 26 | |
| 27 | // The eight data masks. A symbol is drawn eight times and the one with the |
| 28 | // lowest penalty wins, which is what stops a payload producing a field of |
| 29 | // stripes a scanner reads as a finder pattern. |
| 30 | export const MASKS = [ |
| 31 | (r, c) => (r + c) % 2 === 0, |
| 32 | (r) => r % 2 === 0, |
| 33 | (r, c) => c % 3 === 0, |
| 34 | (r, c) => (r + c) % 3 === 0, |
| 35 | (r, c) => (Math.floor(r / 2) + Math.floor(c / 3)) % 2 === 0, |
| 36 | (r, c) => ((r * c) % 2) + ((r * c) % 3) === 0, |
| 37 | (r, c) => (((r * c) % 2) + ((r * c) % 3)) % 2 === 0, |
| 38 | (r, c) => (((r + c) % 2) + ((r * c) % 3)) % 2 === 0, |
| 39 | ]; |
| 40 | |
| 41 | export const size = (version) => version * 4 + 17; |
| 42 | |
| 43 | export const dataCapacity = (version, ec) => |
| 44 | BLOCKS[version][ec][2].reduce((n, [blocks, words]) => n + blocks * words, 0); |
| 45 | |