188 lines
6.1 KiB
Text
188 lines
6.1 KiB
Text
Quirc
|
|
=====
|
|
|
|
QR codes are a type of high-density matrix barcodes, and quirc is a
|
|
library for extracting and decoding them from images. It has several
|
|
features which make it a good choice for this purpose:
|
|
|
|
* It is fast enough to be used with realtime video: extracting and
|
|
decoding from VGA frame takes about 50 ms on a modern x86 core.
|
|
|
|
* It has a robust and tolerant recognition algorithm. It can
|
|
correctly recognise and decode QR codes which are rotated and/or
|
|
oblique to the camera. It can also distinguish and decode multiple
|
|
codes within the same image.
|
|
|
|
* It is easy to use, with a simple API described in a single
|
|
commented header file (see below for an overview).
|
|
|
|
* It is small and easily embeddable, with no dependencies other than
|
|
standard C functions.
|
|
|
|
* It has a very small memory footprint: one byte per image pixel,
|
|
plus a few kB per decoder object.
|
|
|
|
* It uses no global mutable state, and is safe to use in a
|
|
multithreaded application.
|
|
|
|
* BSD-licensed, with almost no restrictions regarding use and/or
|
|
modification.
|
|
|
|
The distribution comes with, in addition to the library, several test
|
|
programs. While the core library is very portable, these programs have
|
|
some additional dependencies. All of them require libjpeg, and two
|
|
(``quirc-demo`` and ``inspect``) require SDL. The camera demos use
|
|
Linux-specific APIs:
|
|
|
|
``quirc-demo``
|
|
|
|
~ This is an real-time demo which requires a camera and a graphical
|
|
display. The video stream is displayed on screen as it's received,
|
|
and any QR codes recognised are highlighted in the image, with the
|
|
decoded information both displayed on the image and printed on
|
|
stdout.
|
|
|
|
``quirc-scanner``
|
|
|
|
~ This program turns your camera into a barcode scanner. It's almost
|
|
the same as the ``demo`` application, but it doesn't display the
|
|
video stream, and thus doesn't require a graphical display.
|
|
|
|
``qrtest``
|
|
|
|
~ This test is used to evaluate the performance of library. Given a
|
|
directory tree containing a bunch of JPEG images, it will attempt
|
|
to locate and decode QR codes in each image. Speed and success
|
|
statistics are collected and printed on stdout.
|
|
|
|
``inspect``
|
|
|
|
~ This test is used for debugging. Given a single JPEG image, it
|
|
will display a diagram showing the internal state of the decoder
|
|
as well as printing additional information on stdout.
|
|
|
|
Installation
|
|
------------
|
|
|
|
To build the library and associated demos/tests, type ``make``. Type
|
|
``make install`` to install the library, header file and camera demos.
|
|
|
|
You can specify one or several of the following targets if you don't
|
|
want, or are unable to build everything:
|
|
|
|
* libquirc.a
|
|
* libquirc.so
|
|
* qrtest
|
|
* inspect
|
|
* quirc-scanner
|
|
* quirc-demo
|
|
|
|
Library use
|
|
-----------
|
|
|
|
All of the library's functionality is exposed through a single header
|
|
file, which you should include:
|
|
|
|
#include <quirc.h>
|
|
|
|
To decode images, you'll need to instantiate a ``struct quirc``
|
|
object, which is done with the ``quirc_new`` function. Later, when you
|
|
no longer need to decode anything, you should release the allocated
|
|
memory with ``quirc_destroy``:
|
|
|
|
struct quirc *qr;
|
|
|
|
qr = quirc_new();
|
|
if (!qr) {
|
|
perror("Failed to allocate memory");
|
|
abort();
|
|
}
|
|
|
|
/* ... */
|
|
|
|
quirc_destroy(qr);
|
|
|
|
Having obtained a decoder object, you need to set the image size that
|
|
you'll be working with, which is done using ``quirc_resize``:
|
|
|
|
if (quirc_resize(qr, 640, 480) < 0) {
|
|
perror("Failed to allocate video memory");
|
|
abort();
|
|
}
|
|
|
|
``quirc_resize`` and ``quirc_new`` are the only library functions
|
|
which allocate memory. If you plan to process a series of frames (or a
|
|
video stream), you probably want to allocate and size a single decoder
|
|
and hold onto it to process each frame.
|
|
|
|
Processing frames is done in two stages. The first stage is an
|
|
image-recognition stage called identification, which takes a grayscale
|
|
image and searches for QR codes. Using ``quirc_begin`` and
|
|
``quirc_end``, you can feed a grayscale image directly into the buffer
|
|
that ``quirc`` uses for image processing:
|
|
|
|
uint8_t *image;
|
|
int w, h;
|
|
|
|
image = quirc_begin(qr, &w, &h);
|
|
|
|
/* Fill out the image buffer here.
|
|
* image is a pointer to a w*h bytes.
|
|
* One byte per pixel, w pixels per line, h lines in the buffer.
|
|
*/
|
|
|
|
quirc_end(qr);
|
|
|
|
Note that ``quirc_begin`` simply returns a pointer to a previously
|
|
allocated buffer. The buffer will contain uninitialized data. After
|
|
the call to ``quirc_end``, the decoder holds a list of detected QR
|
|
codes which can be queried via ``quirc_count`` and ``quirc_extract``.
|
|
|
|
At this point, the second stage of processing occurs -- decoding. This
|
|
is done via the call to ``quirc_decode``, which is not associated with
|
|
a decoder object.
|
|
|
|
int num_codes;
|
|
int i;
|
|
|
|
/* We've previously fed an image to the decoder via
|
|
* quirc_begin/quirc_end.
|
|
*/
|
|
|
|
num_codes = quirc_count(qr);
|
|
for (i = 0; i < num_codes; i++) {
|
|
struct quirc_code code;
|
|
struct quirc_data data;
|
|
quirc_decode_error_t err;
|
|
|
|
quirc_extract(qr, i, &code);
|
|
|
|
/* Decoding stage */
|
|
err = quirc_decode(&code, &data);
|
|
if (err)
|
|
printf("DECODE FAILED: %s\n", quirc_strerror(err));
|
|
else
|
|
printf("Data: %s\n", data.payload);
|
|
}
|
|
|
|
``quirc_code`` and ``quirc_data`` are flat structures which don't need
|
|
to be initialized or freed after use.
|
|
|
|
Copyright
|
|
---------
|
|
|
|
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.
|