quirc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 95b42c1794ae28a39eaa4624f95f21ec08998e82
4
+ data.tar.gz: 30374a93a681b09eb4c6895187a1149139bcca36
5
+ SHA512:
6
+ metadata.gz: 20cd7bc2adbf17fcfbbb10dc1286a23f6db8b6597c4705147e265c55b665c721676889ad50bea6075b168427ed2e93fddf930125bf6fbf1368cae85e92de1c38
7
+ data.tar.gz: a72a276e462450515e457c60f5b86b33702e30b38d5bbf0ecda8f9ec9a18fdfcd3d2d04199c799a7450233ceeeb52e7f76d4d9457e30d0a1ef9fbdb0e4c2c021
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Jacob Middag
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ # Quirc bindings for Ruby
2
+
3
+ Quirc is a small C library for extracting and decode QR codes from images.
4
+ This project is a Ruby binding for that library with the library embedded.
5
+
6
+ ## License
7
+ This software is licensed under the MIT License. [View the license](LICENSE).
@@ -0,0 +1,16 @@
1
+ quirc -- QR-code recognition library
2
+ Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
3
+
4
+ Permission to use, copy, modify, and/or distribute this software for
5
+ any purpose with or without fee is hereby granted, provided that the
6
+ above copyright notice and this permission notice appear in all
7
+ copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10
+ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11
+ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12
+ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14
+ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16
+ PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,35 @@
1
+ # quirc -- QR-code recognition library
2
+ # Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
3
+ # 2017 Jacob Middag <jacob@gaddim.nl>
4
+ #
5
+ # Permission to use, copy, modify, and/or distribute this software for any
6
+ # purpose with or without fee is hereby granted, provided that the above
7
+ # copyright notice and this permission notice appear in all copies.
8
+ #
9
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+
17
+ CC ?= gcc
18
+ BUILD_DIR ?= .
19
+
20
+ LIB_VERSION = 1.0
21
+
22
+ CFLAGS ?= -O3 -Wall -fPIC
23
+ LIB_OBJ = \
24
+ lib/decode.o \
25
+ lib/identify.o \
26
+ lib/quirc.o \
27
+ lib/version_db.o
28
+
29
+ $(BUILD_DIR)/libquirc.a: $(patsubst lib/%.o, $(BUILD_DIR)/%.o, $(LIB_OBJ))
30
+ rm -f $@
31
+ ar cru $@ $+
32
+ ranlib $@
33
+
34
+ $(BUILD_DIR)/%.o: lib/%.c
35
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
@@ -0,0 +1,913 @@
1
+ /* quirc -- QR-code recognition library
2
+ * Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #include "quirc_internal.h"
18
+
19
+ #include <string.h>
20
+ #include <stdlib.h>
21
+
22
+ #define MAX_POLY 64
23
+
24
+ /************************************************************************
25
+ * Galois fields
26
+ */
27
+
28
+ struct galois_field {
29
+ int p;
30
+ const uint8_t *log;
31
+ const uint8_t *exp;
32
+ };
33
+
34
+ static const uint8_t gf16_exp[16] = {
35
+ 0x01, 0x02, 0x04, 0x08, 0x03, 0x06, 0x0c, 0x0b,
36
+ 0x05, 0x0a, 0x07, 0x0e, 0x0f, 0x0d, 0x09, 0x01
37
+ };
38
+
39
+ static const uint8_t gf16_log[16] = {
40
+ 0x00, 0x0f, 0x01, 0x04, 0x02, 0x08, 0x05, 0x0a,
41
+ 0x03, 0x0e, 0x09, 0x07, 0x06, 0x0d, 0x0b, 0x0c
42
+ };
43
+
44
+ static const struct galois_field gf16 = {
45
+ .p = 15,
46
+ .log = gf16_log,
47
+ .exp = gf16_exp
48
+ };
49
+
50
+ static const uint8_t gf256_exp[256] = {
51
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
52
+ 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
53
+ 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
54
+ 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
55
+ 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
56
+ 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
57
+ 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
58
+ 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
59
+ 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
60
+ 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
61
+ 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
62
+ 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
63
+ 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
64
+ 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
65
+ 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
66
+ 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
67
+ 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
68
+ 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
69
+ 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
70
+ 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
71
+ 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
72
+ 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
73
+ 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
74
+ 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
75
+ 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
76
+ 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
77
+ 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
78
+ 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
79
+ 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
80
+ 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
81
+ 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
82
+ 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01
83
+ };
84
+
85
+ static const uint8_t gf256_log[256] = {
86
+ 0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
87
+ 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
88
+ 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
89
+ 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
90
+ 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
91
+ 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
92
+ 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
93
+ 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
94
+ 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
95
+ 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
96
+ 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
97
+ 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
98
+ 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
99
+ 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
100
+ 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
101
+ 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
102
+ 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
103
+ 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
104
+ 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
105
+ 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
106
+ 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
107
+ 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
108
+ 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
109
+ 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
110
+ 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
111
+ 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
112
+ 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
113
+ 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
114
+ 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
115
+ 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
116
+ 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
117
+ 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
118
+ };
119
+
120
+ const static struct galois_field gf256 = {
121
+ .p = 255,
122
+ .log = gf256_log,
123
+ .exp = gf256_exp
124
+ };
125
+
126
+ /************************************************************************
127
+ * Polynomial operations
128
+ */
129
+
130
+ static void poly_add(uint8_t *dst, const uint8_t *src, uint8_t c,
131
+ int shift, const struct galois_field *gf)
132
+ {
133
+ int i;
134
+ int log_c = gf->log[c];
135
+
136
+ if (!c)
137
+ return;
138
+
139
+ for (i = 0; i < MAX_POLY; i++) {
140
+ int p = i + shift;
141
+ uint8_t v = src[i];
142
+
143
+ if (p < 0 || p >= MAX_POLY)
144
+ continue;
145
+ if (!v)
146
+ continue;
147
+
148
+ dst[p] ^= gf->exp[(gf->log[v] + log_c) % gf->p];
149
+ }
150
+ }
151
+
152
+ static uint8_t poly_eval(const uint8_t *s, uint8_t x,
153
+ const struct galois_field *gf)
154
+ {
155
+ int i;
156
+ uint8_t sum = 0;
157
+ uint8_t log_x = gf->log[x];
158
+
159
+ if (!x)
160
+ return s[0];
161
+
162
+ for (i = 0; i < MAX_POLY; i++) {
163
+ uint8_t c = s[i];
164
+
165
+ if (!c)
166
+ continue;
167
+
168
+ sum ^= gf->exp[(gf->log[c] + log_x * i) % gf->p];
169
+ }
170
+
171
+ return sum;
172
+ }
173
+
174
+ /************************************************************************
175
+ * Berlekamp-Massey algorithm for finding error locator polynomials.
176
+ */
177
+
178
+ static void berlekamp_massey(const uint8_t *s, int N,
179
+ const struct galois_field *gf,
180
+ uint8_t *sigma)
181
+ {
182
+ uint8_t C[MAX_POLY];
183
+ uint8_t B[MAX_POLY];
184
+ int L = 0;
185
+ int m = 1;
186
+ uint8_t b = 1;
187
+ int n;
188
+
189
+ memset(B, 0, sizeof(B));
190
+ memset(C, 0, sizeof(C));
191
+ B[0] = 1;
192
+ C[0] = 1;
193
+
194
+ for (n = 0; n < N; n++) {
195
+ uint8_t d = s[n];
196
+ uint8_t mult;
197
+ int i;
198
+
199
+ for (i = 1; i <= L; i++) {
200
+ if (!(C[i] && s[n - i]))
201
+ continue;
202
+
203
+ d ^= gf->exp[(gf->log[C[i]] +
204
+ gf->log[s[n - i]]) %
205
+ gf->p];
206
+ }
207
+
208
+ mult = gf->exp[(gf->p - gf->log[b] + gf->log[d]) % gf->p];
209
+
210
+ if (!d) {
211
+ m++;
212
+ } else if (L * 2 <= n) {
213
+ uint8_t T[MAX_POLY];
214
+
215
+ memcpy(T, C, sizeof(T));
216
+ poly_add(C, B, mult, m, gf);
217
+ memcpy(B, T, sizeof(B));
218
+ L = n + 1 - L;
219
+ b = d;
220
+ m = 1;
221
+ } else {
222
+ poly_add(C, B, mult, m, gf);
223
+ m++;
224
+ }
225
+ }
226
+
227
+ memcpy(sigma, C, MAX_POLY);
228
+ }
229
+
230
+ /************************************************************************
231
+ * Code stream error correction
232
+ *
233
+ * Generator polynomial for GF(2^8) is x^8 + x^4 + x^3 + x^2 + 1
234
+ */
235
+
236
+ static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
237
+ {
238
+ int nonzero = 0;
239
+ int i;
240
+
241
+ memset(s, 0, MAX_POLY);
242
+
243
+ for (i = 0; i < npar; i++) {
244
+ int j;
245
+
246
+ for (j = 0; j < bs; j++) {
247
+ uint8_t c = data[bs - j - 1];
248
+
249
+ if (!c)
250
+ continue;
251
+
252
+ s[i] ^= gf256_exp[((int)gf256_log[c] +
253
+ i * j) % 255];
254
+ }
255
+
256
+ if (s[i])
257
+ nonzero = 1;
258
+ }
259
+
260
+ return nonzero;
261
+ }
262
+
263
+ static void eloc_poly(uint8_t *omega,
264
+ const uint8_t *s, const uint8_t *sigma,
265
+ int npar)
266
+ {
267
+ int i;
268
+
269
+ memset(omega, 0, MAX_POLY);
270
+
271
+ for (i = 0; i < npar; i++) {
272
+ const uint8_t a = sigma[i];
273
+ const uint8_t log_a = gf256_log[a];
274
+ int j;
275
+
276
+ if (!a)
277
+ continue;
278
+
279
+ for (j = 0; j + 1 < MAX_POLY; j++) {
280
+ const uint8_t b = s[j + 1];
281
+
282
+ if (i + j >= npar)
283
+ break;
284
+
285
+ if (!b)
286
+ continue;
287
+
288
+ omega[i + j] ^=
289
+ gf256_exp[(log_a + gf256_log[b]) % 255];
290
+ }
291
+ }
292
+ }
293
+
294
+ static quirc_decode_error_t correct_block(uint8_t *data,
295
+ const struct quirc_rs_params *ecc)
296
+ {
297
+ int npar = ecc->bs - ecc->dw;
298
+ uint8_t s[MAX_POLY];
299
+ uint8_t sigma[MAX_POLY];
300
+ uint8_t sigma_deriv[MAX_POLY];
301
+ uint8_t omega[MAX_POLY];
302
+ int i;
303
+
304
+ /* Compute syndrome vector */
305
+ if (!block_syndromes(data, ecc->bs, npar, s))
306
+ return QUIRC_SUCCESS;
307
+
308
+ berlekamp_massey(s, npar, &gf256, sigma);
309
+
310
+ /* Compute derivative of sigma */
311
+ memset(sigma_deriv, 0, MAX_POLY);
312
+ for (i = 0; i + 1 < MAX_POLY; i += 2)
313
+ sigma_deriv[i] = sigma[i + 1];
314
+
315
+ /* Compute error evaluator polynomial */
316
+ eloc_poly(omega, s, sigma, npar - 1);
317
+
318
+ /* Find error locations and magnitudes */
319
+ for (i = 0; i < ecc->bs; i++) {
320
+ uint8_t xinv = gf256_exp[255 - i];
321
+
322
+ if (!poly_eval(sigma, xinv, &gf256)) {
323
+ uint8_t sd_x = poly_eval(sigma_deriv, xinv, &gf256);
324
+ uint8_t omega_x = poly_eval(omega, xinv, &gf256);
325
+ uint8_t error = gf256_exp[(255 - gf256_log[sd_x] +
326
+ gf256_log[omega_x]) % 255];
327
+
328
+ data[ecc->bs - i - 1] ^= error;
329
+ }
330
+ }
331
+
332
+ if (block_syndromes(data, ecc->bs, npar, s))
333
+ return QUIRC_ERROR_DATA_ECC;
334
+
335
+ return QUIRC_SUCCESS;
336
+ }
337
+
338
+ /************************************************************************
339
+ * Format value error correction
340
+ *
341
+ * Generator polynomial for GF(2^4) is x^4 + x + 1
342
+ */
343
+
344
+ #define FORMAT_MAX_ERROR 3
345
+ #define FORMAT_SYNDROMES (FORMAT_MAX_ERROR * 2)
346
+ #define FORMAT_BITS 15
347
+
348
+ static int format_syndromes(uint16_t u, uint8_t *s)
349
+ {
350
+ int i;
351
+ int nonzero = 0;
352
+
353
+ memset(s, 0, MAX_POLY);
354
+
355
+ for (i = 0; i < FORMAT_SYNDROMES; i++) {
356
+ int j;
357
+
358
+ s[i] = 0;
359
+ for (j = 0; j < FORMAT_BITS; j++)
360
+ if (u & (1 << j))
361
+ s[i] ^= gf16_exp[((i + 1) * j) % 15];
362
+
363
+ if (s[i])
364
+ nonzero = 1;
365
+ }
366
+
367
+ return nonzero;
368
+ }
369
+
370
+ static quirc_decode_error_t correct_format(uint16_t *f_ret)
371
+ {
372
+ uint16_t u = *f_ret;
373
+ int i;
374
+ uint8_t s[MAX_POLY];
375
+ uint8_t sigma[MAX_POLY];
376
+
377
+ /* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
378
+ * to get S_1 .. S_6 (but we index them from 0).
379
+ */
380
+ if (!format_syndromes(u, s))
381
+ return QUIRC_SUCCESS;
382
+
383
+ berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
384
+
385
+ /* Now, find the roots of the polynomial */
386
+ for (i = 0; i < 15; i++)
387
+ if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
388
+ u ^= (1 << i);
389
+
390
+ if (format_syndromes(u, s))
391
+ return QUIRC_ERROR_FORMAT_ECC;
392
+
393
+ *f_ret = u;
394
+ return QUIRC_SUCCESS;
395
+ }
396
+
397
+ /************************************************************************
398
+ * Decoder algorithm
399
+ */
400
+
401
+ struct datastream {
402
+ uint8_t raw[QUIRC_MAX_PAYLOAD];
403
+ int data_bits;
404
+ int ptr;
405
+
406
+ uint8_t data[QUIRC_MAX_PAYLOAD];
407
+ };
408
+
409
+ static inline int grid_bit(const struct quirc_code *code, int x, int y)
410
+ {
411
+ int p = y * code->size + x;
412
+
413
+ return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
414
+ }
415
+
416
+ static quirc_decode_error_t read_format(const struct quirc_code *code,
417
+ struct quirc_data *data, int which)
418
+ {
419
+ int i;
420
+ uint16_t format = 0;
421
+ uint16_t fdata;
422
+ quirc_decode_error_t err;
423
+
424
+ if (which) {
425
+ for (i = 0; i < 7; i++)
426
+ format = (format << 1) |
427
+ grid_bit(code, 8, code->size - 1 - i);
428
+ for (i = 0; i < 8; i++)
429
+ format = (format << 1) |
430
+ grid_bit(code, code->size - 8 + i, 8);
431
+ } else {
432
+ static const int xs[15] = {
433
+ 8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0
434
+ };
435
+ static const int ys[15] = {
436
+ 0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8
437
+ };
438
+
439
+ for (i = 14; i >= 0; i--)
440
+ format = (format << 1) | grid_bit(code, xs[i], ys[i]);
441
+ }
442
+
443
+ format ^= 0x5412;
444
+
445
+ err = correct_format(&format);
446
+ if (err)
447
+ return err;
448
+
449
+ fdata = format >> 10;
450
+ data->ecc_level = fdata >> 3;
451
+ data->mask = fdata & 7;
452
+
453
+ return QUIRC_SUCCESS;
454
+ }
455
+
456
+ static int mask_bit(int mask, int i, int j)
457
+ {
458
+ switch (mask) {
459
+ case 0: return !((i + j) % 2);
460
+ case 1: return !(i % 2);
461
+ case 2: return !(j % 3);
462
+ case 3: return !((i + j) % 3);
463
+ case 4: return !(((i / 2) + (j / 3)) % 2);
464
+ case 5: return !((i * j) % 2 + (i * j) % 3);
465
+ case 6: return !(((i * j) % 2 + (i * j) % 3) % 2);
466
+ case 7: return !(((i * j) % 3 + (i + j) % 2) % 2);
467
+ }
468
+
469
+ return 0;
470
+ }
471
+
472
+ static int reserved_cell(int version, int i, int j)
473
+ {
474
+ const struct quirc_version_info *ver = &quirc_version_db[version];
475
+ int size = version * 4 + 17;
476
+ int ai = -1, aj = -1, a;
477
+
478
+ /* Finder + format: top left */
479
+ if (i < 9 && j < 9)
480
+ return 1;
481
+
482
+ /* Finder + format: bottom left */
483
+ if (i + 8 >= size && j < 9)
484
+ return 1;
485
+
486
+ /* Finder + format: top right */
487
+ if (i < 9 && j + 8 >= size)
488
+ return 1;
489
+
490
+ /* Exclude timing patterns */
491
+ if (i == 6 || j == 6)
492
+ return 1;
493
+
494
+ /* Exclude version info, if it exists. Version info sits adjacent to
495
+ * the top-right and bottom-left finders in three rows, bounded by
496
+ * the timing pattern.
497
+ */
498
+ if (version >= 7) {
499
+ if (i < 6 && j + 11 >= size)
500
+ return 1;
501
+ if (i + 11 >= size && j < 6)
502
+ return 1;
503
+ }
504
+
505
+ /* Exclude alignment patterns */
506
+ for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++) {
507
+ int p = ver->apat[a];
508
+
509
+ if (abs(p - i) < 3)
510
+ ai = a;
511
+ if (abs(p - j) < 3)
512
+ aj = a;
513
+ }
514
+
515
+ if (ai >= 0 && aj >= 0) {
516
+ a--;
517
+ if (ai > 0 && ai < a)
518
+ return 1;
519
+ if (aj > 0 && aj < a)
520
+ return 1;
521
+ if (aj == a && ai == a)
522
+ return 1;
523
+ }
524
+
525
+ return 0;
526
+ }
527
+
528
+ static void read_bit(const struct quirc_code *code,
529
+ struct quirc_data *data,
530
+ struct datastream *ds, int i, int j)
531
+ {
532
+ int bitpos = ds->data_bits & 7;
533
+ int bytepos = ds->data_bits >> 3;
534
+ int v = grid_bit(code, j, i);
535
+
536
+ if (mask_bit(data->mask, i, j))
537
+ v ^= 1;
538
+
539
+ if (v)
540
+ ds->raw[bytepos] |= (0x80 >> bitpos);
541
+
542
+ ds->data_bits++;
543
+ }
544
+
545
+ static void read_data(const struct quirc_code *code,
546
+ struct quirc_data *data,
547
+ struct datastream *ds)
548
+ {
549
+ int y = code->size - 1;
550
+ int x = code->size - 1;
551
+ int dir = -1;
552
+
553
+ while (x > 0) {
554
+ if (x == 6)
555
+ x--;
556
+
557
+ if (!reserved_cell(data->version, y, x))
558
+ read_bit(code, data, ds, y, x);
559
+
560
+ if (!reserved_cell(data->version, y, x - 1))
561
+ read_bit(code, data, ds, y, x - 1);
562
+
563
+ y += dir;
564
+ if (y < 0 || y >= code->size) {
565
+ dir = -dir;
566
+ x -= 2;
567
+ y += dir;
568
+ }
569
+ }
570
+ }
571
+
572
+ static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
573
+ struct datastream *ds)
574
+ {
575
+ const struct quirc_version_info *ver =
576
+ &quirc_version_db[data->version];
577
+ const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
578
+ struct quirc_rs_params lb_ecc;
579
+ const int lb_count =
580
+ (ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
581
+ const int bc = lb_count + sb_ecc->ns;
582
+ const int ecc_offset = sb_ecc->dw * bc + lb_count;
583
+ int dst_offset = 0;
584
+ int i;
585
+
586
+ memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
587
+ lb_ecc.dw++;
588
+ lb_ecc.bs++;
589
+
590
+ for (i = 0; i < bc; i++) {
591
+ uint8_t *dst = ds->data + dst_offset;
592
+ const struct quirc_rs_params *ecc =
593
+ (i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
594
+ const int num_ec = ecc->bs - ecc->dw;
595
+ quirc_decode_error_t err;
596
+ int j;
597
+
598
+ for (j = 0; j < ecc->dw; j++)
599
+ dst[j] = ds->raw[j * bc + i];
600
+ for (j = 0; j < num_ec; j++)
601
+ dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
602
+
603
+ err = correct_block(dst, ecc);
604
+ if (err)
605
+ return err;
606
+
607
+ dst_offset += ecc->dw;
608
+ }
609
+
610
+ ds->data_bits = dst_offset * 8;
611
+
612
+ return QUIRC_SUCCESS;
613
+ }
614
+
615
+ static inline int bits_remaining(const struct datastream *ds)
616
+ {
617
+ return ds->data_bits - ds->ptr;
618
+ }
619
+
620
+ static int take_bits(struct datastream *ds, int len)
621
+ {
622
+ int ret = 0;
623
+
624
+ while (len && (ds->ptr < ds->data_bits)) {
625
+ uint8_t b = ds->data[ds->ptr >> 3];
626
+ int bitpos = ds->ptr & 7;
627
+
628
+ ret <<= 1;
629
+ if ((b << bitpos) & 0x80)
630
+ ret |= 1;
631
+
632
+ ds->ptr++;
633
+ len--;
634
+ }
635
+
636
+ return ret;
637
+ }
638
+
639
+ static int numeric_tuple(struct quirc_data *data,
640
+ struct datastream *ds,
641
+ int bits, int digits)
642
+ {
643
+ int tuple;
644
+ int i;
645
+
646
+ if (bits_remaining(ds) < bits)
647
+ return -1;
648
+
649
+ tuple = take_bits(ds, bits);
650
+
651
+ for (i = digits - 1; i >= 0; i--) {
652
+ data->payload[data->payload_len + i] = tuple % 10 + '0';
653
+ tuple /= 10;
654
+ }
655
+
656
+ data->payload_len += digits;
657
+ return 0;
658
+ }
659
+
660
+ static quirc_decode_error_t decode_numeric(struct quirc_data *data,
661
+ struct datastream *ds)
662
+ {
663
+ int bits = 14;
664
+ int count;
665
+
666
+ if (data->version < 10)
667
+ bits = 10;
668
+ else if (data->version < 27)
669
+ bits = 12;
670
+
671
+ count = take_bits(ds, bits);
672
+ if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
673
+ return QUIRC_ERROR_DATA_OVERFLOW;
674
+
675
+ while (count >= 3) {
676
+ if (numeric_tuple(data, ds, 10, 3) < 0)
677
+ return QUIRC_ERROR_DATA_UNDERFLOW;
678
+ count -= 3;
679
+ }
680
+
681
+ if (count >= 2) {
682
+ if (numeric_tuple(data, ds, 7, 2) < 0)
683
+ return QUIRC_ERROR_DATA_UNDERFLOW;
684
+ count -= 2;
685
+ }
686
+
687
+ if (count) {
688
+ if (numeric_tuple(data, ds, 4, 1) < 0)
689
+ return QUIRC_ERROR_DATA_UNDERFLOW;
690
+ count--;
691
+ }
692
+
693
+ return QUIRC_SUCCESS;
694
+ }
695
+
696
+ static int alpha_tuple(struct quirc_data *data,
697
+ struct datastream *ds,
698
+ int bits, int digits)
699
+ {
700
+ int tuple;
701
+ int i;
702
+
703
+ if (bits_remaining(ds) < bits)
704
+ return -1;
705
+
706
+ tuple = take_bits(ds, bits);
707
+
708
+ for (i = 0; i < digits; i++) {
709
+ static const char *alpha_map =
710
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
711
+
712
+ data->payload[data->payload_len + digits - i - 1] =
713
+ alpha_map[tuple % 45];
714
+ tuple /= 45;
715
+ }
716
+
717
+ data->payload_len += digits;
718
+ return 0;
719
+ }
720
+
721
+ static quirc_decode_error_t decode_alpha(struct quirc_data *data,
722
+ struct datastream *ds)
723
+ {
724
+ int bits = 13;
725
+ int count;
726
+
727
+ if (data->version < 10)
728
+ bits = 9;
729
+ else if (data->version < 27)
730
+ bits = 11;
731
+
732
+ count = take_bits(ds, bits);
733
+ if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
734
+ return QUIRC_ERROR_DATA_OVERFLOW;
735
+
736
+ while (count >= 2) {
737
+ if (alpha_tuple(data, ds, 11, 2) < 0)
738
+ return QUIRC_ERROR_DATA_UNDERFLOW;
739
+ count -= 2;
740
+ }
741
+
742
+ if (count) {
743
+ if (alpha_tuple(data, ds, 6, 1) < 0)
744
+ return QUIRC_ERROR_DATA_UNDERFLOW;
745
+ count--;
746
+ }
747
+
748
+ return QUIRC_SUCCESS;
749
+ }
750
+
751
+ static quirc_decode_error_t decode_byte(struct quirc_data *data,
752
+ struct datastream *ds)
753
+ {
754
+ int bits = 16;
755
+ int count;
756
+ int i;
757
+
758
+ if (data->version < 10)
759
+ bits = 8;
760
+
761
+ count = take_bits(ds, bits);
762
+ if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
763
+ return QUIRC_ERROR_DATA_OVERFLOW;
764
+ if (bits_remaining(ds) < count * 8)
765
+ return QUIRC_ERROR_DATA_UNDERFLOW;
766
+
767
+ for (i = 0; i < count; i++)
768
+ data->payload[data->payload_len++] = take_bits(ds, 8);
769
+
770
+ return QUIRC_SUCCESS;
771
+ }
772
+
773
+ static quirc_decode_error_t decode_kanji(struct quirc_data *data,
774
+ struct datastream *ds)
775
+ {
776
+ int bits = 12;
777
+ int count;
778
+ int i;
779
+
780
+ if (data->version < 10)
781
+ bits = 8;
782
+ else if (data->version < 27)
783
+ bits = 10;
784
+
785
+ count = take_bits(ds, bits);
786
+ if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD)
787
+ return QUIRC_ERROR_DATA_OVERFLOW;
788
+ if (bits_remaining(ds) < count * 13)
789
+ return QUIRC_ERROR_DATA_UNDERFLOW;
790
+
791
+ for (i = 0; i < count; i++) {
792
+ int d = take_bits(ds, 13);
793
+ uint16_t sjw;
794
+
795
+ if (d + 0x8140 >= 0x9ffc)
796
+ sjw = d + 0x8140;
797
+ else
798
+ sjw = d + 0xc140;
799
+
800
+ data->payload[data->payload_len++] = sjw >> 8;
801
+ data->payload[data->payload_len++] = sjw & 0xff;
802
+ }
803
+
804
+ return QUIRC_SUCCESS;
805
+ }
806
+
807
+ static quirc_decode_error_t decode_eci(struct quirc_data *data,
808
+ struct datastream *ds)
809
+ {
810
+ if (bits_remaining(ds) < 8)
811
+ return QUIRC_ERROR_DATA_UNDERFLOW;
812
+
813
+ data->eci = take_bits(ds, 8);
814
+
815
+ if ((data->eci & 0xc0) == 0x80) {
816
+ if (bits_remaining(ds) < 8)
817
+ return QUIRC_ERROR_DATA_UNDERFLOW;
818
+
819
+ data->eci = (data->eci << 8) | take_bits(ds, 8);
820
+ } else if ((data->eci & 0xe0) == 0xc0) {
821
+ if (bits_remaining(ds) < 16)
822
+ return QUIRC_ERROR_DATA_UNDERFLOW;
823
+
824
+ data->eci = (data->eci << 16) | take_bits(ds, 16);
825
+ }
826
+
827
+ return QUIRC_SUCCESS;
828
+ }
829
+
830
+ static quirc_decode_error_t decode_payload(struct quirc_data *data,
831
+ struct datastream *ds)
832
+ {
833
+ while (bits_remaining(ds) >= 4) {
834
+ quirc_decode_error_t err = QUIRC_SUCCESS;
835
+ int type = take_bits(ds, 4);
836
+
837
+ switch (type) {
838
+ case QUIRC_DATA_TYPE_NUMERIC:
839
+ err = decode_numeric(data, ds);
840
+ break;
841
+
842
+ case QUIRC_DATA_TYPE_ALPHA:
843
+ err = decode_alpha(data, ds);
844
+ break;
845
+
846
+ case QUIRC_DATA_TYPE_BYTE:
847
+ err = decode_byte(data, ds);
848
+ break;
849
+
850
+ case QUIRC_DATA_TYPE_KANJI:
851
+ err = decode_kanji(data, ds);
852
+ break;
853
+
854
+ case 7:
855
+ err = decode_eci(data, ds);
856
+ break;
857
+
858
+ default:
859
+ goto done;
860
+ }
861
+
862
+ if (err)
863
+ return err;
864
+
865
+ if (!(type & (type - 1)) && (type > data->data_type))
866
+ data->data_type = type;
867
+ }
868
+ done:
869
+
870
+ /* Add nul terminator to all payloads */
871
+ if (data->payload_len >= sizeof(data->payload))
872
+ data->payload_len--;
873
+ data->payload[data->payload_len] = 0;
874
+
875
+ return QUIRC_SUCCESS;
876
+ }
877
+
878
+ quirc_decode_error_t quirc_decode(const struct quirc_code *code,
879
+ struct quirc_data *data)
880
+ {
881
+ quirc_decode_error_t err;
882
+ struct datastream ds;
883
+
884
+ if ((code->size - 17) % 4)
885
+ return QUIRC_ERROR_INVALID_GRID_SIZE;
886
+
887
+ memset(data, 0, sizeof(*data));
888
+ memset(&ds, 0, sizeof(ds));
889
+
890
+ data->version = (code->size - 17) / 4;
891
+
892
+ if (data->version < 1 ||
893
+ data->version > QUIRC_MAX_VERSION)
894
+ return QUIRC_ERROR_INVALID_VERSION;
895
+
896
+ /* Read format information -- try both locations */
897
+ err = read_format(code, data, 0);
898
+ if (err)
899
+ err = read_format(code, data, 1);
900
+ if (err)
901
+ return err;
902
+
903
+ read_data(code, data, &ds);
904
+ err = codestream_ecc(data, &ds);
905
+ if (err)
906
+ return err;
907
+
908
+ err = decode_payload(data, &ds);
909
+ if (err)
910
+ return err;
911
+
912
+ return QUIRC_SUCCESS;
913
+ }