| 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. |