├── .gitignore ├── LICENSE ├── Makefile ├── bin ├── dbgutil.h ├── dbgutil.c └── qrscan.c ├── lib ├── quirc_internal.h ├── quirc.c ├── quirc.h ├── version_db.c ├── decode.c └── identify.c └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.lo 3 | qrscan 4 | inspect 5 | libquirc.a 6 | libquirc.so* 7 | .*.swp 8 | *~ 9 | .DS_Store 10 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | quirc -- QR-code recognition library 2 | Copyright (C) 2010-2012 Daniel Beer 3 | 4 | ISC License 5 | =========== 6 | 7 | Permission to use, copy, modify, and/or distribute this software for 8 | any purpose with or without fee is hereby granted, provided that the 9 | above copyright notice and this permission notice appear in all 10 | copies. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 | AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 | PERFORMANCE OF THIS SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC ?= $(CC) 2 | AR ?= $(AR) 3 | 4 | CFLAGS ?= -O1 -Wall -fPIC 5 | QUIRC_CFLAGS = -Ilib $(CFLAGS) 6 | 7 | LIB_OBJ = \ 8 | lib/decode.o \ 9 | lib/identify.o \ 10 | lib/quirc.o \ 11 | lib/version_db.o 12 | 13 | .PHONY: all install uninstall clean 14 | 15 | all: libquirc.a qrscan 16 | 17 | qrscan: bin/dbgutil.o bin/qrscan.o libquirc.a 18 | $(CC) -o $@ bin/dbgutil.o bin/qrscan.o libquirc.a $(LDFLAGS) -lm -ljpeg 19 | 20 | libquirc.a: $(LIB_OBJ) 21 | rm -f $@ 22 | $(AR) cr $@ $(LIB_OBJ) 23 | ranlib $@ 24 | 25 | .c.o: 26 | $(CC) $(QUIRC_CFLAGS) -o $@ -c $< 27 | 28 | install: libquirc.a 29 | install -m 0644 libquirc.a $(DESTDIR)/usr/lib 30 | install -m 0755 qrscan $(DESTDIR)/usr/sbin 31 | 32 | uninstall: 33 | rm -f $(DESTDIR)/usr/sbin/qrscan 34 | rm -f $(DESTDIR)/usr/lib/libquirc.a 35 | 36 | clean: 37 | rm -f */*.o 38 | rm -f */*.lo 39 | rm -f libquirc.a 40 | rm -f qrscan 41 | -------------------------------------------------------------------------------- /bin/dbgutil.h: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 | #ifndef DBGUTIL_H_ 18 | #define DBGUTIL_H_ 19 | 20 | #include "quirc.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* Dump decoded information on stdout. */ 27 | void dump_data(const struct quirc_data *data); 28 | 29 | /* Dump a grid cell map on stdout. */ 30 | void dump_cells(const struct quirc_code *code); 31 | 32 | /* Read a JPEG image into the decoder. 33 | * 34 | * Note that you must call quirc_end() if the function returns 35 | * successfully (0). 36 | */ 37 | int load_jpeg(struct quirc *q, const char *filename); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /lib/quirc_internal.h: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 | #ifndef QUIRC_INTERNAL_H_ 18 | #define QUIRC_INTERNAL_H_ 19 | 20 | #include 21 | #include 22 | 23 | #include "quirc.h" 24 | 25 | #define QUIRC_ASSERT(a) assert(a) 26 | 27 | #define QUIRC_PIXEL_WHITE 0 28 | #define QUIRC_PIXEL_BLACK 1 29 | #define QUIRC_PIXEL_REGION 2 30 | 31 | #ifndef QUIRC_MAX_REGIONS 32 | #define QUIRC_MAX_REGIONS 254 33 | #endif 34 | #define QUIRC_MAX_CAPSTONES 32 35 | #define QUIRC_MAX_GRIDS (QUIRC_MAX_CAPSTONES * 2) 36 | 37 | #define QUIRC_PERSPECTIVE_PARAMS 8 38 | 39 | #if QUIRC_MAX_REGIONS < UINT8_MAX 40 | #define QUIRC_PIXEL_ALIAS_IMAGE 1 41 | typedef uint8_t quirc_pixel_t; 42 | #elif QUIRC_MAX_REGIONS < UINT16_MAX 43 | #define QUIRC_PIXEL_ALIAS_IMAGE 0 44 | typedef uint16_t quirc_pixel_t; 45 | #else 46 | #error "QUIRC_MAX_REGIONS > 65534 is not supported" 47 | #endif 48 | 49 | struct quirc_region { 50 | struct quirc_point seed; 51 | int count; 52 | int capstone; 53 | }; 54 | 55 | struct quirc_capstone { 56 | int ring; 57 | int stone; 58 | 59 | struct quirc_point corners[4]; 60 | struct quirc_point center; 61 | double c[QUIRC_PERSPECTIVE_PARAMS]; 62 | 63 | int qr_grid; 64 | }; 65 | 66 | struct quirc_grid { 67 | /* Capstone indices */ 68 | int caps[3]; 69 | 70 | /* Alignment pattern region and corner */ 71 | int align_region; 72 | struct quirc_point align; 73 | 74 | /* Timing pattern endpoints */ 75 | struct quirc_point tpep[3]; 76 | 77 | /* Grid size and perspective transform */ 78 | int grid_size; 79 | double c[QUIRC_PERSPECTIVE_PARAMS]; 80 | }; 81 | 82 | struct quirc_flood_fill_vars { 83 | int y; 84 | int right; 85 | int left_up; 86 | int left_down; 87 | }; 88 | 89 | struct quirc { 90 | uint8_t *image; 91 | quirc_pixel_t *pixels; 92 | int w; 93 | int h; 94 | 95 | int num_regions; 96 | struct quirc_region regions[QUIRC_MAX_REGIONS]; 97 | 98 | int num_capstones; 99 | struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES]; 100 | 101 | int num_grids; 102 | struct quirc_grid grids[QUIRC_MAX_GRIDS]; 103 | 104 | size_t num_flood_fill_vars; 105 | struct quirc_flood_fill_vars *flood_fill_vars; 106 | }; 107 | 108 | /************************************************************************ 109 | * QR-code version information database 110 | */ 111 | 112 | #define QUIRC_MAX_VERSION 40 113 | #define QUIRC_MAX_ALIGNMENT 7 114 | 115 | struct quirc_rs_params { 116 | int bs; /* Small block size */ 117 | int dw; /* Small data words */ 118 | int ns; /* Number of small blocks */ 119 | }; 120 | 121 | struct quirc_version_info { 122 | int data_bytes; 123 | int apat[QUIRC_MAX_ALIGNMENT]; 124 | struct quirc_rs_params ecc[4]; 125 | }; 126 | 127 | extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1]; 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /bin/dbgutil.c: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include "dbgutil.h" 27 | 28 | static const char *data_type_str(int dt) 29 | { 30 | switch (dt) { 31 | case QUIRC_DATA_TYPE_NUMERIC: return "NUMERIC"; 32 | case QUIRC_DATA_TYPE_ALPHA: return "ALPHA"; 33 | case QUIRC_DATA_TYPE_BYTE: return "BYTE"; 34 | case QUIRC_DATA_TYPE_KANJI: return "KANJI"; 35 | } 36 | 37 | return "unknown"; 38 | } 39 | 40 | void dump_data(const struct quirc_data *data) 41 | { 42 | printf(" Version: %d\n", data->version); 43 | printf(" ECC level: %c\n", "MLHQ"[data->ecc_level]); 44 | printf(" Mask: %d\n", data->mask); 45 | printf(" Data type: %d (%s)\n", data->data_type, data_type_str(data->data_type)); 46 | printf(" Length: %d\n", data->payload_len); 47 | printf(" Payload: %s\n", data->payload); 48 | 49 | if (data->eci) 50 | printf(" ECI: %d\n", data->eci); 51 | } 52 | 53 | void dump_cells(const struct quirc_code *code) 54 | { 55 | int u, v; 56 | 57 | printf(" %d cells, corners:", code->size); 58 | for (u = 0; u < 4; u++) 59 | printf(" (%d,%d)", code->corners[u].x, code->corners[u].y); 60 | printf("\n"); 61 | 62 | for (v = 0; v < code->size; v++) { 63 | printf(" "); 64 | for (u = 0; u < code->size; u++) { 65 | int p = v * code->size + u; 66 | 67 | if (code->cell_bitmap[p >> 3] & (1 << (p & 7))) 68 | printf("[]"); 69 | else 70 | printf(" "); 71 | } 72 | printf("\n"); 73 | } 74 | } 75 | 76 | struct my_jpeg_error { 77 | struct jpeg_error_mgr base; 78 | jmp_buf env; 79 | }; 80 | 81 | static void my_output_message(struct jpeg_common_struct *com) 82 | { 83 | struct my_jpeg_error *err = (struct my_jpeg_error *)com->err; 84 | char buf[JMSG_LENGTH_MAX]; 85 | 86 | err->base.format_message(com, buf); 87 | fprintf(stderr, "JPEG error: %s\n", buf); 88 | } 89 | 90 | static void my_error_exit(struct jpeg_common_struct *com) 91 | { 92 | struct my_jpeg_error *err = (struct my_jpeg_error *)com->err; 93 | 94 | my_output_message(com); 95 | longjmp(err->env, 0); 96 | } 97 | 98 | static struct jpeg_error_mgr *my_error_mgr(struct my_jpeg_error *err) 99 | { 100 | jpeg_std_error(&err->base); 101 | 102 | err->base.error_exit = my_error_exit; 103 | err->base.output_message = my_output_message; 104 | 105 | return &err->base; 106 | } 107 | 108 | int load_jpeg(struct quirc *q, const char *filename) 109 | { 110 | FILE *infile = fopen(filename, "rb"); 111 | struct jpeg_decompress_struct dinfo; 112 | struct my_jpeg_error err; 113 | uint8_t *image; 114 | int y; 115 | 116 | if (!infile) { 117 | perror("can't open input file"); 118 | return -1; 119 | } 120 | 121 | memset(&dinfo, 0, sizeof(dinfo)); 122 | dinfo.err = my_error_mgr(&err); 123 | 124 | if (setjmp(err.env)) 125 | goto fail; 126 | 127 | jpeg_create_decompress(&dinfo); 128 | jpeg_stdio_src(&dinfo, infile); 129 | 130 | jpeg_read_header(&dinfo, TRUE); 131 | dinfo.output_components = 1; 132 | dinfo.out_color_space = JCS_GRAYSCALE; 133 | jpeg_start_decompress(&dinfo); 134 | 135 | if (dinfo.output_components != 1) { 136 | fprintf(stderr, "Unexpected number of output components: %d", 137 | dinfo.output_components); 138 | goto fail; 139 | } 140 | 141 | if (quirc_resize(q, dinfo.output_width, dinfo.output_height) < 0) 142 | goto fail; 143 | 144 | image = quirc_begin(q, NULL, NULL); 145 | 146 | for (y = 0; y < dinfo.output_height; y++) { 147 | JSAMPROW row_pointer = image + y * dinfo.output_width; 148 | 149 | jpeg_read_scanlines(&dinfo, &row_pointer, 1); 150 | } 151 | 152 | jpeg_finish_decompress(&dinfo); 153 | fclose(infile); 154 | jpeg_destroy_decompress(&dinfo); 155 | return 0; 156 | 157 | fail: 158 | fclose(infile); 159 | jpeg_destroy_decompress(&dinfo); 160 | return -1; 161 | } 162 | -------------------------------------------------------------------------------- /lib/quirc.c: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 18 | #include 19 | #include "quirc_internal.h" 20 | 21 | const char *quirc_version(void) 22 | { 23 | return "1.0"; 24 | } 25 | 26 | struct quirc *quirc_new(void) 27 | { 28 | struct quirc *q = malloc(sizeof(*q)); 29 | 30 | if (!q) 31 | return NULL; 32 | 33 | memset(q, 0, sizeof(*q)); 34 | return q; 35 | } 36 | 37 | void quirc_destroy(struct quirc *q) 38 | { 39 | free(q->image); 40 | /* q->pixels may alias q->image when their type representation is of the 41 | same size, so we need to be careful here to avoid a double free */ 42 | if (!QUIRC_PIXEL_ALIAS_IMAGE) 43 | free(q->pixels); 44 | free(q->flood_fill_vars); 45 | free(q); 46 | } 47 | 48 | int quirc_resize(struct quirc *q, int w, int h) 49 | { 50 | uint8_t *image = NULL; 51 | quirc_pixel_t *pixels = NULL; 52 | size_t num_vars; 53 | size_t vars_byte_size; 54 | struct quirc_flood_fill_vars *vars = NULL; 55 | 56 | /* 57 | * XXX: w and h should be size_t (or at least unsigned) as negatives 58 | * values would not make much sense. The downside is that it would break 59 | * both the API and ABI. Thus, at the moment, let's just do a sanity 60 | * check. 61 | */ 62 | if (w < 0 || h < 0) 63 | goto fail; 64 | 65 | /* 66 | * alloc a new buffer for q->image. We avoid realloc(3) because we want 67 | * on failure to be leave `q` in a consistant, unmodified state. 68 | */ 69 | image = calloc(w, h); 70 | if (!image) 71 | goto fail; 72 | 73 | /* compute the "old" (i.e. currently allocated) and the "new" 74 | (i.e. requested) image dimensions */ 75 | size_t olddim = q->w * q->h; 76 | size_t newdim = w * h; 77 | size_t min = (olddim < newdim ? olddim : newdim); 78 | 79 | /* 80 | * copy the data into the new buffer, avoiding (a) to read beyond the 81 | * old buffer when the new size is greater and (b) to write beyond the 82 | * new buffer when the new size is smaller, hence the min computation. 83 | */ 84 | (void)memcpy(image, q->image, min); 85 | 86 | /* alloc a new buffer for q->pixels if needed */ 87 | if (!QUIRC_PIXEL_ALIAS_IMAGE) { 88 | pixels = calloc(newdim, sizeof(quirc_pixel_t)); 89 | if (!pixels) 90 | goto fail; 91 | } 92 | 93 | /* 94 | * alloc the work area for the flood filling logic. 95 | * 96 | * the size was chosen with the following assumptions and observations: 97 | * 98 | * - rings are the regions which requires the biggest work area. 99 | * - they consumes the most when they are rotated by about 45 degree. 100 | * in that case, the necessary depth is about (2 * height_of_the_ring). 101 | * - the maximum height of rings would be about 1/3 of the image height. 102 | */ 103 | 104 | if ((size_t)h * 2 / 2 != h) { 105 | goto fail; /* size_t overflow */ 106 | } 107 | num_vars = (size_t)h * 2 / 3; 108 | if (num_vars == 0) { 109 | num_vars = 1; 110 | } 111 | 112 | vars_byte_size = sizeof(*vars) * num_vars; 113 | if (vars_byte_size / sizeof(*vars) != num_vars) { 114 | goto fail; /* size_t overflow */ 115 | } 116 | vars = malloc(vars_byte_size); 117 | if (!vars) 118 | goto fail; 119 | 120 | /* alloc succeeded, update `q` with the new size and buffers */ 121 | q->w = w; 122 | q->h = h; 123 | free(q->image); 124 | q->image = image; 125 | if (!QUIRC_PIXEL_ALIAS_IMAGE) { 126 | free(q->pixels); 127 | q->pixels = pixels; 128 | } 129 | free(q->flood_fill_vars); 130 | q->flood_fill_vars = vars; 131 | q->num_flood_fill_vars = num_vars; 132 | 133 | return 0; 134 | /* NOTREACHED */ 135 | fail: 136 | free(image); 137 | free(pixels); 138 | free(vars); 139 | 140 | return -1; 141 | } 142 | 143 | int quirc_count(const struct quirc *q) 144 | { 145 | return q->num_grids; 146 | } 147 | 148 | static const char *const error_table[] = { 149 | [QUIRC_SUCCESS] = "Success", 150 | [QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size", 151 | [QUIRC_ERROR_INVALID_VERSION] = "Invalid version", 152 | [QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure", 153 | [QUIRC_ERROR_DATA_ECC] = "ECC failure", 154 | [QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type", 155 | [QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow", 156 | [QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow" 157 | }; 158 | 159 | const char *quirc_strerror(quirc_decode_error_t err) 160 | { 161 | if (err >= 0 && err < sizeof(error_table) / sizeof(error_table[0])) 162 | return error_table[err]; 163 | 164 | return "Unknown error"; 165 | } 166 | -------------------------------------------------------------------------------- /bin/qrscan.c: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "dbgutil.h" 26 | 27 | static int want_verbose = 0; 28 | static int want_cell_dump = 0; 29 | static int payload_only = 0; 30 | 31 | static struct quirc *decoder; 32 | 33 | struct result_info { 34 | int file_count; 35 | int id_count; 36 | int decode_count; 37 | }; 38 | 39 | static void print_result(const char *name, struct result_info *info) 40 | { 41 | puts("-------------------------------------------------------------------------------"); 42 | printf("%s: %d files, %d codes, %d decoded (%d failures)", name, info->file_count, info->id_count, info->decode_count, (info->id_count - info->decode_count)); 43 | if (info->id_count) 44 | printf(", %d%% success rate", (info->decode_count * 100 + info->id_count / 2) / info->id_count); 45 | printf("\n"); 46 | } 47 | 48 | static void add_result(struct result_info *sum, struct result_info *inf) 49 | { 50 | sum->file_count += inf->file_count; 51 | sum->id_count += inf->id_count; 52 | sum->decode_count += inf->decode_count; 53 | } 54 | 55 | static int scan_file(const char *path, const char *filename, struct result_info *info) 56 | { 57 | int (*loader)(struct quirc *, const char *); 58 | int len = strlen(filename); 59 | const char *ext; 60 | int ret; 61 | int i; 62 | 63 | while (len >= 0 && filename[len] != '.') 64 | len--; 65 | ext = filename + len + 1; 66 | if (strcasecmp(ext, "jpg") == 0 || strcasecmp(ext, "jpeg") == 0) 67 | loader = load_jpeg; 68 | else 69 | return 0; 70 | 71 | ret = loader(decoder, path); 72 | 73 | if (ret < 0) { 74 | fprintf(stderr, "%s: load failed\n", filename); 75 | return -1; 76 | } 77 | 78 | quirc_end(decoder); 79 | 80 | info->id_count = quirc_count(decoder); 81 | for (i = 0; i < info->id_count; i++) { 82 | struct quirc_code code; 83 | struct quirc_data data; 84 | 85 | quirc_extract(decoder, i, &code); 86 | 87 | quirc_decode_error_t err = quirc_decode(&code, &data); 88 | if (err == QUIRC_ERROR_DATA_ECC) { 89 | quirc_flip(&code); 90 | err = quirc_decode(&code, &data); 91 | } 92 | 93 | if (!err) { 94 | info->decode_count++; 95 | } 96 | } 97 | 98 | if (!payload_only) { 99 | printf(" %-30s: %5d %5d\n", filename, info->id_count, info->decode_count); 100 | } 101 | 102 | if (want_cell_dump || want_verbose || payload_only) { 103 | for (i = 0; i < info->id_count; i++) { 104 | struct quirc_code code; 105 | 106 | quirc_extract(decoder, i, &code); 107 | if (want_cell_dump) { 108 | dump_cells(&code); 109 | printf("\n"); 110 | } 111 | 112 | if (want_verbose || payload_only) { 113 | struct quirc_data data; 114 | quirc_decode_error_t err = quirc_decode(&code, &data); 115 | if (err == QUIRC_ERROR_DATA_ECC) { 116 | quirc_flip(&code); 117 | err = quirc_decode(&code, &data); 118 | } 119 | 120 | if (err) { 121 | printf(" ERROR: %s\n\n", quirc_strerror(err)); 122 | } else { 123 | if (payload_only) { 124 | printf("%s\n", data.payload); 125 | } else { 126 | printf(" Decode successful:\n"); 127 | dump_data(&data); 128 | } 129 | printf("\n"); 130 | } 131 | } 132 | } 133 | } 134 | 135 | info->file_count = 1; 136 | return 1; 137 | } 138 | 139 | static int test_scan(const char *path, struct result_info *info) 140 | { 141 | int len = strlen(path); 142 | struct stat st; 143 | const char *filename; 144 | 145 | memset(info, 0, sizeof(*info)); 146 | 147 | while (len >= 0 && path[len] != '/') 148 | len--; 149 | filename = path + len + 1; 150 | 151 | if (lstat(path, &st) < 0) { 152 | fprintf(stderr, "%s: lstat: %s\n", path, strerror(errno)); 153 | return -1; 154 | } 155 | 156 | if (S_ISREG(st.st_mode)) 157 | return scan_file(path, filename, info); 158 | 159 | return 0; 160 | } 161 | 162 | static int run_tests(int argc, char **argv) 163 | { 164 | struct result_info sum; 165 | int count = 0; 166 | int i; 167 | 168 | decoder = quirc_new(); 169 | if (!decoder) { 170 | perror("quirc_new"); 171 | return -1; 172 | } 173 | 174 | if (!payload_only) { 175 | printf(" %-30s %5s %5s %5s %5s %5s\n", "Filename", "Load", "ID", "Total", "ID", "Dec"); 176 | puts("---------------------------------------------------------------"); 177 | } 178 | 179 | memset(&sum, 0, sizeof(sum)); 180 | for (i = 0; i < argc; i++) { 181 | struct result_info info; 182 | 183 | if (test_scan(argv[i], &info) > 0) { 184 | add_result(&sum, &info); 185 | count++; 186 | } 187 | } 188 | 189 | if (count > 1) 190 | print_result("TOTAL", &sum); 191 | 192 | quirc_destroy(decoder); 193 | return 0; 194 | } 195 | 196 | int main(int argc, char **argv) 197 | { 198 | int opt; 199 | 200 | while ((opt = getopt(argc, argv, "vdp")) >= 0) 201 | switch (opt) { 202 | case 'v': 203 | want_verbose = 1; 204 | break; 205 | 206 | case 'd': 207 | want_cell_dump = 1; 208 | break; 209 | 210 | case 'p': 211 | payload_only = 1; 212 | break; 213 | 214 | case '?': 215 | return -1; 216 | } 217 | 218 | argv += optind; 219 | argc -= optind; 220 | 221 | return run_tests(argc, argv); 222 | } 223 | -------------------------------------------------------------------------------- /lib/quirc.h: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 | #ifndef QUIRC_H_ 18 | #define QUIRC_H_ 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | struct quirc; 27 | 28 | /* Obtain the library version string. */ 29 | const char *quirc_version(void); 30 | 31 | /* Construct a new QR-code recognizer. This function will return NULL 32 | * if sufficient memory could not be allocated. 33 | */ 34 | struct quirc *quirc_new(void); 35 | 36 | /* Destroy a QR-code recognizer. */ 37 | void quirc_destroy(struct quirc *q); 38 | 39 | /* Resize the QR-code recognizer. The size of an image must be 40 | * specified before codes can be analyzed. 41 | * 42 | * This function returns 0 on success, or -1 if sufficient memory could 43 | * not be allocated. 44 | */ 45 | int quirc_resize(struct quirc *q, int w, int h); 46 | 47 | /* These functions are used to process images for QR-code recognition. 48 | * quirc_begin() must first be called to obtain access to a buffer into 49 | * which the input image should be placed. Optionally, the current 50 | * width and height may be returned. 51 | * 52 | * After filling the buffer, quirc_end() should be called to process 53 | * the image for QR-code recognition. The locations and content of each 54 | * code may be obtained using accessor functions described below. 55 | */ 56 | uint8_t *quirc_begin(struct quirc *q, int *w, int *h); 57 | void quirc_end(struct quirc *q); 58 | 59 | /* This structure describes a location in the input image buffer. */ 60 | struct quirc_point { 61 | int x; 62 | int y; 63 | }; 64 | 65 | /* This enum describes the various decoder errors which may occur. */ 66 | typedef enum { 67 | QUIRC_SUCCESS = 0, 68 | QUIRC_ERROR_INVALID_GRID_SIZE, 69 | QUIRC_ERROR_INVALID_VERSION, 70 | QUIRC_ERROR_FORMAT_ECC, 71 | QUIRC_ERROR_DATA_ECC, 72 | QUIRC_ERROR_UNKNOWN_DATA_TYPE, 73 | QUIRC_ERROR_DATA_OVERFLOW, 74 | QUIRC_ERROR_DATA_UNDERFLOW 75 | } quirc_decode_error_t; 76 | 77 | /* Return a string error message for an error code. */ 78 | const char *quirc_strerror(quirc_decode_error_t err); 79 | 80 | /* Limits on the maximum size of QR-codes and their content. */ 81 | #define QUIRC_MAX_VERSION 40 82 | #define QUIRC_MAX_GRID_SIZE (QUIRC_MAX_VERSION * 4 + 17) 83 | #define QUIRC_MAX_BITMAP (((QUIRC_MAX_GRID_SIZE * QUIRC_MAX_GRID_SIZE) + 7) / 8) 84 | #define QUIRC_MAX_PAYLOAD 8896 85 | 86 | /* QR-code ECC types. */ 87 | #define QUIRC_ECC_LEVEL_M 0 88 | #define QUIRC_ECC_LEVEL_L 1 89 | #define QUIRC_ECC_LEVEL_H 2 90 | #define QUIRC_ECC_LEVEL_Q 3 91 | 92 | /* QR-code data types. */ 93 | #define QUIRC_DATA_TYPE_NUMERIC 1 94 | #define QUIRC_DATA_TYPE_ALPHA 2 95 | #define QUIRC_DATA_TYPE_BYTE 4 96 | #define QUIRC_DATA_TYPE_KANJI 8 97 | 98 | /* Common character encodings */ 99 | #define QUIRC_ECI_ISO_8859_1 1 100 | #define QUIRC_ECI_IBM437 2 101 | #define QUIRC_ECI_ISO_8859_2 4 102 | #define QUIRC_ECI_ISO_8859_3 5 103 | #define QUIRC_ECI_ISO_8859_4 6 104 | #define QUIRC_ECI_ISO_8859_5 7 105 | #define QUIRC_ECI_ISO_8859_6 8 106 | #define QUIRC_ECI_ISO_8859_7 9 107 | #define QUIRC_ECI_ISO_8859_8 10 108 | #define QUIRC_ECI_ISO_8859_9 11 109 | #define QUIRC_ECI_WINDOWS_874 13 110 | #define QUIRC_ECI_ISO_8859_13 15 111 | #define QUIRC_ECI_ISO_8859_15 17 112 | #define QUIRC_ECI_SHIFT_JIS 20 113 | #define QUIRC_ECI_UTF_8 26 114 | 115 | /* This structure is used to return information about detected QR codes 116 | * in the input image. 117 | */ 118 | struct quirc_code { 119 | /* The four corners of the QR-code, from top left, clockwise */ 120 | struct quirc_point corners[4]; 121 | 122 | /* The number of cells across in the QR-code. The cell bitmap 123 | * is a bitmask giving the actual values of cells. If the cell 124 | * at (x, y) is black, then the following bit is set: 125 | * 126 | * cell_bitmap[i >> 3] & (1 << (i & 7)) 127 | * 128 | * where i = (y * size) + x. 129 | */ 130 | int size; 131 | uint8_t cell_bitmap[QUIRC_MAX_BITMAP]; 132 | }; 133 | 134 | /* This structure holds the decoded QR-code data */ 135 | struct quirc_data { 136 | /* Various parameters of the QR-code. These can mostly be 137 | * ignored if you only care about the data. 138 | */ 139 | int version; 140 | int ecc_level; 141 | int mask; 142 | 143 | /* This field is the highest-valued data type found in the QR 144 | * code. 145 | */ 146 | int data_type; 147 | 148 | /* Data payload. For the Kanji datatype, payload is encoded as 149 | * Shift-JIS. For all other datatypes, payload is ASCII text. 150 | */ 151 | uint8_t payload[QUIRC_MAX_PAYLOAD]; 152 | int payload_len; 153 | 154 | /* ECI assignment number */ 155 | uint32_t eci; 156 | }; 157 | 158 | /* Return the number of QR-codes identified in the last processed 159 | * image. 160 | */ 161 | int quirc_count(const struct quirc *q); 162 | 163 | /* Extract the QR-code specified by the given index. */ 164 | void quirc_extract(const struct quirc *q, int index, 165 | struct quirc_code *code); 166 | 167 | /* Decode a QR-code, returning the payload data. */ 168 | quirc_decode_error_t quirc_decode(const struct quirc_code *code, 169 | struct quirc_data *data); 170 | 171 | /* Flip a QR-code according to optional mirror feature of ISO 18004:2015 */ 172 | void quirc_flip(struct quirc_code *code); 173 | 174 | #ifdef __cplusplus 175 | } 176 | #endif 177 | 178 | #endif 179 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Quirc 2 | ===== 3 | 4 | QR codes are a type of high-density matrix barcodes, and quirc is a library for 5 | extracting and decoding them from images. It has several features which make it 6 | a good choice for this purpose: 7 | 8 | * It is fast enough to be used with realtime video: extracting and decoding 9 | from VGA frame takes about 50 ms on a modern x86 core. 10 | 11 | * It has a robust and tolerant recognition algorithm. It can correctly 12 | recognise and decode QR codes which are rotated and/or oblique to the camera. 13 | It can also distinguish and decode multiple codes within the same image. 14 | 15 | * It is easy to use, with a simple API described in a single commented header 16 | file (see below for an overview). 17 | 18 | * It is small and easily embeddable, with no dependencies other than standard C 19 | functions. 20 | 21 | * It has a very small memory footprint: one byte per image pixel, plus a few kB 22 | per decoder object. 23 | 24 | * It uses no global mutable state, and is safe to use in a multithreaded 25 | application. 26 | 27 | * BSD-licensed, with almost no restrictions regarding use and/or modification. 28 | 29 | The distribution comes with, in addition to the library, several test programs. 30 | While the core library is very portable, these programs have some additional 31 | dependencies as documented below. 32 | 33 | ### quirc-demo 34 | 35 | This is an real-time demo which requires a camera and a graphical display. The 36 | video stream is displayed on screen as it's received, and any QR codes 37 | recognised are highlighted in the image, with the decoded information both 38 | displayed on the image and printed on stdout. 39 | 40 | This requires: libjpeg, libpng, SDL, V4L2 41 | 42 | ### quirc-demo-opencv 43 | 44 | A demo similar to `quirc-demo`. 45 | But this version uses OpenCV instead of other libraries. 46 | 47 | This requires: OpenCV 48 | 49 | ### quirc-scanner 50 | 51 | This program turns your camera into a barcode scanner. It's almost the same as 52 | the `demo` application, but it doesn't display the video stream, and thus 53 | doesn't require a graphical display. 54 | 55 | This requires: libjpeg, V4L2 56 | 57 | ### qrtest 58 | 59 | This test is used to evaluate the performance of library. Given a directory 60 | tree containing a bunch of JPEG images, it will attempt to locate and decode QR 61 | codes in each image. Speed and success statistics are collected and printed on 62 | stdout. 63 | 64 | This requires: libjpeg, libpng 65 | 66 | ### inspect 67 | 68 | This test is used for debugging. Given a single JPEG image, it will display a 69 | diagram showing the internal state of the decoder as well as printing 70 | additional information on stdout. 71 | 72 | This requires: libjpeg, libpng, SDL 73 | 74 | ### inspect-opencv 75 | 76 | A test similar to `inspect`. 77 | But this version uses OpenCV instead of other libraries. 78 | 79 | This requires: libjpeg, libpng, OpenCV 80 | 81 | Build-time requirements 82 | ----------------------- 83 | 84 | ### make 85 | 86 | While we are trying to keep our makefiles portable, 87 | it might be incompatible with some versions of make. 88 | 89 | #### GNU make 90 | 91 | Version 4.x and later works. We recommend to use it. 92 | 93 | Version prior to 4.0 doesn't work because it doesn't support `!=`. 94 | 95 | *Note*: macOS's default version of make is GNU make 3.81 as of writing this. 96 | 97 | #### BSD make 98 | 99 | It also works. 100 | You might need to specify the `-r` make option because some of 101 | the default macros like CFLAGS from sys.mk can cause unintended effects. 102 | 103 | Installation 104 | ------------ 105 | To build the library and associated demos/tests, type `make`. If you need to 106 | decode "large" image files build with `CFLAGS="-DQUIRC_MAX_REGIONS=65534" make` 107 | instead. Note that this will increase the memory usage, it is discouraged for 108 | low resource devices (i.e. embedded). 109 | 110 | Type `make install` to install the library, header file and camera demos. 111 | 112 | You can specify one or several of the following targets if you don't want, or 113 | are unable to build everything: 114 | 115 | * libquirc.a 116 | * libquirc.so 117 | * qrtest 118 | * inspect 119 | * inspect-opencv 120 | * quirc-scanner 121 | * quirc-demo 122 | * quirc-demo-opencv 123 | 124 | Library use 125 | ----------- 126 | All of the library's functionality is exposed through a single header file, 127 | which you should include: 128 | 129 | ```C 130 | #include 131 | ``` 132 | 133 | To decode images, you'll need to instantiate a `struct quirc` object, which is 134 | done with the `quirc_new` function. Later, when you no longer need to decode 135 | anything, you should release the allocated memory with `quirc_destroy`: 136 | 137 | ```C 138 | struct quirc *qr; 139 | 140 | qr = quirc_new(); 141 | if (!qr) { 142 | perror("Failed to allocate memory"); 143 | abort(); 144 | } 145 | 146 | /* ... */ 147 | 148 | quirc_destroy(qr); 149 | ``` 150 | 151 | Having obtained a decoder object, you need to set the image size that you'll be 152 | working with, which is done using `quirc_resize`: 153 | 154 | ```C 155 | if (quirc_resize(qr, 640, 480) < 0) { 156 | perror("Failed to allocate video memory"); 157 | abort(); 158 | } 159 | ``` 160 | 161 | `quirc_resize` and `quirc_new` are the only library functions which allocate 162 | memory. If you plan to process a series of frames (or a video stream), you 163 | probably want to allocate and size a single decoder and hold onto it to process 164 | each frame. 165 | 166 | Processing frames is done in two stages. The first stage is an 167 | image-recognition stage called identification, which takes a grayscale image 168 | and searches for QR codes. Using `quirc_begin` and `quirc_end`, you can feed a 169 | grayscale image directly into the buffer that `quirc` uses for image 170 | processing: 171 | 172 | ```C 173 | uint8_t *image; 174 | int w, h; 175 | 176 | image = quirc_begin(qr, &w, &h); 177 | 178 | /* Fill out the image buffer here. 179 | * image is a pointer to a w*h bytes. 180 | * One byte per pixel, w pixels per line, h lines in the buffer. 181 | */ 182 | 183 | quirc_end(qr); 184 | ``` 185 | 186 | Note that `quirc_begin` simply returns a pointer to a previously allocated 187 | buffer. The buffer will contain uninitialized data. After the call to 188 | `quirc_end`, the decoder holds a list of detected QR codes which can be queried 189 | via `quirc_count` and `quirc_extract`. 190 | 191 | At this point, the second stage of processing occurs -- decoding. This is done 192 | via the call to `quirc_decode`, which is not associated with a decoder object. 193 | 194 | ```C 195 | int num_codes; 196 | int i; 197 | 198 | /* We've previously fed an image to the decoder via 199 | * quirc_begin/quirc_end. 200 | */ 201 | 202 | num_codes = quirc_count(qr); 203 | for (i = 0; i < num_codes; i++) { 204 | struct quirc_code code; 205 | struct quirc_data data; 206 | quirc_decode_error_t err; 207 | 208 | quirc_extract(qr, i, &code); 209 | 210 | /* Decoding stage */ 211 | err = quirc_decode(&code, &data); 212 | if (err) 213 | printf("DECODE FAILED: %s\n", quirc_strerror(err)); 214 | else 215 | printf("Data: %s\n", data.payload); 216 | } 217 | ``` 218 | 219 | `quirc_code` and `quirc_data` are flat structures which don't need to be 220 | initialized or freed after use. 221 | 222 | In case you also need to support horizontally flipped QR-codes (mirrored 223 | images according to ISO 18004:2015, pages 6 and 62), you can make a second 224 | decode attempt with the flipped image data whenever you get an ECC failure: 225 | 226 | ```C 227 | err = quirc_decode(&code, &data); 228 | if (err == QUIRC_ERROR_DATA_ECC) { 229 | quirc_flip(&code); 230 | err = quirc_decode(&code, &data); 231 | } 232 | 233 | if (err) 234 | printf("DECODE FAILED: %s\n", quirc_strerror(err)); 235 | else 236 | printf("Data: %s\n", data.payload); 237 | ``` 238 | 239 | Copyright 240 | --------- 241 | Copyright (C) 2010-2012 Daniel Beer <> 242 | 243 | Permission to use, copy, modify, and/or distribute this software for 244 | any purpose with or without fee is hereby granted, provided that the 245 | above copyright notice and this permission notice appear in all 246 | copies. 247 | 248 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 249 | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 250 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 251 | AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 252 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 253 | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 254 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 255 | PERFORMANCE OF THIS SOFTWARE. 256 | -------------------------------------------------------------------------------- /lib/version_db.c: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 | const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = { 20 | {0}, 21 | { /* Version 1 */ 22 | .data_bytes = 26, 23 | .apat = {0}, 24 | .ecc = { 25 | {.bs = 26, .dw = 16, .ns = 1}, 26 | {.bs = 26, .dw = 19, .ns = 1}, 27 | {.bs = 26, .dw = 9, .ns = 1}, 28 | {.bs = 26, .dw = 13, .ns = 1} 29 | } 30 | }, 31 | { /* Version 2 */ 32 | .data_bytes = 44, 33 | .apat = {6, 18, 0}, 34 | .ecc = { 35 | {.bs = 44, .dw = 28, .ns = 1}, 36 | {.bs = 44, .dw = 34, .ns = 1}, 37 | {.bs = 44, .dw = 16, .ns = 1}, 38 | {.bs = 44, .dw = 22, .ns = 1} 39 | } 40 | }, 41 | { /* Version 3 */ 42 | .data_bytes = 70, 43 | .apat = {6, 22, 0}, 44 | .ecc = { 45 | {.bs = 70, .dw = 44, .ns = 1}, 46 | {.bs = 70, .dw = 55, .ns = 1}, 47 | {.bs = 35, .dw = 13, .ns = 2}, 48 | {.bs = 35, .dw = 17, .ns = 2} 49 | } 50 | }, 51 | { /* Version 4 */ 52 | .data_bytes = 100, 53 | .apat = {6, 26, 0}, 54 | .ecc = { 55 | {.bs = 50, .dw = 32, .ns = 2}, 56 | {.bs = 100, .dw = 80, .ns = 1}, 57 | {.bs = 25, .dw = 9, .ns = 4}, 58 | {.bs = 50, .dw = 24, .ns = 2} 59 | } 60 | }, 61 | { /* Version 5 */ 62 | .data_bytes = 134, 63 | .apat = {6, 30, 0}, 64 | .ecc = { 65 | {.bs = 67, .dw = 43, .ns = 2}, 66 | {.bs = 134, .dw = 108, .ns = 1}, 67 | {.bs = 33, .dw = 11, .ns = 2}, 68 | {.bs = 33, .dw = 15, .ns = 2} 69 | } 70 | }, 71 | { /* Version 6 */ 72 | .data_bytes = 172, 73 | .apat = {6, 34, 0}, 74 | .ecc = { 75 | {.bs = 43, .dw = 27, .ns = 4}, 76 | {.bs = 86, .dw = 68, .ns = 2}, 77 | {.bs = 43, .dw = 15, .ns = 4}, 78 | {.bs = 43, .dw = 19, .ns = 4} 79 | } 80 | }, 81 | { /* Version 7 */ 82 | .data_bytes = 196, 83 | .apat = {6, 22, 38, 0}, 84 | .ecc = { 85 | {.bs = 49, .dw = 31, .ns = 4}, 86 | {.bs = 98, .dw = 78, .ns = 2}, 87 | {.bs = 39, .dw = 13, .ns = 4}, 88 | {.bs = 32, .dw = 14, .ns = 2} 89 | } 90 | }, 91 | { /* Version 8 */ 92 | .data_bytes = 242, 93 | .apat = {6, 24, 42, 0}, 94 | .ecc = { 95 | {.bs = 60, .dw = 38, .ns = 2}, 96 | {.bs = 121, .dw = 97, .ns = 2}, 97 | {.bs = 40, .dw = 14, .ns = 4}, 98 | {.bs = 40, .dw = 18, .ns = 4} 99 | } 100 | }, 101 | { /* Version 9 */ 102 | .data_bytes = 292, 103 | .apat = {6, 26, 46, 0}, 104 | .ecc = { 105 | {.bs = 58, .dw = 36, .ns = 3}, 106 | {.bs = 146, .dw = 116, .ns = 2}, 107 | {.bs = 36, .dw = 12, .ns = 4}, 108 | {.bs = 36, .dw = 16, .ns = 4} 109 | } 110 | }, 111 | { /* Version 10 */ 112 | .data_bytes = 346, 113 | .apat = {6, 28, 50, 0}, 114 | .ecc = { 115 | {.bs = 69, .dw = 43, .ns = 4}, 116 | {.bs = 86, .dw = 68, .ns = 2}, 117 | {.bs = 43, .dw = 15, .ns = 6}, 118 | {.bs = 43, .dw = 19, .ns = 6} 119 | } 120 | }, 121 | { /* Version 11 */ 122 | .data_bytes = 404, 123 | .apat = {6, 30, 54, 0}, 124 | .ecc = { 125 | {.bs = 80, .dw = 50, .ns = 1}, 126 | {.bs = 101, .dw = 81, .ns = 4}, 127 | {.bs = 36, .dw = 12, .ns = 3}, 128 | {.bs = 50, .dw = 22, .ns = 4} 129 | } 130 | }, 131 | { /* Version 12 */ 132 | .data_bytes = 466, 133 | .apat = {6, 32, 58, 0}, 134 | .ecc = { 135 | {.bs = 58, .dw = 36, .ns = 6}, 136 | {.bs = 116, .dw = 92, .ns = 2}, 137 | {.bs = 42, .dw = 14, .ns = 7}, 138 | {.bs = 46, .dw = 20, .ns = 4} 139 | } 140 | }, 141 | { /* Version 13 */ 142 | .data_bytes = 532, 143 | .apat = {6, 34, 62, 0}, 144 | .ecc = { 145 | {.bs = 59, .dw = 37, .ns = 8}, 146 | {.bs = 133, .dw = 107, .ns = 4}, 147 | {.bs = 33, .dw = 11, .ns = 12}, 148 | {.bs = 44, .dw = 20, .ns = 8} 149 | } 150 | }, 151 | { /* Version 14 */ 152 | .data_bytes = 581, 153 | .apat = {6, 26, 46, 66, 0}, 154 | .ecc = { 155 | {.bs = 64, .dw = 40, .ns = 4}, 156 | {.bs = 145, .dw = 115, .ns = 3}, 157 | {.bs = 36, .dw = 12, .ns = 11}, 158 | {.bs = 36, .dw = 16, .ns = 11} 159 | } 160 | }, 161 | { /* Version 15 */ 162 | .data_bytes = 655, 163 | .apat = {6, 26, 48, 70, 0}, 164 | .ecc = { 165 | {.bs = 65, .dw = 41, .ns = 5}, 166 | {.bs = 109, .dw = 87, .ns = 5}, 167 | {.bs = 36, .dw = 12, .ns = 11}, 168 | {.bs = 54, .dw = 24, .ns = 5} 169 | } 170 | }, 171 | { /* Version 16 */ 172 | .data_bytes = 733, 173 | .apat = {6, 26, 50, 74, 0}, 174 | .ecc = { 175 | {.bs = 73, .dw = 45, .ns = 7}, 176 | {.bs = 122, .dw = 98, .ns = 5}, 177 | {.bs = 45, .dw = 15, .ns = 3}, 178 | {.bs = 43, .dw = 19, .ns = 15} 179 | } 180 | }, 181 | { /* Version 17 */ 182 | .data_bytes = 815, 183 | .apat = {6, 30, 54, 78, 0}, 184 | .ecc = { 185 | {.bs = 74, .dw = 46, .ns = 10}, 186 | {.bs = 135, .dw = 107, .ns = 1}, 187 | {.bs = 42, .dw = 14, .ns = 2}, 188 | {.bs = 50, .dw = 22, .ns = 1} 189 | } 190 | }, 191 | { /* Version 18 */ 192 | .data_bytes = 901, 193 | .apat = {6, 30, 56, 82, 0}, 194 | .ecc = { 195 | {.bs = 69, .dw = 43, .ns = 9}, 196 | {.bs = 150, .dw = 120, .ns = 5}, 197 | {.bs = 42, .dw = 14, .ns = 2}, 198 | {.bs = 50, .dw = 22, .ns = 17} 199 | } 200 | }, 201 | { /* Version 19 */ 202 | .data_bytes = 991, 203 | .apat = {6, 30, 58, 86, 0}, 204 | .ecc = { 205 | {.bs = 70, .dw = 44, .ns = 3}, 206 | {.bs = 141, .dw = 113, .ns = 3}, 207 | {.bs = 39, .dw = 13, .ns = 9}, 208 | {.bs = 47, .dw = 21, .ns = 17} 209 | } 210 | }, 211 | { /* Version 20 */ 212 | .data_bytes = 1085, 213 | .apat = {6, 34, 62, 90, 0}, 214 | .ecc = { 215 | {.bs = 67, .dw = 41, .ns = 3}, 216 | {.bs = 135, .dw = 107, .ns = 3}, 217 | {.bs = 43, .dw = 15, .ns = 15}, 218 | {.bs = 54, .dw = 24, .ns = 15} 219 | } 220 | }, 221 | { /* Version 21 */ 222 | .data_bytes = 1156, 223 | .apat = {6, 28, 50, 72, 92, 0}, 224 | .ecc = { 225 | {.bs = 68, .dw = 42, .ns = 17}, 226 | {.bs = 144, .dw = 116, .ns = 4}, 227 | {.bs = 46, .dw = 16, .ns = 19}, 228 | {.bs = 50, .dw = 22, .ns = 17} 229 | } 230 | }, 231 | { /* Version 22 */ 232 | .data_bytes = 1258, 233 | .apat = {6, 26, 50, 74, 98, 0}, 234 | .ecc = { 235 | {.bs = 74, .dw = 46, .ns = 17}, 236 | {.bs = 139, .dw = 111, .ns = 2}, 237 | {.bs = 37, .dw = 13, .ns = 34}, 238 | {.bs = 54, .dw = 24, .ns = 7} 239 | } 240 | }, 241 | { /* Version 23 */ 242 | .data_bytes = 1364, 243 | .apat = {6, 30, 54, 78, 102, 0}, 244 | .ecc = { 245 | {.bs = 75, .dw = 47, .ns = 4}, 246 | {.bs = 151, .dw = 121, .ns = 4}, 247 | {.bs = 45, .dw = 15, .ns = 16}, 248 | {.bs = 54, .dw = 24, .ns = 11} 249 | } 250 | }, 251 | { /* Version 24 */ 252 | .data_bytes = 1474, 253 | .apat = {6, 28, 54, 80, 106, 0}, 254 | .ecc = { 255 | {.bs = 73, .dw = 45, .ns = 6}, 256 | {.bs = 147, .dw = 117, .ns = 6}, 257 | {.bs = 46, .dw = 16, .ns = 30}, 258 | {.bs = 54, .dw = 24, .ns = 11} 259 | } 260 | }, 261 | { /* Version 25 */ 262 | .data_bytes = 1588, 263 | .apat = {6, 32, 58, 84, 110, 0}, 264 | .ecc = { 265 | {.bs = 75, .dw = 47, .ns = 8}, 266 | {.bs = 132, .dw = 106, .ns = 8}, 267 | {.bs = 45, .dw = 15, .ns = 22}, 268 | {.bs = 54, .dw = 24, .ns = 7} 269 | } 270 | }, 271 | { /* Version 26 */ 272 | .data_bytes = 1706, 273 | .apat = {6, 30, 58, 86, 114, 0}, 274 | .ecc = { 275 | {.bs = 74, .dw = 46, .ns = 19}, 276 | {.bs = 142, .dw = 114, .ns = 10}, 277 | {.bs = 46, .dw = 16, .ns = 33}, 278 | {.bs = 50, .dw = 22, .ns = 28} 279 | } 280 | }, 281 | { /* Version 27 */ 282 | .data_bytes = 1828, 283 | .apat = {6, 34, 62, 90, 118, 0}, 284 | .ecc = { 285 | {.bs = 73, .dw = 45, .ns = 22}, 286 | {.bs = 152, .dw = 122, .ns = 8}, 287 | {.bs = 45, .dw = 15, .ns = 12}, 288 | {.bs = 53, .dw = 23, .ns = 8} 289 | } 290 | }, 291 | { /* Version 28 */ 292 | .data_bytes = 1921, 293 | .apat = {6, 26, 50, 74, 98, 122, 0}, 294 | .ecc = { 295 | {.bs = 73, .dw = 45, .ns = 3}, 296 | {.bs = 147, .dw = 117, .ns = 3}, 297 | {.bs = 45, .dw = 15, .ns = 11}, 298 | {.bs = 54, .dw = 24, .ns = 4} 299 | } 300 | }, 301 | { /* Version 29 */ 302 | .data_bytes = 2051, 303 | .apat = {6, 30, 54, 78, 102, 126, 0}, 304 | .ecc = { 305 | {.bs = 73, .dw = 45, .ns = 21}, 306 | {.bs = 146, .dw = 116, .ns = 7}, 307 | {.bs = 45, .dw = 15, .ns = 19}, 308 | {.bs = 53, .dw = 23, .ns = 1} 309 | } 310 | }, 311 | { /* Version 30 */ 312 | .data_bytes = 2185, 313 | .apat = {6, 26, 52, 78, 104, 130, 0}, 314 | .ecc = { 315 | {.bs = 75, .dw = 47, .ns = 19}, 316 | {.bs = 145, .dw = 115, .ns = 5}, 317 | {.bs = 45, .dw = 15, .ns = 23}, 318 | {.bs = 54, .dw = 24, .ns = 15} 319 | } 320 | }, 321 | { /* Version 31 */ 322 | .data_bytes = 2323, 323 | .apat = {6, 30, 56, 82, 108, 134, 0}, 324 | .ecc = { 325 | {.bs = 74, .dw = 46, .ns = 2}, 326 | {.bs = 145, .dw = 115, .ns = 13}, 327 | {.bs = 45, .dw = 15, .ns = 23}, 328 | {.bs = 54, .dw = 24, .ns = 42} 329 | } 330 | }, 331 | { /* Version 32 */ 332 | .data_bytes = 2465, 333 | .apat = {6, 34, 60, 86, 112, 138, 0}, 334 | .ecc = { 335 | {.bs = 74, .dw = 46, .ns = 10}, 336 | {.bs = 145, .dw = 115, .ns = 17}, 337 | {.bs = 45, .dw = 15, .ns = 19}, 338 | {.bs = 54, .dw = 24, .ns = 10} 339 | } 340 | }, 341 | { /* Version 33 */ 342 | .data_bytes = 2611, 343 | .apat = {6, 30, 58, 86, 114, 142, 0}, 344 | .ecc = { 345 | {.bs = 74, .dw = 46, .ns = 14}, 346 | {.bs = 145, .dw = 115, .ns = 17}, 347 | {.bs = 45, .dw = 15, .ns = 11}, 348 | {.bs = 54, .dw = 24, .ns = 29} 349 | } 350 | }, 351 | { /* Version 34 */ 352 | .data_bytes = 2761, 353 | .apat = {6, 34, 62, 90, 118, 146, 0}, 354 | .ecc = { 355 | {.bs = 74, .dw = 46, .ns = 14}, 356 | {.bs = 145, .dw = 115, .ns = 13}, 357 | {.bs = 46, .dw = 16, .ns = 59}, 358 | {.bs = 54, .dw = 24, .ns = 44} 359 | } 360 | }, 361 | { /* Version 35 */ 362 | .data_bytes = 2876, 363 | .apat = {6, 30, 54, 78, 102, 126, 150}, 364 | .ecc = { 365 | {.bs = 75, .dw = 47, .ns = 12}, 366 | {.bs = 151, .dw = 121, .ns = 12}, 367 | {.bs = 45, .dw = 15, .ns = 22}, 368 | {.bs = 54, .dw = 24, .ns = 39} 369 | } 370 | }, 371 | { /* Version 36 */ 372 | .data_bytes = 3034, 373 | .apat = {6, 24, 50, 76, 102, 128, 154}, 374 | .ecc = { 375 | {.bs = 75, .dw = 47, .ns = 6}, 376 | {.bs = 151, .dw = 121, .ns = 6}, 377 | {.bs = 45, .dw = 15, .ns = 2}, 378 | {.bs = 54, .dw = 24, .ns = 46} 379 | } 380 | }, 381 | { /* Version 37 */ 382 | .data_bytes = 3196, 383 | .apat = {6, 28, 54, 80, 106, 132, 158}, 384 | .ecc = { 385 | {.bs = 74, .dw = 46, .ns = 29}, 386 | {.bs = 152, .dw = 122, .ns = 17}, 387 | {.bs = 45, .dw = 15, .ns = 24}, 388 | {.bs = 54, .dw = 24, .ns = 49} 389 | } 390 | }, 391 | { /* Version 38 */ 392 | .data_bytes = 3362, 393 | .apat = {6, 32, 58, 84, 110, 136, 162}, 394 | .ecc = { 395 | {.bs = 74, .dw = 46, .ns = 13}, 396 | {.bs = 152, .dw = 122, .ns = 4}, 397 | {.bs = 45, .dw = 15, .ns = 42}, 398 | {.bs = 54, .dw = 24, .ns = 48} 399 | } 400 | }, 401 | { /* Version 39 */ 402 | .data_bytes = 3532, 403 | .apat = {6, 26, 54, 82, 110, 138, 166}, 404 | .ecc = { 405 | {.bs = 75, .dw = 47, .ns = 40}, 406 | {.bs = 147, .dw = 117, .ns = 20}, 407 | {.bs = 45, .dw = 15, .ns = 10}, 408 | {.bs = 54, .dw = 24, .ns = 43} 409 | } 410 | }, 411 | { /* Version 40 */ 412 | .data_bytes = 3706, 413 | .apat = {6, 30, 58, 86, 114, 142, 170}, 414 | .ecc = { 415 | {.bs = 75, .dw = 47, .ns = 18}, 416 | {.bs = 148, .dw = 118, .ns = 19}, 417 | {.bs = 45, .dw = 15, .ns = 20}, 418 | {.bs = 54, .dw = 24, .ns = 34} 419 | } 420 | } 421 | }; 422 | -------------------------------------------------------------------------------- /lib/decode.c: -------------------------------------------------------------------------------- 1 | /* quirc -- QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 20 | #include 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 | static const 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; 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 | return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1; 413 | } 414 | 415 | static quirc_decode_error_t read_format(const struct quirc_code *code, 416 | struct quirc_data *data, int which) 417 | { 418 | int i; 419 | uint16_t format = 0; 420 | uint16_t fdata; 421 | quirc_decode_error_t err; 422 | 423 | if (which) { 424 | for (i = 0; i < 7; i++) 425 | format = (format << 1) | 426 | grid_bit(code, 8, code->size - 1 - i); 427 | for (i = 0; i < 8; i++) 428 | format = (format << 1) | 429 | grid_bit(code, code->size - 8 + i, 8); 430 | } else { 431 | static const int xs[15] = { 432 | 8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0 433 | }; 434 | static const int ys[15] = { 435 | 0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8 436 | }; 437 | 438 | for (i = 14; i >= 0; i--) 439 | format = (format << 1) | grid_bit(code, xs[i], ys[i]); 440 | } 441 | 442 | format ^= 0x5412; 443 | 444 | err = correct_format(&format); 445 | if (err) 446 | return err; 447 | 448 | fdata = format >> 10; 449 | data->ecc_level = fdata >> 3; 450 | data->mask = fdata & 7; 451 | 452 | return QUIRC_SUCCESS; 453 | } 454 | 455 | static int mask_bit(int mask, int i, int j) 456 | { 457 | switch (mask) { 458 | case 0: return !((i + j) % 2); 459 | case 1: return !(i % 2); 460 | case 2: return !(j % 3); 461 | case 3: return !((i + j) % 3); 462 | case 4: return !(((i / 2) + (j / 3)) % 2); 463 | case 5: return !((i * j) % 2 + (i * j) % 3); 464 | case 6: return !(((i * j) % 2 + (i * j) % 3) % 2); 465 | case 7: return !(((i * j) % 3 + (i + j) % 2) % 2); 466 | } 467 | 468 | return 0; 469 | } 470 | 471 | static int reserved_cell(int version, int i, int j) 472 | { 473 | const struct quirc_version_info *ver = &quirc_version_db[version]; 474 | int size = version * 4 + 17; 475 | int ai = -1, aj = -1, a; 476 | 477 | /* Finder + format: top left */ 478 | if (i < 9 && j < 9) 479 | return 1; 480 | 481 | /* Finder + format: bottom left */ 482 | if (i + 8 >= size && j < 9) 483 | return 1; 484 | 485 | /* Finder + format: top right */ 486 | if (i < 9 && j + 8 >= size) 487 | return 1; 488 | 489 | /* Exclude timing patterns */ 490 | if (i == 6 || j == 6) 491 | return 1; 492 | 493 | /* Exclude version info, if it exists. Version info sits adjacent to 494 | * the top-right and bottom-left finders in three rows, bounded by 495 | * the timing pattern. 496 | */ 497 | if (version >= 7) { 498 | if (i < 6 && j + 11 >= size) 499 | return 1; 500 | if (i + 11 >= size && j < 6) 501 | return 1; 502 | } 503 | 504 | /* Exclude alignment patterns */ 505 | for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++) { 506 | int p = ver->apat[a]; 507 | 508 | if (abs(p - i) < 3) 509 | ai = a; 510 | if (abs(p - j) < 3) 511 | aj = a; 512 | } 513 | 514 | if (ai >= 0 && aj >= 0) { 515 | a--; 516 | if (ai > 0 && ai < a) 517 | return 1; 518 | if (aj > 0 && aj < a) 519 | return 1; 520 | if (aj == a && ai == a) 521 | return 1; 522 | } 523 | 524 | return 0; 525 | } 526 | 527 | static void read_bit(const struct quirc_code *code, 528 | struct quirc_data *data, 529 | struct datastream *ds, int i, int j) 530 | { 531 | int bitpos = ds->data_bits & 7; 532 | int bytepos = ds->data_bits >> 3; 533 | int v = grid_bit(code, j, i); 534 | 535 | if (mask_bit(data->mask, i, j)) 536 | v ^= 1; 537 | 538 | if (v) 539 | ds->raw[bytepos] |= (0x80 >> bitpos); 540 | 541 | ds->data_bits++; 542 | } 543 | 544 | static void read_data(const struct quirc_code *code, 545 | struct quirc_data *data, 546 | struct datastream *ds) 547 | { 548 | int y = code->size - 1; 549 | int x = code->size - 1; 550 | int dir = -1; 551 | 552 | while (x > 0) { 553 | if (x == 6) 554 | x--; 555 | 556 | if (!reserved_cell(data->version, y, x)) 557 | read_bit(code, data, ds, y, x); 558 | 559 | if (!reserved_cell(data->version, y, x - 1)) 560 | read_bit(code, data, ds, y, x - 1); 561 | 562 | y += dir; 563 | if (y < 0 || y >= code->size) { 564 | dir = -dir; 565 | x -= 2; 566 | y += dir; 567 | } 568 | } 569 | } 570 | 571 | static quirc_decode_error_t codestream_ecc(struct quirc_data *data, 572 | struct datastream *ds) 573 | { 574 | const struct quirc_version_info *ver = 575 | &quirc_version_db[data->version]; 576 | const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level]; 577 | struct quirc_rs_params lb_ecc; 578 | const int lb_count = 579 | (ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1); 580 | const int bc = lb_count + sb_ecc->ns; 581 | const int ecc_offset = sb_ecc->dw * bc + lb_count; 582 | int dst_offset = 0; 583 | int i; 584 | 585 | memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc)); 586 | lb_ecc.dw++; 587 | lb_ecc.bs++; 588 | 589 | for (i = 0; i < bc; i++) { 590 | uint8_t *dst = ds->data + dst_offset; 591 | const struct quirc_rs_params *ecc = 592 | (i < sb_ecc->ns) ? sb_ecc : &lb_ecc; 593 | const int num_ec = ecc->bs - ecc->dw; 594 | quirc_decode_error_t err; 595 | int j; 596 | 597 | for (j = 0; j < ecc->dw; j++) 598 | dst[j] = ds->raw[j * bc + i]; 599 | for (j = 0; j < num_ec; j++) 600 | dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i]; 601 | 602 | err = correct_block(dst, ecc); 603 | if (err) 604 | return err; 605 | 606 | dst_offset += ecc->dw; 607 | } 608 | 609 | ds->data_bits = dst_offset * 8; 610 | 611 | return QUIRC_SUCCESS; 612 | } 613 | 614 | static inline int bits_remaining(const struct datastream *ds) 615 | { 616 | return ds->data_bits - ds->ptr; 617 | } 618 | 619 | static int take_bits(struct datastream *ds, int len) 620 | { 621 | int ret = 0; 622 | 623 | while (len && (ds->ptr < ds->data_bits)) { 624 | uint8_t b = ds->data[ds->ptr >> 3]; 625 | int bitpos = ds->ptr & 7; 626 | 627 | ret <<= 1; 628 | if ((b << bitpos) & 0x80) 629 | ret |= 1; 630 | 631 | ds->ptr++; 632 | len--; 633 | } 634 | 635 | return ret; 636 | } 637 | 638 | static int numeric_tuple(struct quirc_data *data, 639 | struct datastream *ds, 640 | int bits, int digits) 641 | { 642 | int tuple; 643 | int i; 644 | 645 | if (bits_remaining(ds) < bits) 646 | return -1; 647 | 648 | tuple = take_bits(ds, bits); 649 | 650 | for (i = digits - 1; i >= 0; i--) { 651 | data->payload[data->payload_len + i] = tuple % 10 + '0'; 652 | tuple /= 10; 653 | } 654 | 655 | data->payload_len += digits; 656 | return 0; 657 | } 658 | 659 | static quirc_decode_error_t decode_numeric(struct quirc_data *data, 660 | struct datastream *ds) 661 | { 662 | int bits = 14; 663 | int count; 664 | 665 | if (data->version < 10) 666 | bits = 10; 667 | else if (data->version < 27) 668 | bits = 12; 669 | 670 | count = take_bits(ds, bits); 671 | if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD) 672 | return QUIRC_ERROR_DATA_OVERFLOW; 673 | 674 | while (count >= 3) { 675 | if (numeric_tuple(data, ds, 10, 3) < 0) 676 | return QUIRC_ERROR_DATA_UNDERFLOW; 677 | count -= 3; 678 | } 679 | 680 | if (count >= 2) { 681 | if (numeric_tuple(data, ds, 7, 2) < 0) 682 | return QUIRC_ERROR_DATA_UNDERFLOW; 683 | count -= 2; 684 | } 685 | 686 | if (count) { 687 | if (numeric_tuple(data, ds, 4, 1) < 0) 688 | return QUIRC_ERROR_DATA_UNDERFLOW; 689 | count--; 690 | } 691 | 692 | return QUIRC_SUCCESS; 693 | } 694 | 695 | static int alpha_tuple(struct quirc_data *data, 696 | struct datastream *ds, 697 | int bits, int digits) 698 | { 699 | int tuple; 700 | int i; 701 | 702 | if (bits_remaining(ds) < bits) 703 | return -1; 704 | 705 | tuple = take_bits(ds, bits); 706 | 707 | for (i = 0; i < digits; i++) { 708 | static const char *alpha_map = 709 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; 710 | 711 | data->payload[data->payload_len + digits - i - 1] = 712 | alpha_map[tuple % 45]; 713 | tuple /= 45; 714 | } 715 | 716 | data->payload_len += digits; 717 | return 0; 718 | } 719 | 720 | static quirc_decode_error_t decode_alpha(struct quirc_data *data, 721 | struct datastream *ds) 722 | { 723 | int bits = 13; 724 | int count; 725 | 726 | if (data->version < 10) 727 | bits = 9; 728 | else if (data->version < 27) 729 | bits = 11; 730 | 731 | count = take_bits(ds, bits); 732 | if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD) 733 | return QUIRC_ERROR_DATA_OVERFLOW; 734 | 735 | while (count >= 2) { 736 | if (alpha_tuple(data, ds, 11, 2) < 0) 737 | return QUIRC_ERROR_DATA_UNDERFLOW; 738 | count -= 2; 739 | } 740 | 741 | if (count) { 742 | if (alpha_tuple(data, ds, 6, 1) < 0) 743 | return QUIRC_ERROR_DATA_UNDERFLOW; 744 | count--; 745 | } 746 | 747 | return QUIRC_SUCCESS; 748 | } 749 | 750 | static quirc_decode_error_t decode_byte(struct quirc_data *data, 751 | struct datastream *ds) 752 | { 753 | int bits = 16; 754 | int count; 755 | int i; 756 | 757 | if (data->version < 10) 758 | bits = 8; 759 | 760 | count = take_bits(ds, bits); 761 | if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD) 762 | return QUIRC_ERROR_DATA_OVERFLOW; 763 | if (bits_remaining(ds) < count * 8) 764 | return QUIRC_ERROR_DATA_UNDERFLOW; 765 | 766 | for (i = 0; i < count; i++) 767 | data->payload[data->payload_len++] = take_bits(ds, 8); 768 | 769 | return QUIRC_SUCCESS; 770 | } 771 | 772 | static quirc_decode_error_t decode_kanji(struct quirc_data *data, 773 | struct datastream *ds) 774 | { 775 | int bits = 12; 776 | int count; 777 | int i; 778 | 779 | if (data->version < 10) 780 | bits = 8; 781 | else if (data->version < 27) 782 | bits = 10; 783 | 784 | count = take_bits(ds, bits); 785 | if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD) 786 | return QUIRC_ERROR_DATA_OVERFLOW; 787 | if (bits_remaining(ds) < count * 13) 788 | return QUIRC_ERROR_DATA_UNDERFLOW; 789 | 790 | for (i = 0; i < count; i++) { 791 | int d = take_bits(ds, 13); 792 | int msB = d / 0xc0; 793 | int lsB = d % 0xc0; 794 | int intermediate = (msB << 8) | lsB; 795 | uint16_t sjw; 796 | 797 | if (intermediate + 0x8140 <= 0x9ffc) { 798 | /* bytes are in the range 0x8140 to 0x9FFC */ 799 | sjw = intermediate + 0x8140; 800 | } else { 801 | /* bytes are in the range 0xE040 to 0xEBBF */ 802 | sjw = intermediate + 0xc140; 803 | } 804 | 805 | data->payload[data->payload_len++] = sjw >> 8; 806 | data->payload[data->payload_len++] = sjw & 0xff; 807 | } 808 | 809 | return QUIRC_SUCCESS; 810 | } 811 | 812 | static quirc_decode_error_t decode_eci(struct quirc_data *data, 813 | struct datastream *ds) 814 | { 815 | if (bits_remaining(ds) < 8) 816 | return QUIRC_ERROR_DATA_UNDERFLOW; 817 | 818 | data->eci = take_bits(ds, 8); 819 | 820 | if ((data->eci & 0xc0) == 0x80) { 821 | if (bits_remaining(ds) < 8) 822 | return QUIRC_ERROR_DATA_UNDERFLOW; 823 | 824 | data->eci = (data->eci << 8) | take_bits(ds, 8); 825 | } else if ((data->eci & 0xe0) == 0xc0) { 826 | if (bits_remaining(ds) < 16) 827 | return QUIRC_ERROR_DATA_UNDERFLOW; 828 | 829 | data->eci = (data->eci << 16) | take_bits(ds, 16); 830 | } 831 | 832 | return QUIRC_SUCCESS; 833 | } 834 | 835 | static quirc_decode_error_t decode_payload(struct quirc_data *data, 836 | struct datastream *ds) 837 | { 838 | while (bits_remaining(ds) >= 4) { 839 | quirc_decode_error_t err = QUIRC_SUCCESS; 840 | int type = take_bits(ds, 4); 841 | 842 | switch (type) { 843 | case QUIRC_DATA_TYPE_NUMERIC: 844 | err = decode_numeric(data, ds); 845 | break; 846 | 847 | case QUIRC_DATA_TYPE_ALPHA: 848 | err = decode_alpha(data, ds); 849 | break; 850 | 851 | case QUIRC_DATA_TYPE_BYTE: 852 | err = decode_byte(data, ds); 853 | break; 854 | 855 | case QUIRC_DATA_TYPE_KANJI: 856 | err = decode_kanji(data, ds); 857 | break; 858 | 859 | case 7: 860 | err = decode_eci(data, ds); 861 | break; 862 | 863 | default: 864 | goto done; 865 | } 866 | 867 | if (err) 868 | return err; 869 | 870 | if (!(type & (type - 1)) && (type > data->data_type)) 871 | data->data_type = type; 872 | } 873 | done: 874 | 875 | /* Add nul terminator to all payloads */ 876 | if (data->payload_len >= (int) sizeof(data->payload)) 877 | data->payload_len--; 878 | data->payload[data->payload_len] = 0; 879 | 880 | return QUIRC_SUCCESS; 881 | } 882 | 883 | quirc_decode_error_t quirc_decode(const struct quirc_code *code, 884 | struct quirc_data *data) 885 | { 886 | quirc_decode_error_t err; 887 | struct datastream ds; 888 | 889 | if (code->size > QUIRC_MAX_GRID_SIZE) 890 | return QUIRC_ERROR_INVALID_GRID_SIZE; 891 | 892 | if ((code->size - 17) % 4) 893 | return QUIRC_ERROR_INVALID_GRID_SIZE; 894 | 895 | memset(data, 0, sizeof(*data)); 896 | memset(&ds, 0, sizeof(ds)); 897 | 898 | data->version = (code->size - 17) / 4; 899 | 900 | if (data->version < 1 || 901 | data->version > QUIRC_MAX_VERSION) 902 | return QUIRC_ERROR_INVALID_VERSION; 903 | 904 | /* Read format information -- try both locations */ 905 | err = read_format(code, data, 0); 906 | if (err) 907 | err = read_format(code, data, 1); 908 | if (err) 909 | return err; 910 | 911 | /* 912 | * Borrow data->payload to store the raw bits. 913 | * It's only used during read_data + coddestream_ecc below. 914 | * 915 | * This trick saves the size of struct datastream, which we allocate 916 | * on the stack. 917 | */ 918 | 919 | ds.raw = data->payload; 920 | 921 | read_data(code, data, &ds); 922 | err = codestream_ecc(data, &ds); 923 | if (err) 924 | return err; 925 | 926 | ds.raw = NULL; /* We've done with this buffer. */ 927 | 928 | err = decode_payload(data, &ds); 929 | if (err) 930 | return err; 931 | 932 | return QUIRC_SUCCESS; 933 | } 934 | 935 | void quirc_flip(struct quirc_code *code) 936 | { 937 | struct quirc_code flipped = {0}; 938 | unsigned int offset = 0; 939 | for (int y = 0; y < code->size; y++) { 940 | for (int x = 0; x < code->size; x++) { 941 | if (grid_bit(code, y, x)) { 942 | flipped.cell_bitmap[offset >> 3u] |= (1u << (offset & 7u)); 943 | } 944 | offset++; 945 | } 946 | } 947 | memcpy(&code->cell_bitmap, &flipped.cell_bitmap, sizeof(flipped.cell_bitmap)); 948 | } 949 | -------------------------------------------------------------------------------- /lib/identify.c: -------------------------------------------------------------------------------- 1 | /* quirc - QR-code recognition library 2 | * Copyright (C) 2010-2012 Daniel Beer 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 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "quirc_internal.h" 23 | 24 | /************************************************************************ 25 | * Linear algebra routines 26 | */ 27 | 28 | static int line_intersect(const struct quirc_point *p0, 29 | const struct quirc_point *p1, 30 | const struct quirc_point *q0, 31 | const struct quirc_point *q1, 32 | struct quirc_point *r) 33 | { 34 | /* (a, b) is perpendicular to line p */ 35 | int a = -(p1->y - p0->y); 36 | int b = p1->x - p0->x; 37 | 38 | /* (c, d) is perpendicular to line q */ 39 | int c = -(q1->y - q0->y); 40 | int d = q1->x - q0->x; 41 | 42 | /* e and f are dot products of the respective vectors with p and q */ 43 | int e = a * p1->x + b * p1->y; 44 | int f = c * q1->x + d * q1->y; 45 | 46 | /* Now we need to solve: 47 | * [a b] [rx] [e] 48 | * [c d] [ry] = [f] 49 | * 50 | * We do this by inverting the matrix and applying it to (e, f): 51 | * [ d -b] [e] [rx] 52 | * 1/det [-c a] [f] = [ry] 53 | */ 54 | int det = (a * d) - (b * c); 55 | 56 | if (!det) 57 | return 0; 58 | 59 | r->x = (d * e - b * f) / det; 60 | r->y = (-c * e + a * f) / det; 61 | 62 | return 1; 63 | } 64 | 65 | static void perspective_setup(double *c, 66 | const struct quirc_point *rect, 67 | double w, double h) 68 | { 69 | double x0 = rect[0].x; 70 | double y0 = rect[0].y; 71 | double x1 = rect[1].x; 72 | double y1 = rect[1].y; 73 | double x2 = rect[2].x; 74 | double y2 = rect[2].y; 75 | double x3 = rect[3].x; 76 | double y3 = rect[3].y; 77 | 78 | double wden = w * (x2*y3 - x3*y2 + (x3-x2)*y1 + x1*(y2-y3)); 79 | double hden = h * (x2*y3 + x1*(y2-y3) - x3*y2 + (x3-x2)*y1); 80 | 81 | c[0] = (x1*(x2*y3-x3*y2) + x0*(-x2*y3+x3*y2+(x2-x3)*y1) + 82 | x1*(x3-x2)*y0) / wden; 83 | c[1] = -(x0*(x2*y3+x1*(y2-y3)-x2*y1) - x1*x3*y2 + x2*x3*y1 84 | + (x1*x3-x2*x3)*y0) / hden; 85 | c[2] = x0; 86 | c[3] = (y0*(x1*(y3-y2)-x2*y3+x3*y2) + y1*(x2*y3-x3*y2) + 87 | x0*y1*(y2-y3)) / wden; 88 | c[4] = (x0*(y1*y3-y2*y3) + x1*y2*y3 - x2*y1*y3 + 89 | y0*(x3*y2-x1*y2+(x2-x3)*y1)) / hden; 90 | c[5] = y0; 91 | c[6] = (x1*(y3-y2) + x0*(y2-y3) + (x2-x3)*y1 + (x3-x2)*y0) / wden; 92 | c[7] = (-x2*y3 + x1*y3 + x3*y2 + x0*(y1-y2) - x3*y1 + (x2-x1)*y0) / 93 | hden; 94 | } 95 | 96 | static void perspective_map(const double *c, 97 | double u, double v, struct quirc_point *ret) 98 | { 99 | double den = c[6]*u + c[7]*v + 1.0; 100 | double x = (c[0]*u + c[1]*v + c[2]) / den; 101 | double y = (c[3]*u + c[4]*v + c[5]) / den; 102 | 103 | ret->x = (int) rint(x); 104 | ret->y = (int) rint(y); 105 | } 106 | 107 | static void perspective_unmap(const double *c, 108 | const struct quirc_point *in, 109 | double *u, double *v) 110 | { 111 | double x = in->x; 112 | double y = in->y; 113 | double den = -c[0]*c[7]*y + c[1]*c[6]*y + (c[3]*c[7]-c[4]*c[6])*x + 114 | c[0]*c[4] - c[1]*c[3]; 115 | 116 | *u = -(c[1]*(y-c[5]) - c[2]*c[7]*y + (c[5]*c[7]-c[4])*x + c[2]*c[4]) / 117 | den; 118 | *v = (c[0]*(y-c[5]) - c[2]*c[6]*y + (c[5]*c[6]-c[3])*x + c[2]*c[3]) / 119 | den; 120 | } 121 | 122 | /************************************************************************ 123 | * Span-based floodfill routine 124 | */ 125 | 126 | typedef void (*span_func_t)(void *user_data, int y, int left, int right); 127 | 128 | static void flood_fill_line(struct quirc *q, int x, int y, 129 | int from, int to, 130 | span_func_t func, void *user_data, 131 | int *leftp, int *rightp) 132 | { 133 | quirc_pixel_t *row; 134 | int left; 135 | int right; 136 | int i; 137 | 138 | row = q->pixels + y * q->w; 139 | QUIRC_ASSERT(row[x] == from); 140 | 141 | left = x; 142 | right = x; 143 | 144 | while (left > 0 && row[left - 1] == from) 145 | left--; 146 | 147 | while (right < q->w - 1 && row[right + 1] == from) 148 | right++; 149 | 150 | /* Fill the extent */ 151 | for (i = left; i <= right; i++) 152 | row[i] = to; 153 | 154 | /* Return the processed range */ 155 | *leftp = left; 156 | *rightp = right; 157 | 158 | if (func) 159 | func(user_data, y, left, right); 160 | } 161 | 162 | static struct quirc_flood_fill_vars *flood_fill_call_next( 163 | struct quirc *q, 164 | quirc_pixel_t *row, 165 | int from, int to, 166 | span_func_t func, void *user_data, 167 | struct quirc_flood_fill_vars *vars, 168 | int direction) 169 | { 170 | int *leftp; 171 | 172 | if (direction < 0) { 173 | leftp = &vars->left_up; 174 | } else { 175 | leftp = &vars->left_down; 176 | } 177 | 178 | while (*leftp <= vars->right) { 179 | if (row[*leftp] == from) { 180 | struct quirc_flood_fill_vars *next_vars; 181 | int next_left; 182 | 183 | /* Set up the next context */ 184 | next_vars = vars + 1; 185 | next_vars->y = vars->y + direction; 186 | 187 | /* Fill the extent */ 188 | flood_fill_line(q, 189 | *leftp, 190 | next_vars->y, 191 | from, to, 192 | func, user_data, 193 | &next_left, 194 | &next_vars->right); 195 | next_vars->left_down = next_left; 196 | next_vars->left_up = next_left; 197 | 198 | return next_vars; 199 | } 200 | (*leftp)++; 201 | } 202 | return NULL; 203 | } 204 | 205 | static void flood_fill_seed(struct quirc *q, 206 | int x0, int y0, 207 | int from, int to, 208 | span_func_t func, void *user_data) 209 | { 210 | struct quirc_flood_fill_vars *const stack = q->flood_fill_vars; 211 | const size_t stack_size = q->num_flood_fill_vars; 212 | const struct quirc_flood_fill_vars *const last_vars = 213 | &stack[stack_size - 1]; 214 | 215 | QUIRC_ASSERT(from != to); 216 | QUIRC_ASSERT(q->pixels[y0 * q->w + x0] == from); 217 | 218 | struct quirc_flood_fill_vars *next_vars; 219 | int next_left; 220 | 221 | /* Set up the first context */ 222 | next_vars = stack; 223 | next_vars->y = y0; 224 | 225 | /* Fill the extent */ 226 | flood_fill_line(q, x0, next_vars->y, from, to, 227 | func, user_data, 228 | &next_left, &next_vars->right); 229 | next_vars->left_down = next_left; 230 | next_vars->left_up = next_left; 231 | 232 | while (true) { 233 | struct quirc_flood_fill_vars * const vars = next_vars; 234 | quirc_pixel_t *row; 235 | 236 | if (vars == last_vars) { 237 | /* 238 | * "Stack overflow". 239 | * Just stop and return. 240 | * This can be caused by very complex shapes in 241 | * the image, which is not likely a part of 242 | * a valid QR code anyway. 243 | */ 244 | break; 245 | } 246 | 247 | /* Seed new flood-fills */ 248 | if (vars->y > 0) { 249 | row = q->pixels + (vars->y - 1) * q->w; 250 | 251 | next_vars = flood_fill_call_next(q, row, 252 | from, to, 253 | func, user_data, 254 | vars, -1); 255 | if (next_vars != NULL) { 256 | continue; 257 | } 258 | } 259 | 260 | if (vars->y < q->h - 1) { 261 | row = q->pixels + (vars->y + 1) * q->w; 262 | 263 | next_vars = flood_fill_call_next(q, row, 264 | from, to, 265 | func, user_data, 266 | vars, 1); 267 | if (next_vars != NULL) { 268 | continue; 269 | } 270 | } 271 | 272 | if (vars > stack) { 273 | /* Restore the previous context */ 274 | next_vars = vars - 1; 275 | continue; 276 | } 277 | 278 | /* We've done. */ 279 | break; 280 | } 281 | } 282 | 283 | /************************************************************************ 284 | * Adaptive thresholding 285 | */ 286 | 287 | static uint8_t otsu(const struct quirc *q) 288 | { 289 | unsigned int numPixels = q->w * q->h; 290 | 291 | // Calculate histogram 292 | unsigned int histogram[UINT8_MAX + 1]; 293 | (void)memset(histogram, 0, sizeof(histogram)); 294 | uint8_t* ptr = q->image; 295 | unsigned int length = numPixels; 296 | while (length--) { 297 | uint8_t value = *ptr++; 298 | histogram[value]++; 299 | } 300 | 301 | // Calculate weighted sum of histogram values 302 | double sum = 0; 303 | unsigned int i = 0; 304 | for (i = 0; i <= UINT8_MAX; ++i) { 305 | sum += i * histogram[i]; 306 | } 307 | 308 | // Compute threshold 309 | double sumB = 0; 310 | unsigned int q1 = 0; 311 | double max = 0; 312 | uint8_t threshold = 0; 313 | for (i = 0; i <= UINT8_MAX; ++i) { 314 | // Weighted background 315 | q1 += histogram[i]; 316 | if (q1 == 0) 317 | continue; 318 | 319 | // Weighted foreground 320 | const unsigned int q2 = numPixels - q1; 321 | if (q2 == 0) 322 | break; 323 | 324 | sumB += i * histogram[i]; 325 | const double m1 = sumB / q1; 326 | const double m2 = (sum - sumB) / q2; 327 | const double m1m2 = m1 - m2; 328 | const double variance = m1m2 * m1m2 * q1 * q2; 329 | if (variance >= max) { 330 | threshold = i; 331 | max = variance; 332 | } 333 | } 334 | 335 | return threshold; 336 | } 337 | 338 | static void area_count(void *user_data, int y, int left, int right) 339 | { 340 | ((struct quirc_region *)user_data)->count += right - left + 1; 341 | } 342 | 343 | static int region_code(struct quirc *q, int x, int y) 344 | { 345 | int pixel; 346 | struct quirc_region *box; 347 | int region; 348 | 349 | if (x < 0 || y < 0 || x >= q->w || y >= q->h) 350 | return -1; 351 | 352 | pixel = q->pixels[y * q->w + x]; 353 | 354 | if (pixel >= QUIRC_PIXEL_REGION) 355 | return pixel; 356 | 357 | if (pixel == QUIRC_PIXEL_WHITE) 358 | return -1; 359 | 360 | if (q->num_regions >= QUIRC_MAX_REGIONS) 361 | return -1; 362 | 363 | region = q->num_regions; 364 | box = &q->regions[q->num_regions++]; 365 | 366 | memset(box, 0, sizeof(*box)); 367 | 368 | box->seed.x = x; 369 | box->seed.y = y; 370 | box->capstone = -1; 371 | 372 | flood_fill_seed(q, x, y, pixel, region, area_count, box); 373 | 374 | return region; 375 | } 376 | 377 | struct polygon_score_data { 378 | struct quirc_point ref; 379 | 380 | int scores[4]; 381 | struct quirc_point *corners; 382 | }; 383 | 384 | static void find_one_corner(void *user_data, int y, int left, int right) 385 | { 386 | struct polygon_score_data *psd = 387 | (struct polygon_score_data *)user_data; 388 | int xs[2] = {left, right}; 389 | int dy = y - psd->ref.y; 390 | int i; 391 | 392 | for (i = 0; i < 2; i++) { 393 | int dx = xs[i] - psd->ref.x; 394 | int d = dx * dx + dy * dy; 395 | 396 | if (d > psd->scores[0]) { 397 | psd->scores[0] = d; 398 | psd->corners[0].x = xs[i]; 399 | psd->corners[0].y = y; 400 | } 401 | } 402 | } 403 | 404 | static void find_other_corners(void *user_data, int y, int left, int right) 405 | { 406 | struct polygon_score_data *psd = 407 | (struct polygon_score_data *)user_data; 408 | int xs[2] = {left, right}; 409 | int i; 410 | 411 | for (i = 0; i < 2; i++) { 412 | int up = xs[i] * psd->ref.x + y * psd->ref.y; 413 | int right = xs[i] * -psd->ref.y + y * psd->ref.x; 414 | int scores[4] = {up, right, -up, -right}; 415 | int j; 416 | 417 | for (j = 0; j < 4; j++) { 418 | if (scores[j] > psd->scores[j]) { 419 | psd->scores[j] = scores[j]; 420 | psd->corners[j].x = xs[i]; 421 | psd->corners[j].y = y; 422 | } 423 | } 424 | } 425 | } 426 | 427 | static void find_region_corners(struct quirc *q, 428 | int rcode, const struct quirc_point *ref, 429 | struct quirc_point *corners) 430 | { 431 | struct quirc_region *region = &q->regions[rcode]; 432 | struct polygon_score_data psd; 433 | int i; 434 | 435 | memset(&psd, 0, sizeof(psd)); 436 | psd.corners = corners; 437 | 438 | memcpy(&psd.ref, ref, sizeof(psd.ref)); 439 | psd.scores[0] = -1; 440 | flood_fill_seed(q, region->seed.x, region->seed.y, 441 | rcode, QUIRC_PIXEL_BLACK, 442 | find_one_corner, &psd); 443 | 444 | psd.ref.x = psd.corners[0].x - psd.ref.x; 445 | psd.ref.y = psd.corners[0].y - psd.ref.y; 446 | 447 | for (i = 0; i < 4; i++) 448 | memcpy(&psd.corners[i], ®ion->seed, 449 | sizeof(psd.corners[i])); 450 | 451 | i = region->seed.x * psd.ref.x + region->seed.y * psd.ref.y; 452 | psd.scores[0] = i; 453 | psd.scores[2] = -i; 454 | i = region->seed.x * -psd.ref.y + region->seed.y * psd.ref.x; 455 | psd.scores[1] = i; 456 | psd.scores[3] = -i; 457 | 458 | flood_fill_seed(q, region->seed.x, region->seed.y, 459 | QUIRC_PIXEL_BLACK, rcode, 460 | find_other_corners, &psd); 461 | } 462 | 463 | static void record_capstone(struct quirc *q, int ring, int stone) 464 | { 465 | struct quirc_region *stone_reg = &q->regions[stone]; 466 | struct quirc_region *ring_reg = &q->regions[ring]; 467 | struct quirc_capstone *capstone; 468 | int cs_index; 469 | 470 | if (q->num_capstones >= QUIRC_MAX_CAPSTONES) 471 | return; 472 | 473 | cs_index = q->num_capstones; 474 | capstone = &q->capstones[q->num_capstones++]; 475 | 476 | memset(capstone, 0, sizeof(*capstone)); 477 | 478 | capstone->qr_grid = -1; 479 | capstone->ring = ring; 480 | capstone->stone = stone; 481 | stone_reg->capstone = cs_index; 482 | ring_reg->capstone = cs_index; 483 | 484 | /* Find the corners of the ring */ 485 | find_region_corners(q, ring, &stone_reg->seed, capstone->corners); 486 | 487 | /* Set up the perspective transform and find the center */ 488 | perspective_setup(capstone->c, capstone->corners, 7.0, 7.0); 489 | perspective_map(capstone->c, 3.5, 3.5, &capstone->center); 490 | } 491 | 492 | static void test_capstone(struct quirc *q, unsigned int x, unsigned int y, 493 | unsigned int *pb) 494 | { 495 | int ring_right = region_code(q, x - pb[4], y); 496 | int stone = region_code(q, x - pb[4] - pb[3] - pb[2], y); 497 | int ring_left = region_code(q, x - pb[4] - pb[3] - 498 | pb[2] - pb[1] - pb[0], 499 | y); 500 | struct quirc_region *stone_reg; 501 | struct quirc_region *ring_reg; 502 | unsigned int ratio; 503 | 504 | if (ring_left < 0 || ring_right < 0 || stone < 0) 505 | return; 506 | 507 | /* Left and ring of ring should be connected */ 508 | if (ring_left != ring_right) 509 | return; 510 | 511 | /* Ring should be disconnected from stone */ 512 | if (ring_left == stone) 513 | return; 514 | 515 | stone_reg = &q->regions[stone]; 516 | ring_reg = &q->regions[ring_left]; 517 | 518 | /* Already detected */ 519 | if (stone_reg->capstone >= 0 || ring_reg->capstone >= 0) 520 | return; 521 | 522 | /* Ratio should ideally be 37.5 */ 523 | ratio = stone_reg->count * 100 / ring_reg->count; 524 | if (ratio < 10 || ratio > 70) 525 | return; 526 | 527 | record_capstone(q, ring_left, stone); 528 | } 529 | 530 | static void finder_scan(struct quirc *q, unsigned int y) 531 | { 532 | quirc_pixel_t *row = q->pixels + y * q->w; 533 | unsigned int x; 534 | int last_color = 0; 535 | unsigned int run_length = 0; 536 | unsigned int run_count = 0; 537 | unsigned int pb[5]; 538 | 539 | memset(pb, 0, sizeof(pb)); 540 | for (x = 0; x < q->w; x++) { 541 | int color = row[x] ? 1 : 0; 542 | 543 | if (x && color != last_color) { 544 | memmove(pb, pb + 1, sizeof(pb[0]) * 4); 545 | pb[4] = run_length; 546 | run_length = 0; 547 | run_count++; 548 | 549 | if (!color && run_count >= 5) { 550 | const int scale = 16; 551 | static const unsigned int check[5] = {1, 1, 3, 1, 1}; 552 | unsigned int avg, err; 553 | unsigned int i; 554 | int ok = 1; 555 | 556 | avg = (pb[0] + pb[1] + pb[3] + pb[4]) * scale / 4; 557 | err = avg * 3 / 4; 558 | 559 | for (i = 0; i < 5; i++) 560 | if (pb[i] * scale < check[i] * avg - err || 561 | pb[i] * scale > check[i] * avg + err) 562 | ok = 0; 563 | 564 | if (ok) 565 | test_capstone(q, x, y, pb); 566 | } 567 | } 568 | 569 | run_length++; 570 | last_color = color; 571 | } 572 | } 573 | 574 | static void find_alignment_pattern(struct quirc *q, int index) 575 | { 576 | struct quirc_grid *qr = &q->grids[index]; 577 | struct quirc_capstone *c0 = &q->capstones[qr->caps[0]]; 578 | struct quirc_capstone *c2 = &q->capstones[qr->caps[2]]; 579 | struct quirc_point a; 580 | struct quirc_point b; 581 | struct quirc_point c; 582 | int size_estimate; 583 | int step_size = 1; 584 | int dir = 0; 585 | double u, v; 586 | 587 | /* Grab our previous estimate of the alignment pattern corner */ 588 | memcpy(&b, &qr->align, sizeof(b)); 589 | 590 | /* Guess another two corners of the alignment pattern so that we 591 | * can estimate its size. 592 | */ 593 | perspective_unmap(c0->c, &b, &u, &v); 594 | perspective_map(c0->c, u, v + 1.0, &a); 595 | perspective_unmap(c2->c, &b, &u, &v); 596 | perspective_map(c2->c, u + 1.0, v, &c); 597 | 598 | size_estimate = abs((a.x - b.x) * -(c.y - b.y) + 599 | (a.y - b.y) * (c.x - b.x)); 600 | 601 | /* Spiral outwards from the estimate point until we find something 602 | * roughly the right size. Don't look too far from the estimate 603 | * point. 604 | */ 605 | while (step_size * step_size < size_estimate * 100) { 606 | static const int dx_map[] = {1, 0, -1, 0}; 607 | static const int dy_map[] = {0, -1, 0, 1}; 608 | int i; 609 | 610 | for (i = 0; i < step_size; i++) { 611 | int code = region_code(q, b.x, b.y); 612 | 613 | if (code >= 0) { 614 | struct quirc_region *reg = &q->regions[code]; 615 | 616 | if (reg->count >= size_estimate / 2 && 617 | reg->count <= size_estimate * 2) { 618 | qr->align_region = code; 619 | return; 620 | } 621 | } 622 | 623 | b.x += dx_map[dir]; 624 | b.y += dy_map[dir]; 625 | } 626 | 627 | dir = (dir + 1) % 4; 628 | if (!(dir & 1)) 629 | step_size++; 630 | } 631 | } 632 | 633 | static void find_leftmost_to_line(void *user_data, int y, int left, int right) 634 | { 635 | struct polygon_score_data *psd = 636 | (struct polygon_score_data *)user_data; 637 | int xs[2] = {left, right}; 638 | int i; 639 | 640 | for (i = 0; i < 2; i++) { 641 | int d = -psd->ref.y * xs[i] + psd->ref.x * y; 642 | 643 | if (d < psd->scores[0]) { 644 | psd->scores[0] = d; 645 | psd->corners[0].x = xs[i]; 646 | psd->corners[0].y = y; 647 | } 648 | } 649 | } 650 | 651 | static double length(struct quirc_point a, struct quirc_point b) 652 | { 653 | double x = abs(a.x - b.x) + 1; 654 | double y = abs(a.y - b.y) + 1; 655 | return sqrt(x * x + y * y); 656 | } 657 | /* Estimate grid size by determing distance between capstones 658 | */ 659 | static void measure_grid_size(struct quirc *q, int index) 660 | { 661 | struct quirc_grid *qr = &q->grids[index]; 662 | 663 | struct quirc_capstone *a = &(q->capstones[qr->caps[0]]); 664 | struct quirc_capstone *b = &(q->capstones[qr->caps[1]]); 665 | struct quirc_capstone *c = &(q->capstones[qr->caps[2]]); 666 | 667 | double ab = length(b->corners[0], a->corners[3]); 668 | double capstone_ab_size = (length(b->corners[0], b->corners[3]) + length(a->corners[0], a->corners[3]))/2.0; 669 | double ver_grid = 7.0 * ab / capstone_ab_size; 670 | 671 | double bc = length(b->corners[0], c->corners[1]); 672 | double capstone_bc_size = (length(b->corners[0], b->corners[1]) + length(c->corners[0], c->corners[1]))/2.0; 673 | double hor_grid = 7.0 * bc / capstone_bc_size; 674 | 675 | double grid_size_estimate = (ver_grid + hor_grid) / 2; 676 | 677 | int ver = (int)((grid_size_estimate - 17.0 + 2.0) / 4.0); 678 | 679 | qr->grid_size = 4*ver + 17; 680 | } 681 | 682 | /* Read a cell from a grid using the currently set perspective 683 | * transform. Returns +/- 1 for black/white, 0 for cells which are 684 | * out of image bounds. 685 | */ 686 | static int read_cell(const struct quirc *q, int index, int x, int y) 687 | { 688 | const struct quirc_grid *qr = &q->grids[index]; 689 | struct quirc_point p; 690 | 691 | perspective_map(qr->c, x + 0.5, y + 0.5, &p); 692 | if (p.y < 0 || p.y >= q->h || p.x < 0 || p.x >= q->w) 693 | return 0; 694 | 695 | return q->pixels[p.y * q->w + p.x] ? 1 : -1; 696 | } 697 | 698 | static int fitness_cell(const struct quirc *q, int index, int x, int y) 699 | { 700 | const struct quirc_grid *qr = &q->grids[index]; 701 | int score = 0; 702 | int u, v; 703 | 704 | for (v = 0; v < 3; v++) 705 | for (u = 0; u < 3; u++) { 706 | static const double offsets[] = {0.3, 0.5, 0.7}; 707 | struct quirc_point p; 708 | 709 | perspective_map(qr->c, x + offsets[u], 710 | y + offsets[v], &p); 711 | if (p.y < 0 || p.y >= q->h || p.x < 0 || p.x >= q->w) 712 | continue; 713 | 714 | if (q->pixels[p.y * q->w + p.x]) 715 | score++; 716 | else 717 | score--; 718 | } 719 | 720 | return score; 721 | } 722 | 723 | static int fitness_ring(const struct quirc *q, int index, int cx, int cy, 724 | int radius) 725 | { 726 | int i; 727 | int score = 0; 728 | 729 | for (i = 0; i < radius * 2; i++) { 730 | score += fitness_cell(q, index, cx - radius + i, cy - radius); 731 | score += fitness_cell(q, index, cx - radius, cy + radius - i); 732 | score += fitness_cell(q, index, cx + radius, cy - radius + i); 733 | score += fitness_cell(q, index, cx + radius - i, cy + radius); 734 | } 735 | 736 | return score; 737 | } 738 | 739 | static int fitness_apat(const struct quirc *q, int index, int cx, int cy) 740 | { 741 | return fitness_cell(q, index, cx, cy) - 742 | fitness_ring(q, index, cx, cy, 1) + 743 | fitness_ring(q, index, cx, cy, 2); 744 | } 745 | 746 | static int fitness_capstone(const struct quirc *q, int index, int x, int y) 747 | { 748 | x += 3; 749 | y += 3; 750 | 751 | return fitness_cell(q, index, x, y) + 752 | fitness_ring(q, index, x, y, 1) - 753 | fitness_ring(q, index, x, y, 2) + 754 | fitness_ring(q, index, x, y, 3); 755 | } 756 | 757 | /* Compute a fitness score for the currently configured perspective 758 | * transform, using the features we expect to find by scanning the 759 | * grid. 760 | */ 761 | static int fitness_all(const struct quirc *q, int index) 762 | { 763 | const struct quirc_grid *qr = &q->grids[index]; 764 | int version = (qr->grid_size - 17) / 4; 765 | const struct quirc_version_info *info = &quirc_version_db[version]; 766 | int score = 0; 767 | int i, j; 768 | int ap_count; 769 | 770 | /* Check the timing pattern */ 771 | for (i = 0; i < qr->grid_size - 14; i++) { 772 | int expect = (i & 1) ? 1 : -1; 773 | 774 | score += fitness_cell(q, index, i + 7, 6) * expect; 775 | score += fitness_cell(q, index, 6, i + 7) * expect; 776 | } 777 | 778 | /* Check capstones */ 779 | score += fitness_capstone(q, index, 0, 0); 780 | score += fitness_capstone(q, index, qr->grid_size - 7, 0); 781 | score += fitness_capstone(q, index, 0, qr->grid_size - 7); 782 | 783 | if (version < 0 || version > QUIRC_MAX_VERSION) 784 | return score; 785 | 786 | /* Check alignment patterns */ 787 | ap_count = 0; 788 | while ((ap_count < QUIRC_MAX_ALIGNMENT) && info->apat[ap_count]) 789 | ap_count++; 790 | 791 | for (i = 1; i + 1 < ap_count; i++) { 792 | score += fitness_apat(q, index, 6, info->apat[i]); 793 | score += fitness_apat(q, index, info->apat[i], 6); 794 | } 795 | 796 | for (i = 1; i < ap_count; i++) 797 | for (j = 1; j < ap_count; j++) 798 | score += fitness_apat(q, index, 799 | info->apat[i], info->apat[j]); 800 | 801 | return score; 802 | } 803 | 804 | static void jiggle_perspective(struct quirc *q, int index) 805 | { 806 | struct quirc_grid *qr = &q->grids[index]; 807 | int best = fitness_all(q, index); 808 | int pass; 809 | double adjustments[8]; 810 | int i; 811 | 812 | for (i = 0; i < 8; i++) 813 | adjustments[i] = qr->c[i] * 0.02; 814 | 815 | for (pass = 0; pass < 5; pass++) { 816 | for (i = 0; i < 16; i++) { 817 | int j = i >> 1; 818 | int test; 819 | double old = qr->c[j]; 820 | double step = adjustments[j]; 821 | double new; 822 | 823 | if (i & 1) 824 | new = old + step; 825 | else 826 | new = old - step; 827 | 828 | qr->c[j] = new; 829 | test = fitness_all(q, index); 830 | 831 | if (test > best) 832 | best = test; 833 | else 834 | qr->c[j] = old; 835 | } 836 | 837 | for (i = 0; i < 8; i++) 838 | adjustments[i] *= 0.5; 839 | } 840 | } 841 | 842 | /* Once the capstones are in place and an alignment point has been 843 | * chosen, we call this function to set up a grid-reading perspective 844 | * transform. 845 | */ 846 | static void setup_qr_perspective(struct quirc *q, int index) 847 | { 848 | struct quirc_grid *qr = &q->grids[index]; 849 | struct quirc_point rect[4]; 850 | 851 | /* Set up the perspective map for reading the grid */ 852 | memcpy(&rect[0], &q->capstones[qr->caps[1]].corners[0], 853 | sizeof(rect[0])); 854 | memcpy(&rect[1], &q->capstones[qr->caps[2]].corners[0], 855 | sizeof(rect[0])); 856 | memcpy(&rect[2], &qr->align, sizeof(rect[0])); 857 | memcpy(&rect[3], &q->capstones[qr->caps[0]].corners[0], 858 | sizeof(rect[0])); 859 | perspective_setup(qr->c, rect, qr->grid_size - 7, qr->grid_size - 7); 860 | 861 | jiggle_perspective(q, index); 862 | } 863 | 864 | /* Rotate the capstone with so that corner 0 is the leftmost with respect 865 | * to the given reference line. 866 | */ 867 | static void rotate_capstone(struct quirc_capstone *cap, 868 | const struct quirc_point *h0, 869 | const struct quirc_point *hd) 870 | { 871 | struct quirc_point copy[4]; 872 | int j; 873 | int best = 0; 874 | int best_score = INT_MAX; 875 | 876 | for (j = 0; j < 4; j++) { 877 | struct quirc_point *p = &cap->corners[j]; 878 | int score = (p->x - h0->x) * -hd->y + 879 | (p->y - h0->y) * hd->x; 880 | 881 | if (!j || score < best_score) { 882 | best = j; 883 | best_score = score; 884 | } 885 | } 886 | 887 | /* Rotate the capstone */ 888 | for (j = 0; j < 4; j++) 889 | memcpy(©[j], &cap->corners[(j + best) % 4], 890 | sizeof(copy[j])); 891 | memcpy(cap->corners, copy, sizeof(cap->corners)); 892 | perspective_setup(cap->c, cap->corners, 7.0, 7.0); 893 | } 894 | 895 | static void record_qr_grid(struct quirc *q, int a, int b, int c) 896 | { 897 | struct quirc_point h0, hd; 898 | int i; 899 | int qr_index; 900 | struct quirc_grid *qr; 901 | 902 | if (q->num_grids >= QUIRC_MAX_GRIDS) 903 | return; 904 | 905 | /* Construct the hypotenuse line from A to C. B should be to 906 | * the left of this line. 907 | */ 908 | memcpy(&h0, &q->capstones[a].center, sizeof(h0)); 909 | hd.x = q->capstones[c].center.x - q->capstones[a].center.x; 910 | hd.y = q->capstones[c].center.y - q->capstones[a].center.y; 911 | 912 | /* Make sure A-B-C is clockwise */ 913 | if ((q->capstones[b].center.x - h0.x) * -hd.y + 914 | (q->capstones[b].center.y - h0.y) * hd.x > 0) { 915 | int swap = a; 916 | 917 | a = c; 918 | c = swap; 919 | hd.x = -hd.x; 920 | hd.y = -hd.y; 921 | } 922 | 923 | /* Record the grid and its components */ 924 | qr_index = q->num_grids; 925 | qr = &q->grids[q->num_grids++]; 926 | 927 | memset(qr, 0, sizeof(*qr)); 928 | qr->caps[0] = a; 929 | qr->caps[1] = b; 930 | qr->caps[2] = c; 931 | qr->align_region = -1; 932 | 933 | /* Rotate each capstone so that corner 0 is top-left with respect 934 | * to the grid. 935 | */ 936 | for (i = 0; i < 3; i++) { 937 | struct quirc_capstone *cap = &q->capstones[qr->caps[i]]; 938 | 939 | rotate_capstone(cap, &h0, &hd); 940 | cap->qr_grid = qr_index; 941 | } 942 | 943 | /* Check the timing pattern by measuring grid size. This doesn't require a perspective 944 | * transform. 945 | */ 946 | measure_grid_size(q, qr_index); 947 | /* Make an estimate based for the alignment pattern based on extending 948 | * lines from capstones A and C. 949 | */ 950 | if (!line_intersect(&q->capstones[a].corners[0], 951 | &q->capstones[a].corners[1], 952 | &q->capstones[c].corners[0], 953 | &q->capstones[c].corners[3], 954 | &qr->align)) 955 | goto fail; 956 | 957 | /* On V2+ grids, we should use the alignment pattern. */ 958 | if (qr->grid_size > 21) { 959 | /* Try to find the actual location of the alignment pattern. */ 960 | find_alignment_pattern(q, qr_index); 961 | 962 | /* Find the point of the alignment pattern closest to the 963 | * top-left of the QR grid. 964 | */ 965 | if (qr->align_region >= 0) { 966 | struct polygon_score_data psd; 967 | struct quirc_region *reg = 968 | &q->regions[qr->align_region]; 969 | 970 | /* Start from some point inside the alignment pattern */ 971 | memcpy(&qr->align, ®->seed, sizeof(qr->align)); 972 | 973 | memcpy(&psd.ref, &hd, sizeof(psd.ref)); 974 | psd.corners = &qr->align; 975 | psd.scores[0] = -hd.y * qr->align.x + 976 | hd.x * qr->align.y; 977 | 978 | flood_fill_seed(q, reg->seed.x, reg->seed.y, 979 | qr->align_region, QUIRC_PIXEL_BLACK, 980 | NULL, NULL); 981 | flood_fill_seed(q, reg->seed.x, reg->seed.y, 982 | QUIRC_PIXEL_BLACK, qr->align_region, 983 | find_leftmost_to_line, &psd); 984 | } 985 | } 986 | 987 | setup_qr_perspective(q, qr_index); 988 | return; 989 | 990 | fail: 991 | /* We've been unable to complete setup for this grid. Undo what we've 992 | * recorded and pretend it never happened. 993 | */ 994 | for (i = 0; i < 3; i++) 995 | q->capstones[qr->caps[i]].qr_grid = -1; 996 | q->num_grids--; 997 | } 998 | 999 | struct neighbour { 1000 | int index; 1001 | double distance; 1002 | }; 1003 | 1004 | struct neighbour_list { 1005 | struct neighbour n[QUIRC_MAX_CAPSTONES]; 1006 | int count; 1007 | }; 1008 | 1009 | static void test_neighbours(struct quirc *q, int i, 1010 | const struct neighbour_list *hlist, 1011 | const struct neighbour_list *vlist) 1012 | { 1013 | /* Test each possible grouping */ 1014 | for (int j = 0; j < hlist->count; j++) { 1015 | const struct neighbour *hn = &hlist->n[j]; 1016 | for (int k = 0; k < vlist->count; k++) { 1017 | const struct neighbour *vn = &vlist->n[k]; 1018 | double squareness = fabs(1.0 - hn->distance / vn->distance); 1019 | if (squareness < 0.2) 1020 | record_qr_grid(q, hn->index, i, vn->index); 1021 | } 1022 | } 1023 | } 1024 | 1025 | static void test_grouping(struct quirc *q, unsigned int i) 1026 | { 1027 | struct quirc_capstone *c1 = &q->capstones[i]; 1028 | int j; 1029 | struct neighbour_list hlist; 1030 | struct neighbour_list vlist; 1031 | 1032 | hlist.count = 0; 1033 | vlist.count = 0; 1034 | 1035 | /* Look for potential neighbours by examining the relative gradients 1036 | * from this capstone to others. 1037 | */ 1038 | for (j = 0; j < q->num_capstones; j++) { 1039 | struct quirc_capstone *c2 = &q->capstones[j]; 1040 | double u, v; 1041 | 1042 | if (i == j) 1043 | continue; 1044 | 1045 | perspective_unmap(c1->c, &c2->center, &u, &v); 1046 | 1047 | u = fabs(u - 3.5); 1048 | v = fabs(v - 3.5); 1049 | 1050 | if (u < 0.2 * v) { 1051 | struct neighbour *n = &hlist.n[hlist.count++]; 1052 | 1053 | n->index = j; 1054 | n->distance = v; 1055 | } 1056 | 1057 | if (v < 0.2 * u) { 1058 | struct neighbour *n = &vlist.n[vlist.count++]; 1059 | 1060 | n->index = j; 1061 | n->distance = u; 1062 | } 1063 | } 1064 | 1065 | if (!(hlist.count && vlist.count)) 1066 | return; 1067 | 1068 | test_neighbours(q, i, &hlist, &vlist); 1069 | } 1070 | 1071 | static void pixels_setup(struct quirc *q, uint8_t threshold) 1072 | { 1073 | if (QUIRC_PIXEL_ALIAS_IMAGE) { 1074 | q->pixels = (quirc_pixel_t *)q->image; 1075 | } 1076 | 1077 | uint8_t* source = q->image; 1078 | quirc_pixel_t* dest = q->pixels; 1079 | int length = q->w * q->h; 1080 | while (length--) { 1081 | uint8_t value = *source++; 1082 | *dest++ = (value < threshold) ? QUIRC_PIXEL_BLACK : QUIRC_PIXEL_WHITE; 1083 | } 1084 | } 1085 | 1086 | uint8_t *quirc_begin(struct quirc *q, int *w, int *h) 1087 | { 1088 | q->num_regions = QUIRC_PIXEL_REGION; 1089 | q->num_capstones = 0; 1090 | q->num_grids = 0; 1091 | 1092 | if (w) 1093 | *w = q->w; 1094 | if (h) 1095 | *h = q->h; 1096 | 1097 | return q->image; 1098 | } 1099 | 1100 | void quirc_end(struct quirc *q) 1101 | { 1102 | int i; 1103 | 1104 | uint8_t threshold = otsu(q); 1105 | pixels_setup(q, threshold); 1106 | 1107 | for (i = 0; i < q->h; i++) 1108 | finder_scan(q, i); 1109 | 1110 | for (i = 0; i < q->num_capstones; i++) 1111 | test_grouping(q, i); 1112 | } 1113 | 1114 | void quirc_extract(const struct quirc *q, int index, 1115 | struct quirc_code *code) 1116 | { 1117 | const struct quirc_grid *qr = &q->grids[index]; 1118 | int y; 1119 | int i = 0; 1120 | 1121 | memset(code, 0, sizeof(*code)); 1122 | 1123 | if (index < 0 || index > q->num_grids) 1124 | return; 1125 | 1126 | perspective_map(qr->c, 0.0, 0.0, &code->corners[0]); 1127 | perspective_map(qr->c, qr->grid_size, 0.0, &code->corners[1]); 1128 | perspective_map(qr->c, qr->grid_size, qr->grid_size, 1129 | &code->corners[2]); 1130 | perspective_map(qr->c, 0.0, qr->grid_size, &code->corners[3]); 1131 | 1132 | code->size = qr->grid_size; 1133 | 1134 | /* Skip out early so as not to overrun the buffer. quirc_decode 1135 | * will return an error on interpreting the code. 1136 | */ 1137 | if (code->size > QUIRC_MAX_GRID_SIZE) 1138 | return; 1139 | 1140 | for (y = 0; y < qr->grid_size; y++) { 1141 | int x; 1142 | for (x = 0; x < qr->grid_size; x++) { 1143 | if (read_cell(q, index, x, y) > 0) { 1144 | code->cell_bitmap[i >> 3] |= (1 << (i & 7)); 1145 | } 1146 | i++; 1147 | } 1148 | } 1149 | } 1150 | --------------------------------------------------------------------------------