Add outer alloc memory buffer options.

Add outer_alloc flag
Add int quirc_set_image_buffer(struct quirc* q, uint8_t* image_buffer);
call quirc_set_image_buffer(struct quirc* q, uint8_t* image_buffer); before int quirc_resize(struct quirc *q, int w, int h);
tested on esp32s2 (esp-idf 4.2)
This commit is contained in:
hassenlin 2021-10-08 16:44:16 +08:00
parent 516d91a94d
commit 883f44d8b0
3 changed files with 51 additions and 16 deletions

View file

@ -36,7 +36,9 @@ struct quirc *quirc_new(void)
void quirc_destroy(struct quirc *q) void quirc_destroy(struct quirc *q)
{ {
if (!q->outer_alloc)
free(q->image); free(q->image);
/* q->pixels may alias q->image when their type representation is of the /* q->pixels may alias q->image when their type representation is of the
same size, so we need to be careful here to avoid a double free */ same size, so we need to be careful here to avoid a double free */
if (!QUIRC_PIXEL_ALIAS_IMAGE) if (!QUIRC_PIXEL_ALIAS_IMAGE)
@ -44,14 +46,28 @@ void quirc_destroy(struct quirc *q)
free(q->flood_fill_vars); free(q->flood_fill_vars);
free(q); free(q);
} }
int quirc_set_image_buffer(struct quirc* q, uint8_t* image_buffer) {
int quirc_resize(struct quirc *q, int w, int h) if (q->image == image_buffer) {
{ q->outer_alloc = (q->image == NULL)? 0 : 1;
uint8_t *image = NULL; return 0;
quirc_pixel_t *pixels = NULL; }
if (q->image != NULL && !q->outer_alloc) {
free(q->image);
q->image = NULL;
q->outer_alloc = 0;
}
if (image_buffer != NULL) {
q->image = image_buffer;
q->outer_alloc = 1;
}
return 0;
}
int quirc_resize(struct quirc* q, int w, int h) {
uint8_t* image = NULL;
quirc_pixel_t* pixels = NULL;
size_t num_vars; size_t num_vars;
size_t vars_byte_size; size_t vars_byte_size;
struct quirc_flood_fill_vars *vars = NULL; struct quirc_flood_fill_vars* vars = NULL;
/* /*
* XXX: w and h should be size_t (or at least unsigned) as negatives * XXX: w and h should be size_t (or at least unsigned) as negatives
@ -66,9 +82,11 @@ int quirc_resize(struct quirc *q, int w, int h)
* alloc a new buffer for q->image. We avoid realloc(3) because we want * alloc a new buffer for q->image. We avoid realloc(3) because we want
* on failure to be leave `q` in a consistant, unmodified state. * on failure to be leave `q` in a consistant, unmodified state.
*/ */
image = calloc(w, h); if (!q->outer_alloc) {
image = calloc(w , h);
if (!image) if (!image)
goto fail; goto fail;
}
/* compute the "old" (i.e. currently allocated) and the "new" /* compute the "old" (i.e. currently allocated) and the "new"
(i.e. requested) image dimensions */ (i.e. requested) image dimensions */
@ -81,11 +99,12 @@ int quirc_resize(struct quirc *q, int w, int h)
* old buffer when the new size is greater and (b) to write beyond the * old buffer when the new size is greater and (b) to write beyond the
* new buffer when the new size is smaller, hence the min computation. * new buffer when the new size is smaller, hence the min computation.
*/ */
(void)memcpy(image, q->image, min); if (q->image)
(void)memcpy(image , q->image , min);
/* alloc a new buffer for q->pixels if needed */ /* alloc a new buffer for q->pixels if needed */
if (!QUIRC_PIXEL_ALIAS_IMAGE) { if (!QUIRC_PIXEL_ALIAS_IMAGE) {
pixels = calloc(newdim, sizeof(quirc_pixel_t)); pixels = calloc(newdim , sizeof(quirc_pixel_t));
if (!pixels) if (!pixels)
goto fail; goto fail;
} }
@ -120,8 +139,12 @@ int quirc_resize(struct quirc *q, int w, int h)
/* alloc succeeded, update `q` with the new size and buffers */ /* alloc succeeded, update `q` with the new size and buffers */
q->w = w; q->w = w;
q->h = h; q->h = h;
if(!q->outer_alloc) {
if (q->image != NULL)
free(q->image); free(q->image);
q->image = image; q->image = image;
}
if (!QUIRC_PIXEL_ALIAS_IMAGE) { if (!QUIRC_PIXEL_ALIAS_IMAGE) {
free(q->pixels); free(q->pixels);
q->pixels = pixels; q->pixels = pixels;
@ -133,6 +156,7 @@ int quirc_resize(struct quirc *q, int w, int h)
return 0; return 0;
/* NOTREACHED */ /* NOTREACHED */
fail: fail:
if (!q->outer_alloc)
free(image); free(image);
free(pixels); free(pixels);
free(vars); free(vars);

View file

@ -36,13 +36,22 @@ struct quirc *quirc_new(void);
/* Destroy a QR-code recognizer. */ /* Destroy a QR-code recognizer. */
void quirc_destroy(struct quirc *q); void quirc_destroy(struct quirc *q);
/* Set the QR-code recognizer. use internal allocation memory or external
* allocation memory buffer.
* specified before call quirc_resize. use internal allocation memory buffer.
*
* This function returns 0 on success, or -1 if sufficient memory could
* not be allocated.
*/
int quirc_set_image_buffer(struct quirc* q, uint8_t* image_buffer);
/* Resize the QR-code recognizer. The size of an image must be /* Resize the QR-code recognizer. The size of an image must be
* specified before codes can be analyzed. * specified before codes can be analyzed.
* *
* This function returns 0 on success, or -1 if sufficient memory could * This function returns 0 on success, or -1 if sufficient memory could
* not be allocated. * not be allocated.
*/ */
int quirc_resize(struct quirc *q, int w, int h); int quirc_resize(struct quirc* q, int w, int h);
/* These functions are used to process images for QR-code recognition. /* These functions are used to process images for QR-code recognition.
* quirc_begin() must first be called to obtain access to a buffer into * quirc_begin() must first be called to obtain access to a buffer into

View file

@ -103,6 +103,8 @@ struct quirc {
size_t num_flood_fill_vars; size_t num_flood_fill_vars;
struct quirc_flood_fill_vars *flood_fill_vars; struct quirc_flood_fill_vars *flood_fill_vars;
uint8_t outer_alloc;
}; };
/************************************************************************ /************************************************************************