quirc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ }