Add support for allocating heap instead of stack memory

This can be enabled by defining `QUIRC_USE_HEAP`.
Define this before import, or add `-D QUIRC_USE_HEAP` flag while compiling.
This commit is contained in:
MU-Software 2022-01-10 02:14:14 +09:00
parent 516d91a94d
commit 18c27d6dd5
2 changed files with 134 additions and 43 deletions

View file

@ -179,15 +179,19 @@ static void berlekamp_massey(const uint8_t *s, int N,
const struct galois_field *gf,
uint8_t *sigma)
{
uint8_t C[MAX_POLY];
uint8_t B[MAX_POLY];
#ifdef QUIRC_USE_HEAP
uint8_t *C = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
uint8_t *B = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
#else
uint8_t C[MAX_POLY] = {0};
uint8_t B[MAX_POLY] = {0};
#endif
int L = 0;
int m = 1;
uint8_t b = 1;
int n;
memset(B, 0, sizeof(B));
memset(C, 0, sizeof(C));
B[0] = 1;
C[0] = 1;
@ -210,21 +214,35 @@ static void berlekamp_massey(const uint8_t *s, int N,
if (!d) {
m++;
} else if (L * 2 <= n) {
uint8_t T[MAX_POLY];
#ifdef QUIRC_USE_HEAP
uint8_t *T = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
#else
uint8_t T[MAX_POLY] = {0};
#endif
memcpy(T, C, sizeof(T));
memcpy(T, C, sizeof(uint8_t) * MAX_POLY);
poly_add(C, B, mult, m, gf);
memcpy(B, T, sizeof(B));
memcpy(B, T, sizeof(uint8_t) * MAX_POLY);
L = n + 1 - L;
b = d;
m = 1;
#ifdef QUIRC_USE_HEAP
free(T);
#endif
} else {
poly_add(C, B, mult, m, gf);
m++;
}
}
memcpy(sigma, C, MAX_POLY);
memcpy(sigma, C, sizeof(uint8_t) * MAX_POLY);
#ifdef QUIRC_USE_HEAP
free(B);
free(C);
#endif
}
/************************************************************************
@ -238,7 +256,7 @@ static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
int nonzero = 0;
int i;
memset(s, 0, MAX_POLY);
memset(s, 0, sizeof(uint8_t) * MAX_POLY);
for (i = 0; i < npar; i++) {
int j;
@ -266,7 +284,7 @@ static void eloc_poly(uint8_t *omega,
{
int i;
memset(omega, 0, MAX_POLY);
memset(omega, 0, sizeof(uint8_t) * MAX_POLY);
for (i = 0; i < npar; i++) {
const uint8_t a = sigma[i];
@ -295,20 +313,36 @@ static quirc_decode_error_t correct_block(uint8_t *data,
const struct quirc_rs_params *ecc)
{
int npar = ecc->bs - ecc->dw;
uint8_t s[MAX_POLY];
uint8_t sigma[MAX_POLY];
uint8_t sigma_deriv[MAX_POLY];
uint8_t omega[MAX_POLY];
int i;
#ifdef QUIRC_USE_HEAP
uint8_t *s = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
#else
uint8_t s[MAX_POLY] = {0};
#endif
/* Compute syndrome vector */
if (!block_syndromes(data, ecc->bs, npar, s))
if (!block_syndromes(data, ecc->bs, npar, s)) {
#ifdef QUIRC_USE_HEAP
free(s);
#endif
return QUIRC_SUCCESS;
}
#ifdef QUIRC_USE_HEAP
uint8_t *sigma = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
uint8_t *sigma_deriv = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
uint8_t *omega = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
#else
uint8_t sigma[MAX_POLY] = {0};
uint8_t sigma_deriv[MAX_POLY] = {0};
uint8_t omega[MAX_POLY] = {0};
#endif
berlekamp_massey(s, npar, &gf256, sigma);
/* Compute derivative of sigma */
memset(sigma_deriv, 0, MAX_POLY);
for (i = 0; i + 1 < MAX_POLY; i += 2)
sigma_deriv[i] = sigma[i + 1];
@ -329,8 +363,23 @@ static quirc_decode_error_t correct_block(uint8_t *data,
}
}
if (block_syndromes(data, ecc->bs, npar, s))
#ifdef QUIRC_USE_HEAP
free(sigma);
free(sigma_deriv);
free(omega);
#endif
if (block_syndromes(data, ecc->bs, npar, s)){
#ifdef QUIRC_USE_HEAP
free(s);
#endif
return QUIRC_ERROR_DATA_ECC;
}
#ifdef QUIRC_USE_HEAP
free(s);
#endif
return QUIRC_SUCCESS;
}
@ -350,7 +399,7 @@ static int format_syndromes(uint16_t u, uint8_t *s)
int i;
int nonzero = 0;
memset(s, 0, MAX_POLY);
memset(s, 0, sizeof(uint8_t) * MAX_POLY);
for (i = 0; i < FORMAT_SYNDROMES; i++) {
int j;
@ -371,14 +420,28 @@ static quirc_decode_error_t correct_format(uint16_t *f_ret)
{
uint16_t u = *f_ret;
int i;
uint8_t s[MAX_POLY];
uint8_t sigma[MAX_POLY];
#ifdef QUIRC_USE_HEAP
uint8_t *s = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
#else
uint8_t s[MAX_POLY] = {0};
#endif
/* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
* to get S_1 .. S_6 (but we index them from 0).
*/
if (!format_syndromes(u, s))
if (!format_syndromes(u, s)) {
#ifdef QUIRC_USE_HEAP
free(s);
#endif
return QUIRC_SUCCESS;
}
#ifdef QUIRC_USE_HEAP
uint8_t *sigma = (uint8_t*)calloc(MAX_POLY, sizeof(uint8_t));
#else
uint8_t sigma[MAX_POLY] = {0};
#endif
berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
@ -387,6 +450,10 @@ static quirc_decode_error_t correct_format(uint16_t *f_ret)
if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
u ^= (1 << i);
#ifdef QUIRC_USE_HEAP
free(sigma);
#endif
if (format_syndromes(u, s))
return QUIRC_ERROR_FORMAT_ECC;
@ -884,29 +951,34 @@ quirc_decode_error_t quirc_decode(const struct quirc_code *code,
struct quirc_data *data)
{
quirc_decode_error_t err;
struct datastream ds;
if (code->size > QUIRC_MAX_GRID_SIZE)
return QUIRC_ERROR_INVALID_GRID_SIZE;
#ifdef QUIRC_USE_HEAP
struct datastream *dsp = (struct datastream*)calloc(1, sizeof(struct datastream));
#else
struct datastream ds = {0};
struct datastream *dsp = &ds;
#endif
if ((code->size - 17) % 4)
return QUIRC_ERROR_INVALID_GRID_SIZE;
memset(data, 0, sizeof(struct quirc_data) * 1);
memset(data, 0, sizeof(*data));
memset(&ds, 0, sizeof(ds));
if (code->size > QUIRC_MAX_GRID_SIZE || (code->size - 17) % 4) {
err = QUIRC_ERROR_INVALID_GRID_SIZE;
goto on_error;
}
data->version = (code->size - 17) / 4;
if (data->version < 1 ||
data->version > QUIRC_MAX_VERSION)
return QUIRC_ERROR_INVALID_VERSION;
if (data->version < 1 || data->version > QUIRC_MAX_VERSION) {
err = QUIRC_ERROR_INVALID_VERSION;
goto on_error;
}
/* Read format information -- try both locations */
err = read_format(code, data, 0);
if (err)
err = read_format(code, data, 1);
if (err)
return err;
goto on_error;
/*
* Borrow data->payload to store the raw bits.
@ -916,20 +988,31 @@ quirc_decode_error_t quirc_decode(const struct quirc_code *code,
* on the stack.
*/
ds.raw = data->payload;
dsp->raw = data->payload;
read_data(code, data, &ds);
err = codestream_ecc(data, &ds);
read_data(code, data, dsp);
err = codestream_ecc(data, dsp);
if (err)
return err;
goto on_error;
ds.raw = NULL; /* We've done with this buffer. */
dsp->raw = NULL; /* We've done with this buffer. */
err = decode_payload(data, &ds);
err = decode_payload(data, dsp);
if (err)
return err;
goto on_error;
#ifdef QUIRC_USE_HEAP
free(dsp);
#endif
return QUIRC_SUCCESS;
on_error:
#ifdef QUIRC_USE_HEAP
free(dsp);
#endif
return err;
}
void quirc_flip(struct quirc_code *code)

View file

@ -289,8 +289,12 @@ static uint8_t otsu(const struct quirc *q)
unsigned int numPixels = q->w * q->h;
// Calculate histogram
unsigned int histogram[UINT8_MAX + 1];
(void)memset(histogram, 0, sizeof(histogram));
#ifdef QUIRC_USE_HEAP
unsigned int *histogram = (unsigned int*)calloc(UINT8_MAX + 1, sizeof(unsigned int));
#else
unsigned int histogram[UINT8_MAX + 1] = {0};
#endif
uint8_t* ptr = q->image;
unsigned int length = numPixels;
while (length--) {
@ -332,6 +336,10 @@ static uint8_t otsu(const struct quirc *q)
}
}
#ifdef QUIRC_USE_HEAP
free(histogram);
#endif
return threshold;
}
@ -671,11 +679,11 @@ static void measure_grid_size(struct quirc *q, int index)
double bc = length(b->corners[0], c->corners[1]);
double capstone_bc_size = (length(b->corners[0], b->corners[1]) + length(c->corners[0], c->corners[1]))/2.0;
double hor_grid = 7.0 * bc / capstone_bc_size;
double grid_size_estimate = (ver_grid + hor_grid) / 2;
int ver = (int)((grid_size_estimate - 17.0 + 2.0) / 4.0);
qr->grid_size = 4*ver + 17;
}