You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Add c_mpos module with quirc
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
idf_component_register(SRC_DIRS "lib" "openmv"
|
||||
INCLUDE_DIRS "lib" ".")
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Ofast)
|
||||
@@ -0,0 +1,16 @@
|
||||
quirc -- QR-code recognition library
|
||||
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.
|
||||
@@ -0,0 +1,88 @@
|
||||
# quirc -- QR-code recognition library
|
||||
# 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.
|
||||
|
||||
CC ?= gcc
|
||||
PREFIX ?= /usr/local
|
||||
SDL_CFLAGS != pkg-config --cflags sdl
|
||||
SDL_LIBS != pkg-config --libs sdl
|
||||
|
||||
LIB_VERSION = 1.0
|
||||
|
||||
CFLAGS ?= -O3 -Wall -fPIC
|
||||
QUIRC_CFLAGS = -Ilib $(CFLAGS) $(SDL_CFLAGS)
|
||||
LIB_OBJ = \
|
||||
lib/decode.o \
|
||||
lib/identify.o \
|
||||
lib/quirc.o \
|
||||
lib/version_db.o
|
||||
DEMO_OBJ = \
|
||||
demo/camera.o \
|
||||
demo/mjpeg.o \
|
||||
demo/convert.o \
|
||||
demo/dthash.o \
|
||||
demo/demoutil.o
|
||||
|
||||
all: libquirc.so qrtest inspect quirc-demo quirc-scanner
|
||||
|
||||
qrtest: tests/dbgutil.o tests/qrtest.o libquirc.a
|
||||
$(CC) -o $@ tests/dbgutil.o tests/qrtest.o libquirc.a $(LDFLAGS) -lm -ljpeg -lpng
|
||||
|
||||
inspect: tests/dbgutil.o tests/inspect.o libquirc.a
|
||||
$(CC) -o $@ tests/dbgutil.o tests/inspect.o libquirc.a $(LDFLAGS) -lm -ljpeg -lpng $(SDL_LIBS) -lSDL_gfx
|
||||
|
||||
quirc-demo: $(DEMO_OBJ) demo/demo.o libquirc.a
|
||||
$(CC) -o $@ $(DEMO_OBJ) demo/demo.o libquirc.a $(LDFLAGS) -lm -ljpeg $(SDL_LIBS) -lSDL_gfx
|
||||
|
||||
quirc-scanner: $(DEMO_OBJ) demo/scanner.o libquirc.a
|
||||
$(CC) -o $@ $(DEMO_OBJ) demo/scanner.o libquirc.a $(LDFLAGS) -lm -ljpeg
|
||||
|
||||
libquirc.a: $(LIB_OBJ)
|
||||
rm -f $@
|
||||
ar cru $@ $(LIB_OBJ)
|
||||
ranlib $@
|
||||
|
||||
.PHONY: libquirc.so
|
||||
libquirc.so: libquirc.so.$(LIB_VERSION)
|
||||
|
||||
libquirc.so.$(LIB_VERSION): $(LIB_OBJ)
|
||||
$(CC) -shared -o $@ $(LIB_OBJ) $(LDFLAGS) -lm
|
||||
|
||||
.c.o:
|
||||
$(CC) $(QUIRC_CFLAGS) -o $@ -c $<
|
||||
|
||||
install: libquirc.a libquirc.so.$(LIB_VERSION) quirc-demo quirc-scanner
|
||||
install -o root -g root -m 0644 lib/quirc.h $(DESTDIR)$(PREFIX)/include
|
||||
install -o root -g root -m 0644 libquirc.a $(DESTDIR)$(PREFIX)/lib
|
||||
install -o root -g root -m 0755 libquirc.so.$(LIB_VERSION) \
|
||||
$(DESTDIR)$(PREFIX)/lib
|
||||
install -o root -g root -m 0755 quirc-demo $(DESTDIR)$(PREFIX)/bin
|
||||
install -o root -g root -m 0755 quirc-scanner $(DESTDIR)$(PREFIX)/bin
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(PREFIX)/include/quirc.h
|
||||
rm -f $(DESTDIR)$(PREFIX)/lib/libquirc.so.$(LIB_VERSION)
|
||||
rm -f $(DESTDIR)$(PREFIX)/lib/libquirc.a
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/quirc-demo
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/quirc-scanner
|
||||
|
||||
clean:
|
||||
rm -f */*.o
|
||||
rm -f */*.lo
|
||||
rm -f libquirc.a
|
||||
rm -f libquirc.so.$(LIB_VERSION)
|
||||
rm -f qrtest
|
||||
rm -f inspect
|
||||
rm -f quirc-demo
|
||||
rm -f quirc-scanner
|
||||
@@ -0,0 +1,16 @@
|
||||
quirc -- QR-code recognition library
|
||||
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.
|
||||
@@ -0,0 +1,193 @@
|
||||
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`. If you need to
|
||||
decode "large" image files build with `CFLAGS="-DQUIRC_MAX_REGIONS=65534" make`
|
||||
instead. Note that this will increase the memory usage, it is discouraged for
|
||||
low resource devices (i.e. embedded).
|
||||
|
||||
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:
|
||||
|
||||
```C
|
||||
#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`:
|
||||
|
||||
```C
|
||||
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`:
|
||||
|
||||
```C
|
||||
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:
|
||||
|
||||
```C
|
||||
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.
|
||||
|
||||
```C
|
||||
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.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,103 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "quirc_internal.h"
|
||||
|
||||
const char *quirc_version(void)
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
//static struct quirc _q;
|
||||
struct quirc *quirc_new(void)
|
||||
{
|
||||
struct quirc *q = d_malloc(sizeof(*q));
|
||||
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
return q;
|
||||
}
|
||||
|
||||
void quirc_destroy(struct quirc *q)
|
||||
{
|
||||
if (q->image)
|
||||
if (q->image)
|
||||
free(q->image);
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
|
||||
if (q)
|
||||
free(q);
|
||||
}
|
||||
|
||||
//static quirc_pixel_t img_buf[320*240];
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
if (q->image)
|
||||
{
|
||||
free(q->image);
|
||||
}
|
||||
uint8_t *new_image = ps_malloc(w * h);
|
||||
|
||||
if (!new_image)
|
||||
return -1;
|
||||
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
{ //should gray, 1==1
|
||||
size_t new_size = w * h * sizeof(quirc_pixel_t);
|
||||
if (q->pixels)
|
||||
free(q->pixels);
|
||||
quirc_pixel_t *new_pixels = ps_malloc(new_size);
|
||||
if (!new_pixels)
|
||||
{
|
||||
free(new_image);
|
||||
return -1;
|
||||
}
|
||||
q->pixels = new_pixels;
|
||||
}
|
||||
q->image = new_image;
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quirc_count(const struct quirc *q)
|
||||
{
|
||||
return q->num_grids;
|
||||
}
|
||||
|
||||
static const char *const error_table[] = {
|
||||
[QUIRC_SUCCESS] = "Success",
|
||||
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
|
||||
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
|
||||
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
|
||||
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
|
||||
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
|
||||
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
|
||||
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"};
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
if (err >= 0 && err < sizeof(error_table) / sizeof(error_table[0]))
|
||||
return error_table[err];
|
||||
|
||||
return "Unknown error";
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_H_
|
||||
#define QUIRC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
const char *quirc_version(void);
|
||||
|
||||
/* Construct a new QR-code recognizer. This function will return NULL
|
||||
* if sufficient memory could not be allocated.
|
||||
*/
|
||||
struct quirc *quirc_new(void);
|
||||
|
||||
/* Destroy a QR-code recognizer. */
|
||||
void quirc_destroy(struct quirc *q);
|
||||
|
||||
/* Resize the QR-code recognizer. The size of an image must be
|
||||
* specified before codes can be analyzed.
|
||||
*
|
||||
* This function returns 0 on success, or -1 if sufficient memory could
|
||||
* not be allocated.
|
||||
*/
|
||||
int quirc_resize(struct quirc *q, int w, int h);
|
||||
|
||||
/* These functions are used to process images for QR-code recognition.
|
||||
* quirc_begin() must first be called to obtain access to a buffer into
|
||||
* which the input image should be placed. Optionally, the current
|
||||
* width and height may be returned.
|
||||
*
|
||||
* After filling the buffer, quirc_end() should be called to process
|
||||
* the image for QR-code recognition. The locations and content of each
|
||||
* code may be obtained using accessor functions described below.
|
||||
*/
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
void quirc_end(struct quirc *q);
|
||||
|
||||
/* This structure describes a location in the input image buffer. */
|
||||
struct quirc_point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This enum describes the various decoder errors which may occur. */
|
||||
typedef enum
|
||||
{
|
||||
QUIRC_SUCCESS = 0,
|
||||
QUIRC_ERROR_INVALID_GRID_SIZE,
|
||||
QUIRC_ERROR_INVALID_VERSION,
|
||||
QUIRC_ERROR_FORMAT_ECC,
|
||||
QUIRC_ERROR_DATA_ECC,
|
||||
QUIRC_ERROR_UNKNOWN_DATA_TYPE,
|
||||
QUIRC_ERROR_DATA_OVERFLOW,
|
||||
QUIRC_ERROR_DATA_UNDERFLOW
|
||||
} quirc_decode_error_t;
|
||||
|
||||
/* Return a string error message for an error code. */
|
||||
const char *quirc_strerror(quirc_decode_error_t err);
|
||||
|
||||
/* Limits on the maximum size of QR-codes and their content. */
|
||||
#define QUIRC_MAX_VERSION 40
|
||||
#define QUIRC_MAX_GRID_SIZE (QUIRC_MAX_VERSION * 4 + 17)
|
||||
#define QUIRC_MAX_BITMAP (((QUIRC_MAX_GRID_SIZE * QUIRC_MAX_GRID_SIZE) + 7) / 8)
|
||||
#define QUIRC_MAX_PAYLOAD 8896
|
||||
|
||||
/* QR-code ECC types. */
|
||||
#define QUIRC_ECC_LEVEL_M 0
|
||||
#define QUIRC_ECC_LEVEL_L 1
|
||||
#define QUIRC_ECC_LEVEL_H 2
|
||||
#define QUIRC_ECC_LEVEL_Q 3
|
||||
|
||||
/* QR-code data types. */
|
||||
#define QUIRC_DATA_TYPE_NUMERIC 1
|
||||
#define QUIRC_DATA_TYPE_ALPHA 2
|
||||
#define QUIRC_DATA_TYPE_BYTE 4
|
||||
#define QUIRC_DATA_TYPE_KANJI 8
|
||||
|
||||
/* Common character encodings */
|
||||
#define QUIRC_ECI_ISO_8859_1 1
|
||||
#define QUIRC_ECI_IBM437 2
|
||||
#define QUIRC_ECI_ISO_8859_2 4
|
||||
#define QUIRC_ECI_ISO_8859_3 5
|
||||
#define QUIRC_ECI_ISO_8859_4 6
|
||||
#define QUIRC_ECI_ISO_8859_5 7
|
||||
#define QUIRC_ECI_ISO_8859_6 8
|
||||
#define QUIRC_ECI_ISO_8859_7 9
|
||||
#define QUIRC_ECI_ISO_8859_8 10
|
||||
#define QUIRC_ECI_ISO_8859_9 11
|
||||
#define QUIRC_ECI_WINDOWS_874 13
|
||||
#define QUIRC_ECI_ISO_8859_13 15
|
||||
#define QUIRC_ECI_ISO_8859_15 17
|
||||
#define QUIRC_ECI_SHIFT_JIS 20
|
||||
#define QUIRC_ECI_UTF_8 26
|
||||
|
||||
/* This structure is used to return information about detected QR codes
|
||||
* in the input image.
|
||||
*/
|
||||
struct quirc_code
|
||||
{
|
||||
/* The four corners of the QR-code, from top left, clockwise */
|
||||
struct quirc_point corners[4];
|
||||
|
||||
/* The number of cells across in the QR-code. The cell bitmap
|
||||
* is a bitmask giving the actual values of cells. If the cell
|
||||
* at (x, y) is black, then the following bit is set:
|
||||
*
|
||||
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
||||
*
|
||||
* where i = (y * size) + x.
|
||||
*/
|
||||
int size;
|
||||
uint8_t cell_bitmap[QUIRC_MAX_BITMAP];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* This structure holds the decoded QR-code data */
|
||||
struct quirc_data
|
||||
{
|
||||
/* Various parameters of the QR-code. These can mostly be
|
||||
* ignored if you only care about the data.
|
||||
*/
|
||||
int version;
|
||||
int ecc_level;
|
||||
int mask;
|
||||
|
||||
/* This field is the highest-valued data type found in the QR
|
||||
* code.
|
||||
*/
|
||||
int data_type;
|
||||
|
||||
/* Data payload. For the Kanji datatype, payload is encoded as
|
||||
* Shift-JIS. For all other datatypes, payload is ASCII text.
|
||||
*/
|
||||
uint8_t payload[QUIRC_MAX_PAYLOAD];
|
||||
int payload_len;
|
||||
|
||||
/* ECI assignment number */
|
||||
uint32_t eci;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct datastream
|
||||
{
|
||||
uint8_t raw[QUIRC_MAX_PAYLOAD];
|
||||
int data_bits;
|
||||
int ptr;
|
||||
|
||||
uint8_t data[QUIRC_MAX_PAYLOAD];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* Return the number of QR-codes identified in the last processed
|
||||
* image.
|
||||
*/
|
||||
int quirc_count(const struct quirc *q);
|
||||
|
||||
/* Extract the QR-code specified by the given index. */
|
||||
void quirc_extract(const struct quirc *q, int index,
|
||||
struct quirc_code *code);
|
||||
|
||||
/* Decode a QR-code, returning the payload data. */
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_INTERNAL_H_
|
||||
#define QUIRC_INTERNAL_H_
|
||||
|
||||
#include "quirc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define QUIRC_PIXEL_WHITE 0
|
||||
#define QUIRC_PIXEL_BLACK 1
|
||||
#define QUIRC_PIXEL_REGION 2
|
||||
|
||||
#ifndef QUIRC_MAX_REGIONS
|
||||
#define QUIRC_MAX_REGIONS 254
|
||||
#endif
|
||||
|
||||
#define QUIRC_MAX_CAPSTONES 32
|
||||
#define QUIRC_MAX_GRIDS 8
|
||||
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
#endif
|
||||
|
||||
//#include <esp_heap_caps.h>
|
||||
static inline void* ps_malloc(const size_t size)
|
||||
{
|
||||
//return heap_caps_malloc_prefer(size, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT);
|
||||
return malloc(size);
|
||||
}
|
||||
static inline void* d_malloc(const size_t size)
|
||||
{
|
||||
//return heap_caps_malloc(size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
struct quirc_region
|
||||
{
|
||||
struct quirc_point seed;
|
||||
int count;
|
||||
int capstone;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_capstone
|
||||
{
|
||||
int ring;
|
||||
int stone;
|
||||
|
||||
struct quirc_point corners[4];
|
||||
struct quirc_point center;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
|
||||
int qr_grid;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_grid
|
||||
{
|
||||
/* Capstone indices */
|
||||
int caps[3];
|
||||
|
||||
/* Alignment pattern region and corner */
|
||||
int align_region;
|
||||
struct quirc_point align;
|
||||
|
||||
/* Timing pattern endpoints */
|
||||
struct quirc_point tpep[3];
|
||||
int hscan;
|
||||
int vscan;
|
||||
|
||||
/* Grid size and perspective transform */
|
||||
int grid_size;
|
||||
float c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc
|
||||
{
|
||||
uint8_t *image;
|
||||
quirc_pixel_t *pixels;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
int num_regions;
|
||||
struct quirc_region regions[QUIRC_MAX_REGIONS];
|
||||
|
||||
int num_capstones;
|
||||
struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES];
|
||||
|
||||
int num_grids;
|
||||
struct quirc_grid grids[QUIRC_MAX_GRIDS];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/************************************************************************
|
||||
* QR-code version information database
|
||||
*/
|
||||
|
||||
#define QUIRC_MAX_VERSION 40
|
||||
#define QUIRC_MAX_ALIGNMENT 7
|
||||
|
||||
struct quirc_rs_params
|
||||
{
|
||||
uint8_t bs; /* Small block size */
|
||||
uint8_t dw; /* Small data words */
|
||||
uint8_t ns; /* Number of small blocks */
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct quirc_version_info
|
||||
{
|
||||
uint16_t data_bytes;
|
||||
uint8_t apat[QUIRC_MAX_ALIGNMENT];
|
||||
struct quirc_rs_params ecc[4];
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1];
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,184 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "quirc_internal.h"
|
||||
|
||||
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
{0},
|
||||
{/* Version 1 */
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 26, .dw = 16, .ns = 1},
|
||||
{.bs = 26, .dw = 19, .ns = 1},
|
||||
{.bs = 26, .dw = 9, .ns = 1},
|
||||
{.bs = 26, .dw = 13, .ns = 1}}},
|
||||
{/* Version 2 */
|
||||
.data_bytes = 44,
|
||||
.apat = {6, 18, 0},
|
||||
.ecc = {{.bs = 44, .dw = 28, .ns = 1}, {.bs = 44, .dw = 34, .ns = 1}, {.bs = 44, .dw = 16, .ns = 1}, {.bs = 44, .dw = 22, .ns = 1}}},
|
||||
{/* Version 3 */
|
||||
.data_bytes = 70,
|
||||
.apat = {6, 22, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 1}, {.bs = 70, .dw = 55, .ns = 1}, {.bs = 35, .dw = 13, .ns = 2}, {.bs = 35, .dw = 17, .ns = 2}}},
|
||||
{/* Version 4 */
|
||||
.data_bytes = 100,
|
||||
.apat = {6, 26, 0},
|
||||
.ecc = {{.bs = 50, .dw = 32, .ns = 2}, {.bs = 100, .dw = 80, .ns = 1}, {.bs = 25, .dw = 9, .ns = 4}, {.bs = 50, .dw = 24, .ns = 2}}},
|
||||
{/* Version 5 */
|
||||
.data_bytes = 134,
|
||||
.apat = {6, 30, 0},
|
||||
.ecc = {{.bs = 67, .dw = 43, .ns = 2}, {.bs = 134, .dw = 108, .ns = 1}, {.bs = 33, .dw = 11, .ns = 2}, {.bs = 33, .dw = 15, .ns = 2}}},
|
||||
{/* Version 6 */
|
||||
.data_bytes = 172,
|
||||
.apat = {6, 34, 0},
|
||||
.ecc = {{.bs = 43, .dw = 27, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 4}, {.bs = 43, .dw = 19, .ns = 4}}},
|
||||
{/* Version 7 */
|
||||
.data_bytes = 196,
|
||||
.apat = {6, 22, 38, 0},
|
||||
.ecc = {{.bs = 49, .dw = 31, .ns = 4}, {.bs = 98, .dw = 78, .ns = 2}, {.bs = 39, .dw = 13, .ns = 4}, {.bs = 32, .dw = 14, .ns = 2}}},
|
||||
{/* Version 8 */
|
||||
.data_bytes = 242,
|
||||
.apat = {6, 24, 42, 0},
|
||||
.ecc = {{.bs = 60, .dw = 38, .ns = 2}, {.bs = 121, .dw = 97, .ns = 2}, {.bs = 40, .dw = 14, .ns = 4}, {.bs = 40, .dw = 18, .ns = 4}}},
|
||||
{/* Version 9 */
|
||||
.data_bytes = 292,
|
||||
.apat = {6, 26, 46, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 3}, {.bs = 146, .dw = 116, .ns = 2}, {.bs = 36, .dw = 12, .ns = 4}, {.bs = 36, .dw = 16, .ns = 4}}},
|
||||
{/* Version 10 */
|
||||
.data_bytes = 346,
|
||||
.apat = {6, 28, 50, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 4}, {.bs = 86, .dw = 68, .ns = 2}, {.bs = 43, .dw = 15, .ns = 6}, {.bs = 43, .dw = 19, .ns = 6}}},
|
||||
{/* Version 11 */
|
||||
.data_bytes = 404,
|
||||
.apat = {6, 30, 54, 0},
|
||||
.ecc = {{.bs = 80, .dw = 50, .ns = 1}, {.bs = 101, .dw = 81, .ns = 4}, {.bs = 36, .dw = 12, .ns = 3}, {.bs = 50, .dw = 22, .ns = 4}}},
|
||||
{/* Version 12 */
|
||||
.data_bytes = 466,
|
||||
.apat = {6, 32, 58, 0},
|
||||
.ecc = {{.bs = 58, .dw = 36, .ns = 6}, {.bs = 116, .dw = 92, .ns = 2}, {.bs = 42, .dw = 14, .ns = 7}, {.bs = 46, .dw = 20, .ns = 4}}},
|
||||
{/* Version 13 */
|
||||
.data_bytes = 532,
|
||||
.apat = {6, 34, 62, 0},
|
||||
.ecc = {{.bs = 59, .dw = 37, .ns = 8}, {.bs = 133, .dw = 107, .ns = 4}, {.bs = 33, .dw = 11, .ns = 12}, {.bs = 44, .dw = 20, .ns = 8}}},
|
||||
{/* Version 14 */
|
||||
.data_bytes = 581,
|
||||
.apat = {6, 26, 46, 66, 0},
|
||||
.ecc = {{.bs = 64, .dw = 40, .ns = 4}, {.bs = 145, .dw = 115, .ns = 3}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 36, .dw = 16, .ns = 11}}},
|
||||
{/* Version 15 */
|
||||
.data_bytes = 655,
|
||||
.apat = {6, 26, 48, 70, 0},
|
||||
.ecc = {{.bs = 65, .dw = 41, .ns = 5}, {.bs = 109, .dw = 87, .ns = 5}, {.bs = 36, .dw = 12, .ns = 11}, {.bs = 54, .dw = 24, .ns = 5}}},
|
||||
{/* Version 16 */
|
||||
.data_bytes = 733,
|
||||
.apat = {6, 26, 50, 74, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 7}, {.bs = 122, .dw = 98, .ns = 5}, {.bs = 45, .dw = 15, .ns = 3}, {.bs = 43, .dw = 19, .ns = 15}}},
|
||||
{/* Version 17 */
|
||||
.data_bytes = 815,
|
||||
.apat = {6, 30, 54, 78, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 135, .dw = 107, .ns = 1}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 1}}},
|
||||
{/* Version 18 */
|
||||
.data_bytes = 901,
|
||||
.apat = {6, 30, 56, 82, 0},
|
||||
.ecc = {{.bs = 69, .dw = 43, .ns = 9}, {.bs = 150, .dw = 120, .ns = 5}, {.bs = 42, .dw = 14, .ns = 2}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 19 */
|
||||
.data_bytes = 991,
|
||||
.apat = {6, 30, 58, 86, 0},
|
||||
.ecc = {{.bs = 70, .dw = 44, .ns = 3}, {.bs = 141, .dw = 113, .ns = 3}, {.bs = 39, .dw = 13, .ns = 9}, {.bs = 47, .dw = 21, .ns = 17}}},
|
||||
{/* Version 20 */
|
||||
.data_bytes = 1085,
|
||||
.apat = {6, 34, 62, 90, 0},
|
||||
.ecc = {{.bs = 67, .dw = 41, .ns = 3}, {.bs = 135, .dw = 107, .ns = 3}, {.bs = 43, .dw = 15, .ns = 15}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 21 */
|
||||
.data_bytes = 1156,
|
||||
.apat = {6, 28, 50, 72, 92, 0},
|
||||
.ecc = {{.bs = 68, .dw = 42, .ns = 17}, {.bs = 144, .dw = 116, .ns = 4}, {.bs = 46, .dw = 16, .ns = 19}, {.bs = 50, .dw = 22, .ns = 17}}},
|
||||
{/* Version 22 */
|
||||
.data_bytes = 1258,
|
||||
.apat = {6, 26, 50, 74, 98, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 17}, {.bs = 139, .dw = 111, .ns = 2}, {.bs = 37, .dw = 13, .ns = 34}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 23 */
|
||||
.data_bytes = 1364,
|
||||
.apat = {6, 30, 54, 78, 102, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 4}, {.bs = 151, .dw = 121, .ns = 4}, {.bs = 45, .dw = 15, .ns = 16}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 24 */
|
||||
.data_bytes = 1474,
|
||||
.apat = {6, 28, 54, 80, 106, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 6}, {.bs = 147, .dw = 117, .ns = 6}, {.bs = 46, .dw = 16, .ns = 30}, {.bs = 54, .dw = 24, .ns = 11}}},
|
||||
{/* Version 25 */
|
||||
.data_bytes = 1588,
|
||||
.apat = {6, 32, 58, 84, 110, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 8}, {.bs = 132, .dw = 106, .ns = 8}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 7}}},
|
||||
{/* Version 26 */
|
||||
.data_bytes = 1706,
|
||||
.apat = {6, 30, 58, 86, 114, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 19}, {.bs = 142, .dw = 114, .ns = 10}, {.bs = 46, .dw = 16, .ns = 33}, {.bs = 50, .dw = 22, .ns = 28}}},
|
||||
{/* Version 27 */
|
||||
.data_bytes = 1828,
|
||||
.apat = {6, 34, 62, 90, 118, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 22}, {.bs = 152, .dw = 122, .ns = 8}, {.bs = 45, .dw = 15, .ns = 12}, {.bs = 53, .dw = 23, .ns = 8}}},
|
||||
{/* Version 28 */
|
||||
.data_bytes = 1921,
|
||||
.apat = {6, 26, 50, 74, 98, 122, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 3}, {.bs = 147, .dw = 117, .ns = 3}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 4}}},
|
||||
{/* Version 29 */
|
||||
.data_bytes = 2051,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 0},
|
||||
.ecc = {{.bs = 73, .dw = 45, .ns = 21}, {.bs = 146, .dw = 116, .ns = 7}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 53, .dw = 23, .ns = 1}}},
|
||||
{/* Version 30 */
|
||||
.data_bytes = 2185,
|
||||
.apat = {6, 26, 52, 78, 104, 130, 0},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 19}, {.bs = 145, .dw = 115, .ns = 5}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 15}}},
|
||||
{/* Version 31 */
|
||||
.data_bytes = 2323,
|
||||
.apat = {6, 30, 56, 82, 108, 134, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 2}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 45, .dw = 15, .ns = 23}, {.bs = 54, .dw = 24, .ns = 42}}},
|
||||
{/* Version 32 */
|
||||
.data_bytes = 2465,
|
||||
.apat = {6, 34, 60, 86, 112, 138, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 10}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 19}, {.bs = 54, .dw = 24, .ns = 10}}},
|
||||
{/* Version 33 */
|
||||
.data_bytes = 2611,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 17}, {.bs = 45, .dw = 15, .ns = 11}, {.bs = 54, .dw = 24, .ns = 29}}},
|
||||
{/* Version 34 */
|
||||
.data_bytes = 2761,
|
||||
.apat = {6, 34, 62, 90, 118, 146, 0},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 14}, {.bs = 145, .dw = 115, .ns = 13}, {.bs = 46, .dw = 16, .ns = 59}, {.bs = 54, .dw = 24, .ns = 44}}},
|
||||
{/* Version 35 */
|
||||
.data_bytes = 2876,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 150},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 12}, {.bs = 151, .dw = 121, .ns = 12}, {.bs = 45, .dw = 15, .ns = 22}, {.bs = 54, .dw = 24, .ns = 39}}},
|
||||
{/* Version 36 */
|
||||
.data_bytes = 3034,
|
||||
.apat = {6, 24, 50, 76, 102, 128, 154},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 6}, {.bs = 151, .dw = 121, .ns = 6}, {.bs = 45, .dw = 15, .ns = 2}, {.bs = 54, .dw = 24, .ns = 46}}},
|
||||
{/* Version 37 */
|
||||
.data_bytes = 3196,
|
||||
.apat = {6, 28, 54, 80, 106, 132, 158},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 29}, {.bs = 152, .dw = 122, .ns = 17}, {.bs = 45, .dw = 15, .ns = 24}, {.bs = 54, .dw = 24, .ns = 49}}},
|
||||
{/* Version 38 */
|
||||
.data_bytes = 3362,
|
||||
.apat = {6, 32, 58, 84, 110, 136, 162},
|
||||
.ecc = {{.bs = 74, .dw = 46, .ns = 13}, {.bs = 152, .dw = 122, .ns = 4}, {.bs = 45, .dw = 15, .ns = 42}, {.bs = 54, .dw = 24, .ns = 48}}},
|
||||
{/* Version 39 */
|
||||
.data_bytes = 3532,
|
||||
.apat = {6, 26, 54, 82, 110, 138, 166},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 40}, {.bs = 147, .dw = 117, .ns = 20}, {.bs = 45, .dw = 15, .ns = 10}, {.bs = 54, .dw = 24, .ns = 43}}},
|
||||
{/* Version 40 */
|
||||
.data_bytes = 3706,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 170},
|
||||
.ecc = {{.bs = 75, .dw = 47, .ns = 18}, {.bs = 148, .dw = 118, .ns = 19}, {.bs = 45, .dw = 15, .ns = 20}, {.bs = 54, .dw = 24, .ns = 34}}}};
|
||||
@@ -0,0 +1,88 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "collections.h"
|
||||
#define CHAR_BITS (sizeof(char) * 8)
|
||||
#define CHAR_MASK (CHAR_BITS - 1)
|
||||
#define CHAR_SHIFT IM_LOG2(CHAR_MASK)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len)
|
||||
{
|
||||
ptr->len = 0;
|
||||
ptr->size = size;
|
||||
ptr->data_len = data_len;
|
||||
ptr->data = (char *)malloc(size * data_len);
|
||||
}
|
||||
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len)
|
||||
{
|
||||
ptr->data = (char *)malloc(255);
|
||||
ptr->data_len = data_len;
|
||||
ptr->size = 255 / data_len;
|
||||
ptr->len = 0;
|
||||
*size = ptr->size;
|
||||
}
|
||||
|
||||
void lifo_free(lifo_t *ptr)
|
||||
{
|
||||
if (ptr->data)
|
||||
{
|
||||
free(ptr->data);
|
||||
}
|
||||
}
|
||||
|
||||
void lifo_clear(lifo_t *ptr)
|
||||
{
|
||||
ptr->len = 0;
|
||||
}
|
||||
|
||||
size_t lifo_size(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_empty(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len;
|
||||
}
|
||||
|
||||
bool lifo_is_not_full(lifo_t *ptr)
|
||||
{
|
||||
return ptr->len != ptr->size;
|
||||
}
|
||||
|
||||
void lifo_enqueue(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
|
||||
ptr->len += 1;
|
||||
}
|
||||
|
||||
void lifo_dequeue(lifo_t *ptr, void *data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
||||
|
||||
ptr->len -= 1;
|
||||
}
|
||||
|
||||
void lifo_poke(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(ptr->data + (ptr->len * ptr->data_len), data, ptr->data_len);
|
||||
}
|
||||
|
||||
void lifo_peek(lifo_t *ptr, void *data)
|
||||
{
|
||||
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2017 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef __COLLECTIONS_H__
|
||||
#define __COLLECTIONS_H__
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
//////////
|
||||
// lifo //
|
||||
//////////
|
||||
|
||||
typedef struct lifo
|
||||
{
|
||||
size_t len, size, data_len;
|
||||
char *data;
|
||||
}
|
||||
__attribute__((aligned(8))) lifo_t;
|
||||
|
||||
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len);
|
||||
void lifo_alloc_all(lifo_t *ptr, size_t *size, size_t data_len);
|
||||
void lifo_free(lifo_t *ptr);
|
||||
void lifo_clear(lifo_t *ptr);
|
||||
size_t lifo_size(lifo_t *ptr);
|
||||
bool lifo_is_not_empty(lifo_t *ptr);
|
||||
bool lifo_is_not_full(lifo_t *ptr);
|
||||
void lifo_enqueue(lifo_t *ptr, void *data);
|
||||
void lifo_dequeue(lifo_t *ptr, void *data);
|
||||
void lifo_poke(lifo_t *ptr, void *data);
|
||||
void lifo_peek(lifo_t *ptr, void *data);
|
||||
|
||||
#endif /* __COLLECTIONS_H__ */
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Fast approximate math functions.
|
||||
*
|
||||
*/
|
||||
#ifndef __FMATH_H
|
||||
#define __FMATH_H
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
static inline float fast_sqrtf(float x)
|
||||
{
|
||||
//return sqrtf(x);
|
||||
asm("fsqrt.s %0, %1"
|
||||
: "=f"(x)
|
||||
: "f"(x));
|
||||
return x;
|
||||
}
|
||||
static inline int fast_floorf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline int fast_ceilf(float x)
|
||||
{
|
||||
return (int)(x + 0.9999f);
|
||||
}
|
||||
|
||||
static inline int fast_roundf(float x)
|
||||
{
|
||||
return (int)(x);
|
||||
}
|
||||
|
||||
static inline float fast_fabsf(float d)
|
||||
{
|
||||
return fabsf(d);
|
||||
}
|
||||
|
||||
extern int fast_floorf(float x);
|
||||
extern int fast_ceilf(float x);
|
||||
extern int fast_roundf(float x);
|
||||
extern float fast_atanf(float x);
|
||||
extern float fast_atan2f(float y, float x);
|
||||
extern float fast_expf(float x);
|
||||
extern float fast_cbrtf(float d);
|
||||
extern float fast_fabsf(float d);
|
||||
extern float fast_log(float x);
|
||||
extern float fast_log2(float x);
|
||||
extern float fast_powf(float a, float b);
|
||||
|
||||
/*#define fast_sqrtf(x) (sqrtf(x))
|
||||
#define fast_floorf(x) ((int)floorf(x))
|
||||
#define fast_ceilf(x) ((int)ceilf(x))
|
||||
#define fast_roundf(x) ((int)roundf(x))
|
||||
#define fast_atanf(x) (atanf(x))
|
||||
#define fast_atan2f(x,y) (atan2f((x),(y)))
|
||||
#define fast_expf(x) (expf(x))
|
||||
#define fast_cbrtf(x) (cbrtf(x))
|
||||
#define fast_fabsf(x) (fabsf(x))
|
||||
#define fast_log(x) (log(x))
|
||||
#define fast_log2(x) (log2(x))
|
||||
#define fast_powf(x,y) (powf((x),(y)))
|
||||
*/
|
||||
|
||||
extern const float cos_table[360];
|
||||
extern const float sin_table[360];
|
||||
#endif // __FMATH_H
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
|
||||
|
||||
# Create an INTERFACE library for our C module.
|
||||
|
||||
add_library(usermod_c_mpos INTERFACE)
|
||||
|
||||
set(MPOS_C_INCLUDES)
|
||||
|
||||
set(MPOS_C_SOURCES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/hello_world.c
|
||||
)
|
||||
|
||||
# Add our source files to the lib
|
||||
target_sources(usermod_c_mpos INTERFACE ${MPOS_C_SOURCES})
|
||||
|
||||
# Add include directories.
|
||||
target_include_directories(usermod_c_mpos INTERFACE ${MPOS_C_INCLUDES})
|
||||
|
||||
# Link our INTERFACE library to the usermod target.
|
||||
target_link_libraries(usermod INTERFACE usermod_c_mpos)
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
|
||||
|
||||
################################################################################
|
||||
# lcd_bus build rules
|
||||
|
||||
MOD_DIR := $(USERMOD_DIR)
|
||||
|
||||
ifneq (,$(findstring -Wno-missing-field-initializers, $(CFLAGS_USERMOD)))
|
||||
CFLAGS_USERMOD += -Wno-missing-field-initializers
|
||||
endif
|
||||
|
||||
SRC_USERMOD_C += $(MOD_DIR)/src/hello_world.c
|
||||
|
||||
SRC_USERMOD_C += $(MOD_DIR)/esp32-quirc/lib/identify.c
|
||||
SRC_USERMOD_C += $(MOD_DIR)/esp32-quirc/lib/version_db.c
|
||||
SRC_USERMOD_C += $(MOD_DIR)/esp32-quirc/lib/decode.c
|
||||
SRC_USERMOD_C += $(MOD_DIR)/esp32-quirc/lib/quirc.c
|
||||
SRC_USERMOD_C += $(MOD_DIR)/esp32-quirc/openmv/collections.c
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "../esp32-quirc/lib/quirc.h"
|
||||
|
||||
//#error "building hello world from lcd_utils"
|
||||
|
||||
// C function to print "Hello World"
|
||||
static mp_obj_t hello_world(void) {
|
||||
printf("Hello World from C with quirc!\n");
|
||||
|
||||
struct quirc *qr;
|
||||
qr = quirc_new();
|
||||
quirc_destroy(qr);
|
||||
|
||||
return mp_const_none; // MicroPython functions typically return None
|
||||
}
|
||||
|
||||
// Define the function entry in the module
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(hello_world_obj, hello_world);
|
||||
|
||||
// Module function table
|
||||
static const mp_rom_map_elem_t hello_world_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hello_world) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_hello), MP_ROM_PTR(&hello_world_obj) },
|
||||
};
|
||||
|
||||
// Module globals dictionary
|
||||
static MP_DEFINE_CONST_DICT(hello_world_module_globals, hello_world_module_globals_table);
|
||||
|
||||
// Module definition
|
||||
const mp_obj_module_t hello_world_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&hello_world_module_globals,
|
||||
};
|
||||
|
||||
// Register the module with MicroPython
|
||||
MP_REGISTER_MODULE(MP_QSTR_hello_world, hello_world_module);
|
||||
Reference in New Issue
Block a user