diff --git a/tests/inspect_opencv.cxx b/tests/inspect_opencv.cxx new file mode 100644 index 0000000..ce5357a --- /dev/null +++ b/tests/inspect_opencv.cxx @@ -0,0 +1,264 @@ +/* quirc -- QR-code recognition library + * Copyright (C) 2010-2012 Daniel Beer + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include "quirc_internal.h" +#include "dbgutil.h" + +static void dump_info(struct quirc *q) +{ + int count = quirc_count(q); + int i; + + printf("%d QR-codes found:\n\n", count); + for (i = 0; i < count; i++) { + struct quirc_code code; + struct quirc_data data; + quirc_decode_error_t err; + + quirc_extract(q, i, &code); + err = quirc_decode(&code, &data); + if (err == QUIRC_ERROR_DATA_ECC) { + quirc_flip(&code); + err = quirc_decode(&code, &data); + } + + dump_cells(&code); + printf("\n"); + + if (err) { + printf(" Decoding FAILED: %s\n", quirc_strerror(err)); + } else { + printf(" Decoding successful:\n"); + dump_data(&data); + } + + printf("\n"); + } +} + +static void draw_frame(SDL_Surface *screen, struct quirc *q) +{ + uint8_t *pix; + uint8_t *raw = q->image; + int x, y; + + SDL_LockSurface(screen); + pix = screen->pixels; + for (y = 0; y < q->h; y++) { + uint32_t *row = (uint32_t *)pix; + + for (x = 0; x < q->w; x++) { + uint8_t v = *(raw++); + uint32_t color = (v << 16) | (v << 8) | v; + struct quirc_region *reg = &q->regions[v]; + + switch (v) { + case QUIRC_PIXEL_WHITE: + color = 0x00ffffff; + break; + + case QUIRC_PIXEL_BLACK: + color = 0x00000000; + break; + + default: + if (reg->capstone >= 0) + color = 0x00008000; + else + color = 0x00808080; + break; + } + + *(row++) = color; + } + + pix += screen->pitch; + } + SDL_UnlockSurface(screen); +} + +static void draw_blob(SDL_Surface *screen, int x, int y) +{ + int i, j; + + for (i = -2; i <= 2; i++) + for (j = -2; j <= 2; j++) + pixelColor(screen, x + i, y + j, 0x0000ffff); +} + +static void draw_mark(SDL_Surface *screen, int x, int y) +{ + pixelColor(screen, x, y, 0xff0000ff); + pixelColor(screen, x + 1, y, 0xff0000ff); + pixelColor(screen, x - 1, y, 0xff0000ff); + pixelColor(screen, x, y + 1, 0xff0000ff); + pixelColor(screen, x, y - 1, 0xff0000ff); +} + +static void draw_capstone(SDL_Surface *screen, struct quirc *q, int index) +{ + struct quirc_capstone *cap = &q->capstones[index]; + int j; + char buf[8]; + + for (j = 0; j < 4; j++) { + struct quirc_point *p0 = &cap->corners[j]; + struct quirc_point *p1 = &cap->corners[(j + 1) % 4]; + + lineColor(screen, p0->x, p0->y, p1->x, p1->y, + 0x800080ff); + } + + draw_blob(screen, cap->corners[0].x, cap->corners[0].y); + + if (cap->qr_grid < 0) { + snprintf(buf, sizeof(buf), "?%d", index); + stringColor(screen, cap->center.x, cap->center.y, buf, + 0x000000ff); + } +} + +static void perspective_map(const double *c, + double u, double v, struct quirc_point *ret) +{ + double den = c[6]*u + c[7]*v + 1.0; + double x = (c[0]*u + c[1]*v + c[2]) / den; + double y = (c[3]*u + c[4]*v + c[5]) / den; + + ret->x = rint(x); + ret->y = rint(y); +} + +static void draw_grid(SDL_Surface *screen, struct quirc *q, int index) +{ + struct quirc_grid *qr = &q->grids[index]; + int x, y; + int i; + + for (i = 0; i < 3; i++) { + struct quirc_capstone *cap = &q->capstones[qr->caps[i]]; + char buf[16]; + + snprintf(buf, sizeof(buf), "%d.%c", index, "ABC"[i]); + stringColor(screen, cap->center.x, cap->center.y, buf, + 0x000000ff); + } + + lineColor(screen, qr->tpep[0].x, qr->tpep[0].y, + qr->tpep[1].x, qr->tpep[1].y, 0xff00ffff); + lineColor(screen, qr->tpep[1].x, qr->tpep[1].y, + qr->tpep[2].x, qr->tpep[2].y, 0xff00ffff); + + if (qr->align_region >= 0) + draw_blob(screen, qr->align.x, qr->align.y); + + for (y = 0; y < qr->grid_size; y++) { + for (x = 0; x < qr->grid_size; x++) { + double u = x + 0.5; + double v = y + 0.5; + struct quirc_point p; + + perspective_map(qr->c, u, v, &p); + draw_mark(screen, p.x, p.y); + } + } +} + +static int sdl_examine(struct quirc *q) +{ + SDL_Surface *screen; + SDL_Event ev; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "couldn't init SDL: %s\n", SDL_GetError()); + return -1; + } + + screen = SDL_SetVideoMode(q->w, q->h, 32, SDL_SWSURFACE); + if (!screen) { + fprintf(stderr, "couldn't init video mode: %s\n", + SDL_GetError()); + return -1; + } + + while (SDL_WaitEvent(&ev) >= 0) { + int i; + + if (ev.type == SDL_QUIT) + break; + + if (ev.type == SDL_KEYDOWN && + ev.key.keysym.sym == 'q') + break; + + draw_frame(screen, q); + for (i = 0; i < q->num_capstones; i++) + draw_capstone(screen, q, i); + for (i = 0; i < q->num_grids; i++) + draw_grid(screen, q, i); + SDL_Flip(screen); + } + + SDL_Quit(); + return 0; +} + +int main(int argc, char **argv) +{ + struct quirc *q; + + printf("quirc inspection program\n"); + printf("Copyright (C) 2010-2012 Daniel Beer \n"); + printf("Library version: %s\n", quirc_version()); + printf("\n"); + + if (argc < 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return -1; + } + + q = quirc_new(); + if (!q) { + perror("can't create quirc object"); + return -1; + } + + int status = -1; + if (check_if_png(argv[1])) { + status = load_png(q, argv[1]); + } else { + status = load_jpeg(q, argv[1]); + } + if (status < 0) { + quirc_destroy(q); + return -1; + } + + quirc_end(q); + dump_info(q); + + if (sdl_examine(q) < 0) { + quirc_destroy(q); + return -1; + } + + quirc_destroy(q); + return 0; +}