README.md formatting tweaks

This commit is contained in:
Alexandre Perrin 2019-09-25 11:07:20 +02:00
parent db4046f997
commit b77da026c9

207
README.md
View file

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