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