Line data Source code
1 : /*
2 : * liblierre - decode_qr.c
3 : *
4 : * This file is part of liblierre.
5 : *
6 : * Author: Go Kudo <zeriyoshi@gmail.com>
7 : * SPDX-License-Identifier: MIT AND ISC
8 : *
9 : * This file contains code derived from quirc (https://github.com/dlbeer/quirc).
10 : * Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
11 : * Licensed under the ISC License.
12 : */
13 :
14 : #include <poporon.h>
15 :
16 : #include "../internal/decoder.h"
17 :
18 : #define FORMAT_BITS_COUNT 15
19 : #define FORMAT_XOR_MASK 0x5412
20 : #define FORMAT_DATA_SHIFT 10
21 : #define FORMAT_ECC_LEVEL_SHIFT 3
22 : #define FORMAT_MASK_BITS 7
23 :
24 : #define FORMAT_BCH_SYMBOL_SIZE 4
25 : #define FORMAT_BCH_GEN_POLY 0x13
26 : #define FORMAT_BCH_CORRECTION_T 3
27 :
28 : #define FINDER_PATTERN_SIZE 7
29 : #define FINDER_EDGE_SIZE 8
30 : #define FINDER_CENTER 9
31 : #define TIMING_PATTERN_POSITION 6
32 : #define VERSION_INFO_OFFSET 11
33 : #define VERSION_INFO_SIZE 6
34 : #define QR_VERSION1_SIZE 17
35 : #define LIERRE_QR_VERSION_INFO_MIN 7
36 :
37 : #define MODE_NUMERIC 1
38 : #define MODE_ALPHANUMERIC 2
39 : #define MODE_BYTE 4
40 : #define MODE_ECI 7
41 : #define MODE_KANJI 8
42 :
43 : #define ALPHANUMERIC_CHARSET_SIZE 45
44 :
45 : #define KANJI_ENCODE_DIVISOR 0xc0
46 : #define KANJI_SJIS_BASE1 0x8140
47 : #define KANJI_SJIS_BOUNDARY 0x9ffc
48 : #define KANJI_SJIS_BASE2 0xc140
49 :
50 : #define VERSION_THRESHOLD_SMALL 10
51 : #define VERSION_THRESHOLD_MEDIUM 27
52 :
53 : #define NUMERIC_BITS_SMALL 10
54 : #define NUMERIC_BITS_MEDIUM 12
55 : #define NUMERIC_BITS_LARGE 14
56 :
57 : #define ALPHA_BITS_SMALL 9
58 : #define ALPHA_BITS_MEDIUM 11
59 : #define ALPHA_BITS_LARGE 13
60 : #define BYTE_BITS_SMALL 8
61 : #define BYTE_BITS_LARGE 16
62 : #define KANJI_BITS_SMALL 8
63 : #define KANJI_BITS_MEDIUM 10
64 : #define KANJI_BITS_LARGE 12
65 : #define KANJI_ENCODED_BITS 13
66 :
67 984050 : static inline int32_t grid_bit(const qr_code_t *code, int32_t x, int32_t y)
68 : {
69 : int32_t bit_position;
70 :
71 984050 : bit_position = y * code->size + x;
72 984050 : return (code->cell_bitmap[bit_position >> 3] >> (bit_position & 7)) & 1;
73 : }
74 :
75 138 : static inline lierre_error_t correct_format_bits(uint16_t *format_bits)
76 : {
77 : poporon_config_t *config;
78 : poporon_t *pprn;
79 : uint8_t data[1], parity[2];
80 : size_t corrected;
81 :
82 138 : config = poporon_bch_config_create(FORMAT_BCH_SYMBOL_SIZE, FORMAT_BCH_GEN_POLY, FORMAT_BCH_CORRECTION_T);
83 138 : if (!config) {
84 0 : return LIERRE_ERROR_FORMAT_ECC;
85 : }
86 :
87 138 : pprn = poporon_create(config);
88 138 : if (!pprn) {
89 0 : poporon_config_destroy(config);
90 0 : return LIERRE_ERROR_FORMAT_ECC;
91 : }
92 :
93 138 : data[0] = (uint8_t)((*format_bits >> 10) & 0x1F);
94 138 : parity[0] = (uint8_t)((*format_bits >> 8) & 0x03);
95 138 : parity[1] = (uint8_t)(*format_bits & 0xFF);
96 :
97 138 : if (!poporon_decode(pprn, data, 1, parity, &corrected)) {
98 15 : poporon_destroy(pprn);
99 15 : poporon_config_destroy(config);
100 15 : return LIERRE_ERROR_FORMAT_ECC;
101 : }
102 :
103 123 : poporon_destroy(pprn);
104 123 : poporon_config_destroy(config);
105 :
106 123 : *format_bits = (uint16_t)((data[0] << 10) | (parity[0] << 8) | parity[1]);
107 :
108 123 : return LIERRE_ERROR_SUCCESS;
109 : }
110 :
111 138 : static inline lierre_error_t read_format(const qr_code_t *code, qr_data_t *data, int32_t use_secondary)
112 : {
113 : static const int32_t primary_x_positions[FORMAT_BITS_COUNT] = {8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0},
114 : primary_y_positions[FORMAT_BITS_COUNT] = {0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8};
115 : lierre_error_t err;
116 : uint16_t format_bits, format_data;
117 : int32_t i;
118 :
119 138 : format_bits = 0;
120 :
121 138 : if (use_secondary) {
122 72 : for (i = 0; i < FINDER_PATTERN_SIZE; i++) {
123 63 : format_bits = (uint16_t)((format_bits << 1) | grid_bit(code, FINDER_EDGE_SIZE, code->size - 1 - i));
124 : }
125 :
126 81 : for (i = 0; i < FINDER_EDGE_SIZE; i++) {
127 72 : format_bits =
128 72 : (uint16_t)((format_bits << 1) | grid_bit(code, code->size - FINDER_EDGE_SIZE + i, FINDER_EDGE_SIZE));
129 : }
130 : } else {
131 2064 : for (i = FORMAT_BITS_COUNT - 1; i >= 0; i--) {
132 1935 : format_bits =
133 1935 : (uint16_t)((format_bits << 1) | grid_bit(code, primary_x_positions[i], primary_y_positions[i]));
134 : }
135 : }
136 :
137 138 : format_bits ^= FORMAT_XOR_MASK;
138 :
139 138 : err = correct_format_bits(&format_bits);
140 138 : if (err) {
141 15 : return err;
142 : }
143 :
144 123 : format_data = (uint16_t)(format_bits >> FORMAT_DATA_SHIFT);
145 123 : data->ecc_level = format_data >> FORMAT_ECC_LEVEL_SHIFT;
146 123 : data->mask = format_data & FORMAT_MASK_BITS;
147 :
148 123 : return LIERRE_ERROR_SUCCESS;
149 : }
150 :
151 981640 : static inline int32_t mask_bit(int32_t mask_pattern, int32_t row, int32_t col)
152 : {
153 981640 : switch (mask_pattern) {
154 100916 : case 0:
155 100916 : return !((row + col) % 2);
156 49805 : case 1:
157 49805 : return !(row % 2);
158 214240 : case 2:
159 214240 : return !(col % 3);
160 279855 : case 3:
161 279855 : return !((row + col) % 3);
162 160433 : case 4:
163 160433 : return !(((row / 2) + (col / 3)) % 2);
164 42821 : case 5:
165 42821 : return !((row * col) % 2 + (row * col) % 3);
166 80100 : case 6:
167 80100 : return !(((row * col) % 2 + (row * col) % 3) % 2);
168 61921 : case 7:
169 61921 : return !(((row * col) % 3 + (row + col) % 2) % 2);
170 : }
171 :
172 0 : return 0;
173 : }
174 :
175 1058467 : static inline int32_t is_reserved_cell(int32_t version, int32_t row, int32_t col)
176 : {
177 : const version_info_t *version_info;
178 : int32_t size, alignment_row_idx, alignment_col_idx, alignment_idx, pos;
179 :
180 1058467 : version_info = &lierre_version_db[version];
181 1058467 : size = version * 4 + QR_VERSION1_SIZE;
182 1058467 : alignment_row_idx = -1;
183 1058467 : alignment_col_idx = -1;
184 :
185 1058467 : if (row < FINDER_CENTER && col < FINDER_CENTER) {
186 8831 : return 1;
187 : }
188 :
189 1049636 : if (row + FINDER_EDGE_SIZE >= size && col < FINDER_CENTER) {
190 7857 : return 1;
191 : }
192 :
193 1041779 : if (row < FINDER_CENTER && col + FINDER_EDGE_SIZE >= size) {
194 8856 : return 1;
195 : }
196 :
197 1032923 : if (row == TIMING_PATTERN_POSITION || col == TIMING_PATTERN_POSITION) {
198 7804 : return 1;
199 : }
200 :
201 1025119 : if (version >= LIERRE_QR_VERSION_INFO_MIN) {
202 999295 : if (row < TIMING_PATTERN_POSITION && col + VERSION_INFO_OFFSET >= size) {
203 1386 : return 1;
204 : }
205 :
206 997909 : if (row + VERSION_INFO_OFFSET >= size && col < TIMING_PATTERN_POSITION) {
207 1383 : return 1;
208 : }
209 : }
210 :
211 6727415 : for (alignment_idx = 0; alignment_idx < LIERRE_DECODER_MAX_ALIGNMENT && version_info->apat[alignment_idx];
212 5705065 : alignment_idx++) {
213 5705065 : pos = version_info->apat[alignment_idx];
214 :
215 5705065 : if ((pos - row) >= -2 && (pos - row) <= 2) {
216 212914 : alignment_row_idx = alignment_idx;
217 : }
218 :
219 5705065 : if ((pos - col) >= -2 && (pos - col) <= 2) {
220 212940 : alignment_col_idx = alignment_idx;
221 : }
222 : }
223 :
224 1022350 : if (alignment_row_idx >= 0 && alignment_col_idx >= 0) {
225 42920 : alignment_idx--;
226 :
227 42920 : if (alignment_row_idx > 0 && alignment_row_idx < alignment_idx) {
228 29799 : return 1;
229 : }
230 :
231 13121 : if (alignment_col_idx > 0 && alignment_col_idx < alignment_idx) {
232 10035 : return 1;
233 : }
234 :
235 3086 : if (alignment_col_idx == alignment_idx && alignment_row_idx == alignment_idx) {
236 2575 : return 1;
237 : }
238 : }
239 :
240 979941 : return 0;
241 : }
242 :
243 982413 : static inline void read_bit(const qr_code_t *code, qr_data_t *data, datastream_t *ds, int32_t row, int32_t col)
244 : {
245 : int32_t bit_offset, byte_offset, value;
246 :
247 982413 : bit_offset = ds->data_bits & 7;
248 982413 : byte_offset = ds->data_bits >> 3;
249 982413 : value = grid_bit(code, col, row);
250 :
251 982138 : if (mask_bit(data->mask, row, col)) {
252 419024 : value ^= 1;
253 : }
254 :
255 981628 : if (value) {
256 489722 : ds->raw[byte_offset] |= (0x80 >> bit_offset);
257 : }
258 :
259 981628 : ds->data_bits++;
260 981628 : }
261 :
262 123 : static inline void read_data(const qr_code_t *code, qr_data_t *data, datastream_t *ds)
263 : {
264 : int32_t row, col, direction;
265 :
266 123 : row = code->size - 1;
267 123 : col = code->size - 1;
268 123 : direction = -1;
269 :
270 533085 : while (col > 0) {
271 532990 : if (col == 6) {
272 123 : col--;
273 : }
274 :
275 532990 : if (!is_reserved_cell(data->version, row, col)) {
276 490365 : read_bit(code, data, ds, row, col);
277 : }
278 :
279 532320 : if (!is_reserved_cell(data->version, row, col - 1)) {
280 498360 : read_bit(code, data, ds, row, col - 1);
281 : }
282 :
283 532962 : row += direction;
284 532962 : if (row < 0 || row >= code->size) {
285 4801 : direction = -direction;
286 4801 : col -= 2;
287 4801 : row += direction;
288 : }
289 : }
290 95 : }
291 :
292 1565 : static inline lierre_error_t correct_block_with_poporon(uint8_t *block_data, const rs_params_t *ecc_params)
293 : {
294 : poporon_t *rs_decoder;
295 : poporon_config_t *config;
296 : int32_t parity_bytes;
297 : size_t corrected;
298 : bool success;
299 :
300 1565 : parity_bytes = ecc_params->bs - ecc_params->dw;
301 :
302 1565 : config = poporon_rs_config_create(8, 0x11D, 0, 1, (uint8_t)parity_bytes, NULL, NULL);
303 1565 : if (!config) {
304 0 : return LIERRE_ERROR_DATA_ECC;
305 : }
306 :
307 1565 : rs_decoder = poporon_create(config);
308 1565 : if (!rs_decoder) {
309 0 : poporon_config_destroy(config);
310 0 : return LIERRE_ERROR_DATA_ECC;
311 : }
312 :
313 1565 : success = poporon_decode(rs_decoder, block_data, (size_t)ecc_params->dw, &block_data[ecc_params->dw], &corrected);
314 1565 : poporon_destroy(rs_decoder);
315 1565 : poporon_config_destroy(config);
316 :
317 1565 : if (!success) {
318 19 : return LIERRE_ERROR_DATA_ECC;
319 : }
320 :
321 1546 : return LIERRE_ERROR_SUCCESS;
322 : }
323 :
324 123 : static inline lierre_error_t codestream_ecc(qr_data_t *data, datastream_t *ds)
325 : {
326 : const version_info_t *version_info;
327 : const rs_params_t *short_block_ecc, *current_ecc;
328 : rs_params_t long_block_ecc;
329 : lierre_error_t err;
330 : uint8_t *dst;
331 : int32_t long_block_count, total_blocks, ecc_offset, dst_offset, block_idx, byte_idx, parity_count;
332 :
333 123 : version_info = &lierre_version_db[data->version];
334 123 : short_block_ecc = &version_info->ecc[data->ecc_level];
335 123 : long_block_count =
336 123 : (version_info->data_bytes - short_block_ecc->bs * short_block_ecc->ns) / (short_block_ecc->bs + 1);
337 123 : total_blocks = long_block_count + short_block_ecc->ns;
338 123 : ecc_offset = short_block_ecc->dw * total_blocks + long_block_count;
339 123 : dst_offset = 0;
340 :
341 123 : lmemcpy(&long_block_ecc, short_block_ecc, sizeof(long_block_ecc));
342 123 : long_block_ecc.dw++;
343 123 : long_block_ecc.bs++;
344 :
345 1669 : for (block_idx = 0; block_idx < total_blocks; block_idx++) {
346 1565 : dst = ds->data + dst_offset;
347 1565 : current_ecc = (block_idx < short_block_ecc->ns) ? short_block_ecc : &long_block_ecc;
348 1565 : parity_count = current_ecc->bs - current_ecc->dw;
349 :
350 72522 : for (byte_idx = 0; byte_idx < current_ecc->dw; byte_idx++) {
351 70957 : dst[byte_idx] = ds->raw[byte_idx * total_blocks + block_idx];
352 : }
353 :
354 43850 : for (byte_idx = 0; byte_idx < parity_count; byte_idx++) {
355 42285 : dst[current_ecc->dw + byte_idx] = ds->raw[ecc_offset + byte_idx * total_blocks + block_idx];
356 : }
357 :
358 1565 : err = correct_block_with_poporon(dst, current_ecc);
359 1565 : if (err) {
360 19 : return err;
361 : }
362 :
363 1546 : dst_offset += current_ecc->dw;
364 : }
365 :
366 104 : ds->data_bits = dst_offset * 8;
367 :
368 104 : return LIERRE_ERROR_SUCCESS;
369 : }
370 :
371 345 : static inline int32_t bits_remaining(const datastream_t *ds)
372 : {
373 345 : return ds->data_bits - ds->ptr;
374 : }
375 :
376 65676 : static inline int32_t take_bits(datastream_t *ds, int32_t count)
377 : {
378 : int32_t result, bit_position;
379 : uint8_t byte_value;
380 :
381 65676 : result = 0;
382 :
383 590856 : while (count && (ds->ptr < ds->data_bits)) {
384 525180 : byte_value = ds->data[ds->ptr >> 3];
385 525180 : bit_position = ds->ptr & 7;
386 :
387 525180 : result <<= 1;
388 525180 : if ((byte_value << bit_position) & 0x80) {
389 261536 : result |= 1;
390 : }
391 :
392 525180 : ds->ptr++;
393 525180 : count--;
394 : }
395 :
396 65676 : return result;
397 : }
398 :
399 21 : static inline int32_t decode_numeric_tuple(qr_data_t *data, datastream_t *ds, int32_t bits, int32_t digits)
400 : {
401 : int32_t value, i;
402 :
403 21 : if (bits_remaining(ds) < bits) {
404 0 : return -1;
405 : }
406 :
407 21 : value = take_bits(ds, bits);
408 :
409 81 : for (i = digits - 1; i >= 0; i--) {
410 60 : data->payload[data->payload_len + i] = (uint8_t)(value % 10 + '0');
411 60 : value /= 10;
412 : }
413 :
414 21 : data->payload_len += digits;
415 :
416 21 : return 0;
417 : }
418 :
419 2 : static inline lierre_error_t decode_numeric(qr_data_t *data, datastream_t *ds)
420 : {
421 : int32_t count_bits, char_count;
422 :
423 2 : count_bits = NUMERIC_BITS_LARGE;
424 :
425 2 : if (data->version < VERSION_THRESHOLD_SMALL) {
426 2 : count_bits = NUMERIC_BITS_SMALL;
427 0 : } else if (data->version < VERSION_THRESHOLD_MEDIUM) {
428 0 : count_bits = NUMERIC_BITS_MEDIUM;
429 : }
430 :
431 2 : char_count = take_bits(ds, count_bits);
432 2 : if (data->payload_len + char_count + 1 > LIERRE_DECODER_MAX_PAYLOAD) {
433 0 : return LIERRE_ERROR_DATA_OVERFLOW;
434 : }
435 :
436 21 : while (char_count >= 3) {
437 19 : if (decode_numeric_tuple(data, ds, 10, 3) < 0) {
438 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
439 : }
440 :
441 19 : char_count -= 3;
442 : }
443 :
444 2 : if (char_count >= 2) {
445 1 : if (decode_numeric_tuple(data, ds, 7, 2) < 0) {
446 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
447 : }
448 :
449 1 : char_count -= 2;
450 : }
451 :
452 2 : if (char_count) {
453 1 : if (decode_numeric_tuple(data, ds, 4, 1) < 0) {
454 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
455 : }
456 : }
457 :
458 2 : return LIERRE_ERROR_SUCCESS;
459 : }
460 :
461 14 : static inline int32_t decode_alpha_tuple(qr_data_t *data, datastream_t *ds, int32_t bits, int32_t digits)
462 : {
463 : static const char *ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
464 : int32_t value, i;
465 :
466 14 : if (bits_remaining(ds) < bits) {
467 0 : return -1;
468 : }
469 :
470 14 : value = take_bits(ds, bits);
471 :
472 40 : for (i = 0; i < digits; i++) {
473 26 : data->payload[data->payload_len + digits - i - 1] =
474 26 : (uint8_t)ALPHANUMERIC_CHARSET[value % ALPHANUMERIC_CHARSET_SIZE];
475 26 : value /= ALPHANUMERIC_CHARSET_SIZE;
476 : }
477 :
478 14 : data->payload_len += digits;
479 :
480 14 : return 0;
481 : }
482 :
483 2 : static inline lierre_error_t decode_alpha(qr_data_t *data, datastream_t *ds)
484 : {
485 : int32_t count_bits, char_count;
486 :
487 2 : count_bits = ALPHA_BITS_LARGE;
488 :
489 2 : if (data->version < VERSION_THRESHOLD_SMALL) {
490 2 : count_bits = ALPHA_BITS_SMALL;
491 0 : } else if (data->version < VERSION_THRESHOLD_MEDIUM) {
492 0 : count_bits = ALPHA_BITS_MEDIUM;
493 : }
494 :
495 2 : char_count = take_bits(ds, count_bits);
496 2 : if (data->payload_len + char_count + 1 > LIERRE_DECODER_MAX_PAYLOAD) {
497 0 : return LIERRE_ERROR_DATA_OVERFLOW;
498 : }
499 :
500 14 : while (char_count >= 2) {
501 12 : if (decode_alpha_tuple(data, ds, 11, 2) < 0) {
502 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
503 : }
504 :
505 12 : char_count -= 2;
506 : }
507 :
508 2 : if (char_count) {
509 2 : if (decode_alpha_tuple(data, ds, 6, 1) < 0) {
510 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
511 : }
512 : }
513 :
514 2 : return LIERRE_ERROR_SUCCESS;
515 : }
516 :
517 98 : static inline lierre_error_t decode_byte(qr_data_t *data, datastream_t *ds)
518 : {
519 : int32_t count_bits, char_count, i;
520 :
521 98 : count_bits = BYTE_BITS_LARGE;
522 :
523 98 : if (data->version < VERSION_THRESHOLD_SMALL) {
524 34 : count_bits = BYTE_BITS_SMALL;
525 : }
526 :
527 98 : char_count = take_bits(ds, count_bits);
528 98 : if (data->payload_len + char_count + 1 > LIERRE_DECODER_MAX_PAYLOAD) {
529 0 : return LIERRE_ERROR_DATA_OVERFLOW;
530 : }
531 :
532 98 : if (bits_remaining(ds) < char_count * 8) {
533 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
534 : }
535 :
536 65420 : for (i = 0; i < char_count; i++) {
537 65322 : data->payload[data->payload_len++] = (uint8_t)take_bits(ds, 8);
538 : }
539 :
540 98 : return LIERRE_ERROR_SUCCESS;
541 : }
542 :
543 2 : static inline lierre_error_t decode_kanji(qr_data_t *data, datastream_t *ds)
544 : {
545 : uint16_t sjis_char;
546 : int32_t count_bits, char_count, i, encoded_value, high_byte, low_byte, intermediate;
547 :
548 2 : count_bits = KANJI_BITS_LARGE;
549 :
550 2 : if (data->version < VERSION_THRESHOLD_SMALL) {
551 2 : count_bits = KANJI_BITS_SMALL;
552 0 : } else if (data->version < VERSION_THRESHOLD_MEDIUM) {
553 0 : count_bits = KANJI_BITS_MEDIUM;
554 : }
555 :
556 2 : char_count = take_bits(ds, count_bits);
557 2 : if (data->payload_len + char_count * 2 + 1 > LIERRE_DECODER_MAX_PAYLOAD) {
558 0 : return LIERRE_ERROR_DATA_OVERFLOW;
559 : }
560 :
561 2 : if (bits_remaining(ds) < char_count * KANJI_ENCODED_BITS) {
562 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
563 : }
564 :
565 7 : for (i = 0; i < char_count; i++) {
566 5 : encoded_value = take_bits(ds, KANJI_ENCODED_BITS);
567 5 : high_byte = encoded_value / KANJI_ENCODE_DIVISOR;
568 5 : low_byte = encoded_value % KANJI_ENCODE_DIVISOR;
569 5 : intermediate = (high_byte << 8) | low_byte;
570 :
571 5 : if (intermediate + KANJI_SJIS_BASE1 <= KANJI_SJIS_BOUNDARY) {
572 5 : sjis_char = (uint16_t)(intermediate + KANJI_SJIS_BASE1);
573 : } else {
574 0 : sjis_char = (uint16_t)(intermediate + KANJI_SJIS_BASE2);
575 : }
576 :
577 5 : data->payload[data->payload_len++] = (uint8_t)(sjis_char >> 8);
578 5 : data->payload[data->payload_len++] = (uint8_t)(sjis_char & 0xff);
579 : }
580 :
581 2 : return LIERRE_ERROR_SUCCESS;
582 : }
583 :
584 1 : static inline lierre_error_t decode_eci(qr_data_t *data, datastream_t *ds)
585 : {
586 1 : if (bits_remaining(ds) < 8) {
587 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
588 : }
589 :
590 1 : data->eci = (uint32_t)take_bits(ds, 8);
591 :
592 1 : if ((data->eci & 0xc0) == 0x80) {
593 0 : if (bits_remaining(ds) < 8) {
594 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
595 : }
596 :
597 0 : data->eci = (data->eci << 8) | (uint32_t)take_bits(ds, 8);
598 1 : } else if ((data->eci & 0xe0) == 0xc0) {
599 0 : if (bits_remaining(ds) < 16) {
600 0 : return LIERRE_ERROR_DATA_UNDERFLOW;
601 : }
602 :
603 0 : data->eci = (data->eci << 16) | (uint32_t)take_bits(ds, 16);
604 : }
605 :
606 1 : return LIERRE_ERROR_SUCCESS;
607 : }
608 :
609 104 : static inline lierre_error_t decode_payload(qr_data_t *data, datastream_t *ds)
610 : {
611 : lierre_error_t err;
612 : int32_t mode_indicator;
613 :
614 209 : while (bits_remaining(ds) >= 4) {
615 209 : err = LIERRE_ERROR_SUCCESS;
616 209 : mode_indicator = take_bits(ds, 4);
617 :
618 209 : switch (mode_indicator) {
619 2 : case MODE_NUMERIC:
620 2 : err = decode_numeric(data, ds);
621 2 : break;
622 2 : case MODE_ALPHANUMERIC:
623 2 : err = decode_alpha(data, ds);
624 2 : break;
625 98 : case MODE_BYTE:
626 98 : err = decode_byte(data, ds);
627 98 : break;
628 2 : case MODE_KANJI:
629 2 : err = decode_kanji(data, ds);
630 2 : break;
631 1 : case MODE_ECI:
632 1 : err = decode_eci(data, ds);
633 1 : break;
634 104 : default:
635 104 : goto done;
636 : }
637 :
638 105 : if (err) {
639 0 : return err;
640 : }
641 :
642 105 : if (!(mode_indicator & (mode_indicator - 1)) && (mode_indicator > data->data_type)) {
643 104 : data->data_type = mode_indicator;
644 : }
645 : }
646 :
647 0 : done:
648 104 : if (data->payload_len >= LIERRE_DECODER_MAX_PAYLOAD) {
649 0 : data->payload_len = LIERRE_DECODER_MAX_PAYLOAD - 1;
650 : }
651 :
652 104 : data->payload[data->payload_len] = 0;
653 :
654 104 : return LIERRE_ERROR_SUCCESS;
655 : }
656 :
657 129 : lierre_error_t decode_qr(const qr_code_t *code, qr_data_t *data)
658 : {
659 : lierre_error_t err;
660 129 : datastream_t ds = {0};
661 :
662 129 : if (code->size > LIERRE_DECODER_MAX_GRID_SIZE) {
663 0 : return LIERRE_ERROR_INVALID_GRID_SIZE;
664 : }
665 :
666 129 : if ((code->size - QR_VERSION1_SIZE) % 4) {
667 0 : return LIERRE_ERROR_INVALID_GRID_SIZE;
668 : }
669 :
670 129 : lmemset(data, 0, sizeof(*data));
671 :
672 129 : data->version = (code->size - QR_VERSION1_SIZE) / 4;
673 :
674 129 : if (data->version < 1 || data->version > LIERRE_DECODER_MAX_VERSION) {
675 0 : return LIERRE_ERROR_INVALID_VERSION;
676 : }
677 :
678 129 : err = read_format(code, data, 0);
679 129 : if (err) {
680 9 : err = read_format(code, data, 1);
681 : }
682 129 : if (err) {
683 6 : return err;
684 : }
685 :
686 123 : ds.raw = data->payload;
687 :
688 123 : read_data(code, data, &ds);
689 123 : err = codestream_ecc(data, &ds);
690 123 : if (err) {
691 19 : return err;
692 : }
693 :
694 104 : ds.raw = NULL;
695 :
696 104 : err = decode_payload(data, &ds);
697 104 : if (err) {
698 0 : return err;
699 : }
700 :
701 104 : return LIERRE_ERROR_SUCCESS;
702 : }
|