diff --git a/.gitignore b/.gitignore index a7494bc..54855db 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ libquirc.so* .*.swp *~ .DS_Store +.idea \ No newline at end of file diff --git a/README.md b/README.md index d70c5c3..78051ad 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,23 @@ for (i = 0; i < num_codes; i++) { `quirc_code` and `quirc_data` are flat structures which don't need to be initialized or freed after use. +In case you also need to support horizontally flipped QR-codes (mirrored +images according to ISO 18004:2015, pages 6 and 62), you can make a second +decode attempt with the flipped image data whenever you get an ECC failure: + +```C + err = quirc_decode(&code, &data); + if (err == QUIRC_ERROR_DATA_ECC) { + quirc_flip(&code); + err = quirc_decode(&code, &data); + } + + if (err) + printf("DECODE FAILED: %s\n", quirc_strerror(err)); + else + printf("Data: %s\n", data.payload); +``` + Copyright --------- Copyright (C) 2010-2012 Daniel Beer <> diff --git a/lib/decode.c b/lib/decode.c index 6266611..0d654c5 100644 --- a/lib/decode.c +++ b/lib/decode.c @@ -916,3 +916,18 @@ quirc_decode_error_t quirc_decode(const struct quirc_code *code, return QUIRC_SUCCESS; } + +void quirc_flip(struct quirc_code *code) +{ + struct quirc_code flipped = {0}; + unsigned int offset = 0; + for (int y = 0; y < code->size; y++) { + for (int x = 0; x < code->size; x++) { + if (grid_bit(code, y, x)) { + flipped.cell_bitmap[offset >> 3u] |= (1u << (offset & 7u)); + } + offset++; + } + } + memcpy(&code->cell_bitmap, &flipped.cell_bitmap, sizeof(flipped.cell_bitmap)); +} diff --git a/lib/identify.c b/lib/identify.c index d33f3d7..b725fea 100644 --- a/lib/identify.c +++ b/lib/identify.c @@ -1140,7 +1140,7 @@ void quirc_extract(const struct quirc *q, int index, int x; for (x = 0; x < qr->grid_size; x++) { if (read_cell(q, index, x, y) > 0) { - code->cell_bitmap[i >> 3] |= (1 << (i & 7)); + code->cell_bitmap[i >> 3] |= (1 << (i & 7)); } i++; } diff --git a/lib/quirc.h b/lib/quirc.h index 97b4bbe..d8d250d 100644 --- a/lib/quirc.h +++ b/lib/quirc.h @@ -168,6 +168,9 @@ void quirc_extract(const struct quirc *q, int index, quirc_decode_error_t quirc_decode(const struct quirc_code *code, struct quirc_data *data); +/* Flip a QR-code according to optional mirror feature of ISO 18004:2015 */ +void quirc_flip(struct quirc_code *code); + #ifdef __cplusplus } #endif diff --git a/tests/inspect.c b/tests/inspect.c index 866ee16..ce5357a 100644 --- a/tests/inspect.c +++ b/tests/inspect.c @@ -34,6 +34,10 @@ static void dump_info(struct quirc *q) quirc_extract(q, i, &code); err = quirc_decode(&code, &data); + if (err == QUIRC_ERROR_DATA_ECC) { + quirc_flip(&code); + err = quirc_decode(&code, &data); + } dump_cells(&code); printf("\n"); diff --git a/tests/qrtest.c b/tests/qrtest.c index 2e50698..1bb178e 100644 --- a/tests/qrtest.c +++ b/tests/qrtest.c @@ -125,8 +125,15 @@ static int scan_file(const char *path, const char *filename, quirc_extract(decoder, i, &code); - if (!quirc_decode(&code, &data)) + quirc_decode_error_t err = quirc_decode(&code, &data); + if (err == QUIRC_ERROR_DATA_ECC) { + quirc_flip(&code); + err = quirc_decode(&code, &data); + } + + if (!err) { info->decode_count++; + } } (void)clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); @@ -150,12 +157,14 @@ static int scan_file(const char *path, const char *filename, if (want_verbose) { struct quirc_data data; - quirc_decode_error_t err = - quirc_decode(&code, &data); + quirc_decode_error_t err = quirc_decode(&code, &data); + if (err == QUIRC_ERROR_DATA_ECC) { + quirc_flip(&code); + err = quirc_decode(&code, &data); + } if (err) { - printf(" ERROR: %s\n\n", - quirc_strerror(err)); + printf(" ERROR: %s\n\n", quirc_strerror(err)); } else { printf(" Decode successful:\n"); dump_data(&data);