Add c_mpos module with quirc

This commit is contained in:
Thomas Farstrike
2025-05-12 16:07:00 +02:00
parent fc12d9e35a
commit a65e48ebb5
17 changed files with 3462 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
idf_component_register(SRC_DIRS "lib" "openmv"
INCLUDE_DIRS "lib" ".")
target_compile_options(${COMPONENT_LIB} PRIVATE -Ofast)
+16
View File
@@ -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.
+88
View File
@@ -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
+16
View File
@@ -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.
+193
View File
@@ -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
+103
View File
@@ -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";
}
+190
View File
@@ -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
+135
View File
@@ -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
+184
View File
@@ -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}}}};
+88
View File
@@ -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);
}
+33
View File
@@ -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__ */
+70
View File
@@ -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
+20
View File
@@ -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)
+19
View File
@@ -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
+38
View File
@@ -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);