Added autoconf/automake scripts so support for decoding large images (i.e. an increased max. number of regions) in the library can be enabled at compile time. The samples don't support this yet.
This commit is contained in:
parent
74b72a89a4
commit
bd473e9df2
12 changed files with 186 additions and 123 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -8,3 +8,13 @@ libquirc.a
|
|||
libquirc.so
|
||||
.*.swp
|
||||
*~
|
||||
.libs
|
||||
.deps
|
||||
.dirstamp
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.m4
|
||||
*.la
|
||||
quirc-config.h
|
||||
config.h
|
||||
configure
|
93
Makefile
93
Makefile
|
@ -1,93 +0,0 @@
|
|||
# quirc -- QR-code recognition library
|
||||
# Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
#
|
||||
# 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.
|
||||
|
||||
CC ?= gcc
|
||||
PREFIX ?= /usr/local
|
||||
SDL_CFLAGS := $(shell pkg-config --cflags sdl)
|
||||
SDL_LIBS := $(shell pkg-config --libs sdl)
|
||||
|
||||
LIB_VERSION = 1.0
|
||||
LIB_SONAME = libquirc.so.1
|
||||
|
||||
QUIRC_CFLAGS = -O3 -Wall -Ilib $(CFLAGS) $(SDL_CFLAGS)
|
||||
LIB_OBJ = \
|
||||
lib/decode.o \
|
||||
lib/identify.o \
|
||||
lib/quirc.o \
|
||||
lib/version_db.o
|
||||
LIB_SOBJ = $(subst .o,.lo,$(LIB_OBJ))
|
||||
DEMO_OBJ = \
|
||||
demo/camera.o \
|
||||
demo/mjpeg.o \
|
||||
demo/convert.o \
|
||||
demo/dthash.o \
|
||||
demo/demoutil.o
|
||||
|
||||
all: libquirc.so qrtest inspect quirc-demo quirc-scanner
|
||||
|
||||
qrtest: tests/dbgutil.o tests/qrtest.o libquirc.a
|
||||
$(CC) -o $@ $^ -lm -ljpeg
|
||||
|
||||
inspect: tests/dbgutil.o tests/inspect.o libquirc.a
|
||||
$(CC) -o $@ $^ -lm -ljpeg $(SDL_LIBS) -lSDL_gfx
|
||||
|
||||
quirc-demo: $(DEMO_OBJ) demo/demo.o libquirc.a
|
||||
$(CC) -o $@ $^ -lm -ljpeg $(SDL_LIBS) -lSDL_gfx
|
||||
|
||||
quirc-scanner: $(DEMO_OBJ) demo/scanner.o libquirc.a
|
||||
$(CC) -o $@ $^ -lm -ljpeg
|
||||
|
||||
libquirc.a: $(LIB_OBJ)
|
||||
rm -f $@
|
||||
ar cru $@ $^
|
||||
ranlib $@
|
||||
|
||||
libquirc.so: $(LIB_SOBJ)
|
||||
$(CC) -shared -Wl,-soname=$(LIB_SONAME) -o $@ $^ -lm
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(QUIRC_CFLAGS) -o $*.o -c $*.c
|
||||
|
||||
%.lo: %.c
|
||||
$(CC) -fPIC $(QUIRC_CFLAGS) -o $*.lo -c $*.c
|
||||
|
||||
install: libquirc.a libquirc.so quirc-demo quirc-scanner
|
||||
install -o root -g root -m 0644 lib/quirc.h $(DESTDIR)$(PREFIX)/include
|
||||
install -o root -g root -m 0644 libquirc.a $(DESTDIR)$(PREFIX)/lib
|
||||
install -o root -g root -m 0755 libquirc.so \
|
||||
$(DESTDIR)$(PREFIX)/lib/libquirc.so.$(LIB_VERSION)
|
||||
ln -sf libquirc.so.$(LIB_VERSION) $(DESTDIR)$(PREFIX)/lib/$(LIB_SONAME)
|
||||
ln -sf libquirc.so.$(LIB_VERSION) $(DESTDIR)$(PREFIX)/lib/libquirc.so
|
||||
install -o root -g root -m 0755 quirc-demo $(DESTDIR)$(PREFIX)/bin
|
||||
install -o root -g root -m 0755 quirc-scanner $(DESTDIR)$(PREFIX)/bin
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(PREFIX)/include/quirc.h
|
||||
rm -f $(DESTDIR)$(PREFIX)/lib/libquirc.so.$(LIB_VERSION)
|
||||
rm -f $(DESTDIR)$(PREFIX)/lib/$(LIB_SONAME)
|
||||
rm -f $(DESTDIR)$(PREFIX)/lib/libquirc.so
|
||||
rm -f $(DESTDIR)$(PREFIX)/lib/libquirc.a
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/quirc-demo
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/quirc-scanner
|
||||
|
||||
clean:
|
||||
rm -f */*.o
|
||||
rm -f */*.lo
|
||||
rm -f libquirc.a
|
||||
rm -f libquirc.so
|
||||
rm -f qrtest
|
||||
rm -f inspect
|
||||
rm -f quirc-demo
|
||||
rm -f quirc-scanner
|
52
Makefile.am
Normal file
52
Makefile.am
Normal file
|
@ -0,0 +1,52 @@
|
|||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
VERSION_INFO = 1:0:0
|
||||
|
||||
lib_LTLIBRARIES = libquirc.la
|
||||
BUILT_SOURCES = lib/quirc-config.h
|
||||
lib/quirc-config.h: config.h make-quirc-config.sed
|
||||
$(AM_V_at)$(SED) -f $(srcdir)/make-quirc-config.sed < config.h > $@T
|
||||
$(AM_V_at)mv -f $@T $@
|
||||
|
||||
include_HEADERS = lib/quirc.h \
|
||||
lib/quirc-config.h
|
||||
|
||||
libquirc_la_SOURCES = lib/decode.c \
|
||||
lib/identify.c \
|
||||
lib/quirc.c \
|
||||
lib/version_db.c
|
||||
libquirc_la_LIBADD = $(SYS_LIBS)
|
||||
libquirc_la_LDFLAGS = -version-info $(VERSION_INFO)
|
||||
|
||||
bin_PROGRAMS = quirc-demo \
|
||||
quirc-scanner
|
||||
|
||||
noinst_PROGRAMS = qrtest \
|
||||
inspect
|
||||
|
||||
DEMO_SOURCES = \
|
||||
demo/camera.c \
|
||||
demo/mjpeg.c \
|
||||
demo/convert.c \
|
||||
demo/dthash.c \
|
||||
demo/demoutil.c
|
||||
|
||||
qrtest_SOURCES = tests/dbgutil.c tests/qrtest.c
|
||||
qrtest_LDADD = libquirc.a -ljpeg
|
||||
|
||||
inspect_SOURCES = tests/dbgutil.c tests/inspect.c
|
||||
inspect_CFLAGS = $(sdl_CFLAGS)
|
||||
inspect_LDADD = libquirc.a -ljpeg $(sdl_LIBS) -lSDL_gfx
|
||||
|
||||
quirc_demo_SOURCES = $(DEMO_SOURCES) tests/dbgutil.c demo/demo.c
|
||||
quirc_demo_CFLAGS = $(sdl_CFLAGS)
|
||||
quirc_demo_LDADD = libquirc.a -ljpeg $(sdl_LIBS) -lSDL_gfx
|
||||
|
||||
quirc_scanner_SOURCES = $(DEMO_SOURCES) tests/dbgutil.c demo/scanner.c
|
||||
quirc_scanner_LDADD = libquirc.a -ljpeg
|
||||
|
||||
AM_CPPFLAGS = -I$(srcdir)/lib $(SYS_INCLUDES)
|
||||
|
||||
DISTCLEANFILES = ./lib/quirc-config.h
|
15
autogen.sh
Executable file
15
autogen.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
if [ -x "`which autoreconf 2>/dev/null`" ] ; then
|
||||
exec autoreconf -ivf
|
||||
fi
|
||||
|
||||
LIBTOOLIZE=libtoolize
|
||||
SYSNAME=`uname`
|
||||
if [ "x$SYSNAME" = "xDarwin" ] ; then
|
||||
LIBTOOLIZE=glibtoolize
|
||||
fi
|
||||
aclocal -I m4 && \
|
||||
autoheader && \
|
||||
$LIBTOOLIZE && \
|
||||
autoconf && \
|
||||
automake --add-missing --force-missing --copy
|
44
configure.ac
Normal file
44
configure.ac
Normal file
|
@ -0,0 +1,44 @@
|
|||
AC_INIT([quirc], [1.0], [https://github.com/dlbeer/quirc/issues], [quirc], [https://github.com/dlbeer/quirc])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_CONFIG_HEADER(config.h:config.in)
|
||||
AM_INIT_AUTOMAKE
|
||||
dnl AM_SILENT_RULES req. automake 1.11. [no] defaults V=1
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
AC_EXEEXT
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_SED
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
|
||||
AC_HEADER_STDC
|
||||
|
||||
PKG_CHECK_MODULES(sdl, sdl)
|
||||
AC_SUBST(sdl_CFLAGS)
|
||||
AC_SUBST(sdl_LIBS)
|
||||
|
||||
AC_CHECK_HEADERS(setjmp.h jpeglib.h)
|
||||
AC_CHECK_HEADERS(linux/videodev2.h linux/videodev.h)
|
||||
AC_SEARCH_LIBS([rint], [m])
|
||||
|
||||
AC_ARG_ENABLE(large-images,
|
||||
[ --enable-large-images enable decoding of large images],
|
||||
[large_images=true],
|
||||
[large_images=false])
|
||||
|
||||
AC_MSG_CHECKING(whether to support decoding lage images)
|
||||
if test "x$large_images" = "xtrue"; then
|
||||
AC_DEFINE(DECODE_LARGE_IMAGES, 1, [Define if decoding of large images is enabled])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
|
@ -14,6 +14,10 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
@ -21,7 +25,11 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef HAVE_LINUX_VIDEODEV2_H
|
||||
#include <linux/videodev2.h>
|
||||
#else
|
||||
#include <linux/videodev.h>
|
||||
#endif
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to,
|
|||
int left = x;
|
||||
int right = x;
|
||||
int i;
|
||||
int *row = q->region_info + y * q->w;
|
||||
quirc_pixel_t *row = q->image + y * q->w;
|
||||
|
||||
if (depth >= FLOOD_FILL_MAX_DEPTH)
|
||||
return;
|
||||
|
@ -152,7 +152,7 @@ static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to,
|
|||
|
||||
/* Seed new flood-fills */
|
||||
if (y > 0) {
|
||||
row = q->region_info + (y - 1) * q->w;
|
||||
row = q->image + (y - 1) * q->w;
|
||||
|
||||
for (i = left; i <= right; i++)
|
||||
if (row[i] == from)
|
||||
|
@ -161,7 +161,7 @@ static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to,
|
|||
}
|
||||
|
||||
if (y < q->h - 1) {
|
||||
row = q->region_info + (y + 1) * q->w;
|
||||
row = q->image + (y + 1) * q->w;
|
||||
|
||||
for (i = left; i <= right; i++)
|
||||
if (row[i] == from)
|
||||
|
@ -183,7 +183,7 @@ static void threshold(struct quirc *q)
|
|||
int avg_w = 0;
|
||||
int avg_u = 0;
|
||||
int threshold_s = q->w / THRESHOLD_S_DEN;
|
||||
int *row = q->region_info;
|
||||
quirc_pixel_t *row = q->image;
|
||||
|
||||
for (y = 0; y < q->h; y++) {
|
||||
int row_average[q->w];
|
||||
|
@ -229,14 +229,14 @@ static void area_count(void *user_data, int y, int left, int right)
|
|||
|
||||
static int region_code(struct quirc *q, int x, int y)
|
||||
{
|
||||
int pixel;
|
||||
quirc_pixel_t pixel;
|
||||
struct quirc_region *box;
|
||||
int region;
|
||||
|
||||
if (x < 0 || y < 0 || x >= q->w || y >= q->h)
|
||||
return -1;
|
||||
|
||||
pixel = q->region_info[y * q->w + x];
|
||||
pixel = q->image[y * q->w + x];
|
||||
|
||||
if (pixel >= QUIRC_PIXEL_REGION)
|
||||
return pixel;
|
||||
|
@ -415,7 +415,7 @@ static void test_capstone(struct quirc *q, int x, int y, int *pb)
|
|||
|
||||
static void finder_scan(struct quirc *q, int y)
|
||||
{
|
||||
int *row = q->region_info + y * q->w;
|
||||
quirc_pixel_t *row = q->image + y * q->w;
|
||||
int x;
|
||||
int last_color;
|
||||
int run_length = 0;
|
||||
|
@ -587,12 +587,12 @@ static int timing_scan(const struct quirc *q,
|
|||
x = p0->x;
|
||||
y = p0->y;
|
||||
for (i = 0; i <= d; i++) {
|
||||
int pixel;
|
||||
quirc_pixel_t pixel;
|
||||
|
||||
if (y < 0 || y >= q->h || x < 0 || x >= q->w)
|
||||
break;
|
||||
|
||||
pixel = q->region_info[y * q->w + x];
|
||||
pixel = q->image[y * q->w + x];
|
||||
|
||||
if (pixel) {
|
||||
if (run_length >= 2)
|
||||
|
@ -670,7 +670,7 @@ static int read_cell(const struct quirc *q, int index, int x, int y)
|
|||
if (p.y < 0 || p.y >= q->h || p.x < 0 || p.x >= q->w)
|
||||
return 0;
|
||||
|
||||
return q->region_info[p.y * q->w + p.x] ? 1 : -1;
|
||||
return q->image[p.y * q->w + p.x] ? 1 : -1;
|
||||
}
|
||||
|
||||
static int fitness_cell(const struct quirc *q, int index, int x, int y)
|
||||
|
@ -689,7 +689,7 @@ static int fitness_cell(const struct quirc *q, int index, int x, int y)
|
|||
if (p.y < 0 || p.y >= q->h || p.x < 0 || p.x >= q->w)
|
||||
continue;
|
||||
|
||||
if (q->region_info[p.y * q->w + p.x])
|
||||
if (q->image[p.y * q->w + p.x])
|
||||
score++;
|
||||
else
|
||||
score--;
|
||||
|
@ -1066,7 +1066,7 @@ static void test_grouping(struct quirc *q, int i)
|
|||
test_neighbours(q, i, &hlist, &vlist);
|
||||
}
|
||||
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h)
|
||||
quirc_pixel_t *quirc_begin(struct quirc *q, int *w, int *h)
|
||||
{
|
||||
q->num_regions = QUIRC_PIXEL_REGION;
|
||||
q->num_capstones = 0;
|
||||
|
@ -1084,9 +1084,6 @@ void quirc_end(struct quirc *q)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < q->w*q->h; i++)
|
||||
q->region_info[i] = q->image[i];
|
||||
|
||||
threshold(q);
|
||||
|
||||
for (i = 0; i < q->h; i++)
|
||||
|
|
11
lib/quirc.c
11
lib/quirc.c
|
@ -38,25 +38,18 @@ void quirc_destroy(struct quirc *q)
|
|||
{
|
||||
if (q->image)
|
||||
free(q->image);
|
||||
if (q->region_info)
|
||||
free(q->region_info);
|
||||
|
||||
free(q);
|
||||
}
|
||||
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
uint8_t *new_image = realloc(q->image, w * h);
|
||||
int *new_region_info = realloc(q->region_info, w * h * sizeof(int));
|
||||
quirc_pixel_t *new_image = realloc(q->image, w * h * sizeof(quirc_pixel_t));
|
||||
|
||||
if (!new_image || !new_region_info) {
|
||||
free(new_image);
|
||||
free(new_region_info);
|
||||
if (!new_image)
|
||||
return -1;
|
||||
}
|
||||
|
||||
q->image = new_image;
|
||||
q->region_info = new_region_info;
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
|
||||
|
|
15
lib/quirc.h
15
lib/quirc.h
|
@ -19,6 +19,14 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <quirc-config.h>
|
||||
|
||||
#ifdef QUIRC__DECODE_LARGE_IMAGES
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
|
@ -42,14 +50,15 @@ int quirc_resize(struct quirc *q, int w, int h);
|
|||
|
||||
/* These functions are used to process images for QR-code recognition.
|
||||
* quirc_begin() must first be called to obtain access to a buffer into
|
||||
* which the input image should be placed. Optionally, the current
|
||||
* width and height may be returned.
|
||||
* which the input image should be placed. Values between 0x00 and 0xff
|
||||
* must be used to store the grayscale level.
|
||||
* Optionally, the current width and height may be returned.
|
||||
*
|
||||
* After filling the buffer, quirc_end() should be called to process
|
||||
* the image for QR-code recognition. The locations and content of each
|
||||
* code may be obtained using accessor functions described below.
|
||||
*/
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
quirc_pixel_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
void quirc_end(struct quirc *q);
|
||||
|
||||
/* This structure describes a location in the input image buffer. */
|
||||
|
|
|
@ -18,12 +18,17 @@
|
|||
#define QUIRC_INTERNAL_H_
|
||||
|
||||
#include "quirc.h"
|
||||
#include "quirc-config.h"
|
||||
|
||||
#define QUIRC_PIXEL_WHITE 0
|
||||
#define QUIRC_PIXEL_BLACK 1
|
||||
#define QUIRC_PIXEL_REGION 2
|
||||
|
||||
#define QUIRC_MAX_REGIONS 2048
|
||||
#ifdef QUIRC__DECODE_LARGE_IMAGES
|
||||
#define QUIRC_MAX_REGIONS 65534
|
||||
#else
|
||||
#define QUIRC_MAX_REGIONS 254
|
||||
#endif
|
||||
#define QUIRC_MAX_CAPSTONES 32
|
||||
#define QUIRC_MAX_GRIDS 8
|
||||
|
||||
|
@ -65,8 +70,7 @@ struct quirc_grid {
|
|||
};
|
||||
|
||||
struct quirc {
|
||||
uint8_t *image;
|
||||
int *region_info;
|
||||
quirc_pixel_t *image;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
|
|
1
m4/empty.dir
Normal file
1
m4/empty.dir
Normal file
|
@ -0,0 +1 @@
|
|||
## empty directory
|
23
make-quirc-config.sed
Normal file
23
make-quirc-config.sed
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Sed script to postprocess config.h into quirc-config.h.
|
||||
|
||||
1i\
|
||||
/* quirc-config.h\
|
||||
*\
|
||||
* This file was generated by autoconf when quirc was built, and post-\
|
||||
* processed by quirc so that its macros would have a uniform prefix.\
|
||||
*\
|
||||
* DO NOT EDIT THIS FILE.\
|
||||
*\
|
||||
* Do not rely on macros in this file existing in later versions.\
|
||||
*/\
|
||||
\
|
||||
#ifndef QUIRC_CONFIG_H_INCLUDED_\
|
||||
#define QUIRC_CONFIG_H_INCLUDED_\
|
||||
|
||||
$a\
|
||||
\
|
||||
#endif /* quirc-config.h */
|
||||
|
||||
s/#\( *\)define /#\1define QUIRC__/
|
||||
s/#\( *\)undef /#\1undef QUIRC__/
|
||||
s/#\( *\)if\(n*\)def /#\1if\2def QUIRC__/
|
Loading…
Reference in a new issue