On some platforms, such as microcontrollers with a single-precision
FPU, operations on double type can be significantly slower compared
to the float type. For example, on ESP32-S3 microcontroller, decoding
a QR code of a certain size may take 1700ms when 'double' is used and
just 250ms when 'float' is used.
This commit adds two options to allow for such optimizations:
- QUIRC_FLOAT_TYPE: if defined, it is the type name to use in floating
point calculations. Can be set, for example, using:
CFLAGS += -DQUIRC_FLOAT_TYPE=float
- QUIRC_USE_TGMATH: if defined, Quirc will internally use <tgmath.h>
header, instead of <math.h>. This C99-or-later header allows the
program to call type-generic functions, such as 'sqrt', and the
calls will be dispatched to the correct implementation (sqrtf, sqrt,
sqrtl) depending on the actual argument type. Without setting this
option, the benefit of -DQUIRC_FLOAT_TYPE=float would be limited as
the double-precision versions of math functions would still be used.
The change is backwards compatible with existing applications. If
these macros are not defined, the behavior is the same as before.
* Make flood filling logic iterative (vs recursive)
I basically tried one-to-one conversions here to avoid mistakes.
probably it has a room for later optimizations.
* Use explicit malloc (vs variables on stack) to allocate the work area.
* Estimate the amount of memory for the work area dynamically
from the image size, instead of using a constant FLOOD_FILL_MAX_DEPTH,
which is too big in the most cases.
When using small captured images, I somehow frequently see failures
to recognize a capstone due to rounding errors.
eg. when pb[] = {2 3 8 3 2}.
This commit tries to improve it by using fixed-point arithmetics.
The scaling factor was chosen somehow arbitrary. A moderate scaling
should be enough.
Before this patch, in the event of `q->image` reallocation success but
`q->pixels` failure, `q->image` would point to a freed memory.
After this patch, once quirc_resize() returns, `q->image` consistently
point to a memory address that can be freed.
There is still an inconsistency left in the example codepath: `q->{h,w}`
would hold the "old" values, while `q->image` allocated size would be
based in the requested width/height; hence the comment update about the
state of the QR-code recognizer (it should only be passed to
quirc_destroy()).