UNPKG

6.97 kBJavaScriptView Raw
1var QRMode = require('./QRMode');
2var QRPolynomial = require('./QRPolynomial');
3var QRMath = require('./QRMath');
4var QRMaskPattern = require('./QRMaskPattern');
5
6var QRUtil = {
7
8 PATTERN_POSITION_TABLE : [
9 [],
10 [6, 18],
11 [6, 22],
12 [6, 26],
13 [6, 30],
14 [6, 34],
15 [6, 22, 38],
16 [6, 24, 42],
17 [6, 26, 46],
18 [6, 28, 50],
19 [6, 30, 54],
20 [6, 32, 58],
21 [6, 34, 62],
22 [6, 26, 46, 66],
23 [6, 26, 48, 70],
24 [6, 26, 50, 74],
25 [6, 30, 54, 78],
26 [6, 30, 56, 82],
27 [6, 30, 58, 86],
28 [6, 34, 62, 90],
29 [6, 28, 50, 72, 94],
30 [6, 26, 50, 74, 98],
31 [6, 30, 54, 78, 102],
32 [6, 28, 54, 80, 106],
33 [6, 32, 58, 84, 110],
34 [6, 30, 58, 86, 114],
35 [6, 34, 62, 90, 118],
36 [6, 26, 50, 74, 98, 122],
37 [6, 30, 54, 78, 102, 126],
38 [6, 26, 52, 78, 104, 130],
39 [6, 30, 56, 82, 108, 134],
40 [6, 34, 60, 86, 112, 138],
41 [6, 30, 58, 86, 114, 142],
42 [6, 34, 62, 90, 118, 146],
43 [6, 30, 54, 78, 102, 126, 150],
44 [6, 24, 50, 76, 102, 128, 154],
45 [6, 28, 54, 80, 106, 132, 158],
46 [6, 32, 58, 84, 110, 136, 162],
47 [6, 26, 54, 82, 110, 138, 166],
48 [6, 30, 58, 86, 114, 142, 170]
49 ],
50
51 G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
52 G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
53 G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
54
55 getBCHTypeInfo : function(data) {
56 var d = data << 10;
57 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
58 d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) );
59 }
60 return ( (data << 10) | d) ^ QRUtil.G15_MASK;
61 },
62
63 getBCHTypeNumber : function(data) {
64 var d = data << 12;
65 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
66 d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) );
67 }
68 return (data << 12) | d;
69 },
70
71 getBCHDigit : function(data) {
72
73 var digit = 0;
74
75 while (data != 0) {
76 digit++;
77 data >>>= 1;
78 }
79
80 return digit;
81 },
82
83 getPatternPosition : function(typeNumber) {
84 return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
85 },
86
87 getMask : function(maskPattern, i, j) {
88
89 switch (maskPattern) {
90
91 case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;
92 case QRMaskPattern.PATTERN001 : return i % 2 == 0;
93 case QRMaskPattern.PATTERN010 : return j % 3 == 0;
94 case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;
95 case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;
96 case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;
97 case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;
98 case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;
99
100 default :
101 throw new Error("bad maskPattern:" + maskPattern);
102 }
103 },
104
105 getErrorCorrectPolynomial : function(errorCorrectLength) {
106
107 var a = new QRPolynomial([1], 0);
108
109 for (var i = 0; i < errorCorrectLength; i++) {
110 a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0) );
111 }
112
113 return a;
114 },
115
116 getLengthInBits : function(mode, type) {
117
118 if (1 <= type && type < 10) {
119
120 // 1 - 9
121
122 switch(mode) {
123 case QRMode.MODE_NUMBER : return 10;
124 case QRMode.MODE_ALPHA_NUM : return 9;
125 case QRMode.MODE_8BIT_BYTE : return 8;
126 case QRMode.MODE_KANJI : return 8;
127 default :
128 throw new Error("mode:" + mode);
129 }
130
131 } else if (type < 27) {
132
133 // 10 - 26
134
135 switch(mode) {
136 case QRMode.MODE_NUMBER : return 12;
137 case QRMode.MODE_ALPHA_NUM : return 11;
138 case QRMode.MODE_8BIT_BYTE : return 16;
139 case QRMode.MODE_KANJI : return 10;
140 default :
141 throw new Error("mode:" + mode);
142 }
143
144 } else if (type < 41) {
145
146 // 27 - 40
147
148 switch(mode) {
149 case QRMode.MODE_NUMBER : return 14;
150 case QRMode.MODE_ALPHA_NUM : return 13;
151 case QRMode.MODE_8BIT_BYTE : return 16;
152 case QRMode.MODE_KANJI : return 12;
153 default :
154 throw new Error("mode:" + mode);
155 }
156
157 } else {
158 throw new Error("type:" + type);
159 }
160 },
161
162 getLostPoint : function(qrCode) {
163
164 var moduleCount = qrCode.getModuleCount();
165
166 var lostPoint = 0;
167
168 // LEVEL1
169
170 for (var row = 0; row < moduleCount; row++) {
171
172 for (var col = 0; col < moduleCount; col++) {
173
174 var sameCount = 0;
175 var dark = qrCode.isDark(row, col);
176
177 for (var r = -1; r <= 1; r++) {
178
179 if (row + r < 0 || moduleCount <= row + r) {
180 continue;
181 }
182
183 for (var c = -1; c <= 1; c++) {
184
185 if (col + c < 0 || moduleCount <= col + c) {
186 continue;
187 }
188
189 if (r == 0 && c == 0) {
190 continue;
191 }
192
193 if (dark == qrCode.isDark(row + r, col + c) ) {
194 sameCount++;
195 }
196 }
197 }
198
199 if (sameCount > 5) {
200 lostPoint += (3 + sameCount - 5);
201 }
202 }
203 }
204
205 // LEVEL2
206
207 for (var row = 0; row < moduleCount - 1; row++) {
208 for (var col = 0; col < moduleCount - 1; col++) {
209 var count = 0;
210 if (qrCode.isDark(row, col ) ) count++;
211 if (qrCode.isDark(row + 1, col ) ) count++;
212 if (qrCode.isDark(row, col + 1) ) count++;
213 if (qrCode.isDark(row + 1, col + 1) ) count++;
214 if (count == 0 || count == 4) {
215 lostPoint += 3;
216 }
217 }
218 }
219
220 // LEVEL3
221
222 for (var row = 0; row < moduleCount; row++) {
223 for (var col = 0; col < moduleCount - 6; col++) {
224 if (qrCode.isDark(row, col)
225 && !qrCode.isDark(row, col + 1)
226 && qrCode.isDark(row, col + 2)
227 && qrCode.isDark(row, col + 3)
228 && qrCode.isDark(row, col + 4)
229 && !qrCode.isDark(row, col + 5)
230 && qrCode.isDark(row, col + 6) ) {
231 lostPoint += 40;
232 }
233 }
234 }
235
236 for (var col = 0; col < moduleCount; col++) {
237 for (var row = 0; row < moduleCount - 6; row++) {
238 if (qrCode.isDark(row, col)
239 && !qrCode.isDark(row + 1, col)
240 && qrCode.isDark(row + 2, col)
241 && qrCode.isDark(row + 3, col)
242 && qrCode.isDark(row + 4, col)
243 && !qrCode.isDark(row + 5, col)
244 && qrCode.isDark(row + 6, col) ) {
245 lostPoint += 40;
246 }
247 }
248 }
249
250 // LEVEL4
251
252 var darkCount = 0;
253
254 for (var col = 0; col < moduleCount; col++) {
255 for (var row = 0; row < moduleCount; row++) {
256 if (qrCode.isDark(row, col) ) {
257 darkCount++;
258 }
259 }
260 }
261
262 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
263 lostPoint += ratio * 10;
264
265 return lostPoint;
266 }
267
268};
269
270module.exports = QRUtil;