Merge pull request #2132 from openmv/refactor_collections

imlib: Refactor collections linked list.
This commit is contained in:
Ibrahim Abdelkader 2024-02-07 20:54:45 +02:00 committed by GitHub
commit 7f5d05f3aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 166 additions and 361 deletions

View File

@ -18,16 +18,16 @@ void imlib_binary(image_t *out, image_t *img, list_t *thresholds, bool invert, b
bmp.pixfmt = PIXFORMAT_BINARY; bmp.pixfmt = PIXFORMAT_BINARY;
bmp.data = fb_alloc0(image_size(&bmp), FB_ALLOC_NO_HINT); bmp.data = fb_alloc0(image_size(&bmp), FB_ALLOC_NO_HINT);
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
switch (img->pixfmt) { switch (img->pixfmt) {
case PIXFORMAT_BINARY: { case PIXFORMAT_BINARY: {
for (int y = 0, yy = img->h; y < yy; y++) { for (int y = 0, yy = img->h; y < yy; y++) {
uint32_t *old_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y); uint32_t *old_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y);
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y); uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
for (int x = 0, xx = img->w; x < xx; x++) { for (int x = 0, xx = img->w; x < xx; x++) {
if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(old_row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(old_row_ptr, x), lnk_data, invert)) {
IMAGE_SET_BINARY_PIXEL_FAST(bmp_row_ptr, x); IMAGE_SET_BINARY_PIXEL_FAST(bmp_row_ptr, x);
} }
} }
@ -39,7 +39,7 @@ void imlib_binary(image_t *out, image_t *img, list_t *thresholds, bool invert, b
uint8_t *old_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y); uint8_t *old_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y);
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y); uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
for (int x = 0, xx = img->w; x < xx; x++) { for (int x = 0, xx = img->w; x < xx; x++) {
if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(old_row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(old_row_ptr, x), lnk_data, invert)) {
IMAGE_SET_BINARY_PIXEL_FAST(bmp_row_ptr, x); IMAGE_SET_BINARY_PIXEL_FAST(bmp_row_ptr, x);
} }
} }
@ -51,7 +51,7 @@ void imlib_binary(image_t *out, image_t *img, list_t *thresholds, bool invert, b
uint16_t *old_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y); uint16_t *old_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y);
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y); uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
for (int x = 0, xx = img->w; x < xx; x++) { for (int x = 0, xx = img->w; x < xx; x++) {
if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(old_row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(old_row_ptr, x), lnk_data, invert)) {
IMAGE_SET_BINARY_PIXEL_FAST(bmp_row_ptr, x); IMAGE_SET_BINARY_PIXEL_FAST(bmp_row_ptr, x);
} }
} }

View File

@ -152,9 +152,8 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
list_init(out, sizeof(find_blobs_list_lnk_data_t)); list_init(out, sizeof(find_blobs_list_lnk_data_t));
size_t code = 0; size_t code = 0;
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
switch (ptr->pixfmt) { switch (ptr->pixfmt) {
case PIXFORMAT_BINARY: { case PIXFORMAT_BINARY: {
@ -163,7 +162,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y); uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w, x_max = xx - 1; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w, x_max = xx - 1; x < xx; x += x_stride) {
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row_ptr, x)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row_ptr, x))
&& COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { && COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
int old_x = x; int old_x = x;
int old_y = y; int old_y = y;
@ -205,14 +204,14 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
while ((left > roi->x) while ((left > roi->x)
&& (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, left - 1)) && (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, left - 1))
&& COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, left - 1), &lnk_data, && COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, left - 1), lnk_data,
invert)) { invert)) {
left--; left--;
} }
while ((right < (roi->x + roi->w - 1)) while ((right < (roi->x + roi->w - 1))
&& (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, right + 1)) && (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, right + 1))
&& COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, right + 1), &lnk_data, && COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, right + 1), lnk_data,
invert)) { invert)) {
right++; right++;
} }
@ -278,7 +277,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i))
&& (ok = && (ok =
COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, i), COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, i),
&lnk_data, lnk_data,
invert))) { invert))) {
xylr_t context; xylr_t context;
context.x = x; context.x = x;
@ -314,7 +313,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i))
&& (ok = && (ok =
COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, i), COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, i),
&lnk_data, lnk_data,
invert))) { invert))) {
xylr_t context; xylr_t context;
context.x = x; context.x = x;
@ -469,7 +468,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y); uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w, x_max = xx - 1; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w, x_max = xx - 1; x < xx; x += x_stride) {
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row_ptr, x)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row_ptr, x))
&& COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { && COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
int old_x = x; int old_x = x;
int old_y = y; int old_y = y;
@ -511,14 +510,14 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
while ((left > roi->x) while ((left > roi->x)
&& (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, left - 1)) && (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, left - 1))
&& COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, left - 1), &lnk_data, && COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, left - 1), lnk_data,
invert)) { invert)) {
left--; left--;
} }
while ((right < (roi->x + roi->w - 1)) while ((right < (roi->x + roi->w - 1))
&& (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, right + 1)) && (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, right + 1))
&& COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, right + 1), &lnk_data, && COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, right + 1), lnk_data,
invert)) { invert)) {
right++; right++;
} }
@ -584,7 +583,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i))
&& (ok = && (ok =
COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, i), COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, i),
&lnk_data, lnk_data,
invert))) { invert))) {
xylr_t context; xylr_t context;
context.x = x; context.x = x;
@ -620,7 +619,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i))
&& (ok = && (ok =
COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, i), COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, i),
&lnk_data, lnk_data,
invert))) { invert))) {
xylr_t context; xylr_t context;
context.x = x; context.x = x;
@ -775,7 +774,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y); uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w, x_max = xx - 1; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w, x_max = xx - 1; x < xx; x += x_stride) {
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row_ptr, x)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row_ptr, x))
&& COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { && COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
int old_x = x; int old_x = x;
int old_y = y; int old_y = y;
@ -817,14 +816,14 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
while ((left > roi->x) while ((left > roi->x)
&& (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, left - 1)) && (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, left - 1))
&& COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, left - 1), &lnk_data, && COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, left - 1), lnk_data,
invert)) { invert)) {
left--; left--;
} }
while ((right < (roi->x + roi->w - 1)) while ((right < (roi->x + roi->w - 1))
&& (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, right + 1)) && (!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, right + 1))
&& COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, right + 1), &lnk_data, && COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, right + 1), lnk_data,
invert)) { invert)) {
right++; right++;
} }
@ -890,7 +889,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i))
&& (ok = && (ok =
COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, i), COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, i),
&lnk_data, lnk_data,
invert))) { invert))) {
xylr_t context; xylr_t context;
context.x = x; context.x = x;
@ -926,7 +925,7 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i)) if ((!IMAGE_GET_BINARY_PIXEL_FAST(bmp_row, i))
&& (ok = && (ok =
COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, i), COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, i),
&lnk_data, lnk_data,
invert))) { invert))) {
xylr_t context; xylr_t context;
context.x = x; context.x = x;

View File

@ -1,8 +1,8 @@
/* /*
* This file is part of the OpenMV project. * This file is part of the OpenMV project.
* *
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io> * Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io> * Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
* *
* This work is licensed under the MIT license, see the file LICENSE for details. * This work is licensed under the MIT license, see the file LICENSE for details.
* *
@ -13,10 +13,7 @@
#define CHAR_MASK (CHAR_BITS - 1) #define CHAR_MASK (CHAR_BITS - 1)
#define CHAR_SHIFT IM_LOG2(CHAR_MASK) #define CHAR_SHIFT IM_LOG2(CHAR_MASK)
//////////// // Bitmap
// bitmap //
////////////
void bitmap_alloc(bitmap_t *ptr, size_t size) { void bitmap_alloc(bitmap_t *ptr, size_t size) {
ptr->size = size; ptr->size = size;
ptr->data = (char *) fb_alloc0(((size + CHAR_MASK) >> CHAR_SHIFT) * sizeof(char), FB_ALLOC_NO_HINT); ptr->data = (char *) fb_alloc0(((size + CHAR_MASK) >> CHAR_SHIFT) * sizeof(char), FB_ALLOC_NO_HINT);
@ -40,10 +37,7 @@ bool bitmap_bit_get(bitmap_t *ptr, size_t index) {
return (ptr->data[index >> CHAR_SHIFT] >> (index & CHAR_MASK)) & 1; return (ptr->data[index >> CHAR_SHIFT] >> (index & CHAR_MASK)) & 1;
} }
////////// // LIFO
// lifo //
//////////
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len) { void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len) {
ptr->len = 0; ptr->len = 0;
ptr->size = size; ptr->size = size;
@ -104,13 +98,10 @@ void lifo_peek(lifo_t *ptr, void *data) {
memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len); memcpy(data, ptr->data + ((ptr->len - 1) * ptr->data_len), ptr->data_len);
} }
////////// // FIFO
// fifo //
//////////
void fifo_alloc(fifo_t *ptr, size_t size, size_t data_len) { void fifo_alloc(fifo_t *ptr, size_t size, size_t data_len) {
ptr->head_ptr = 0; ptr->head = 0;
ptr->tail_ptr = 0; ptr->tail = 0;
ptr->len = 0; ptr->len = 0;
ptr->size = size; ptr->size = size;
ptr->data_len = data_len; ptr->data_len = data_len;
@ -123,8 +114,8 @@ void fifo_alloc_all(fifo_t *ptr, size_t *size, size_t data_len) {
ptr->data_len = data_len; ptr->data_len = data_len;
ptr->size = tmp_size / data_len; ptr->size = tmp_size / data_len;
ptr->len = 0; ptr->len = 0;
ptr->tail_ptr = 0; ptr->tail = 0;
ptr->head_ptr = 0; ptr->head = 0;
*size = ptr->size; *size = ptr->size;
} }
@ -135,8 +126,8 @@ void fifo_free(fifo_t *ptr) {
} }
void fifo_clear(fifo_t *ptr) { void fifo_clear(fifo_t *ptr) {
ptr->head_ptr = 0; ptr->head = 0;
ptr->tail_ptr = 0; ptr->tail = 0;
ptr->len = 0; ptr->len = 0;
} }
@ -153,48 +144,45 @@ bool fifo_is_not_full(fifo_t *ptr) {
} }
void fifo_enqueue(fifo_t *ptr, void *data) { void fifo_enqueue(fifo_t *ptr, void *data) {
memcpy(ptr->data + (ptr->head_ptr * ptr->data_len), data, ptr->data_len); memcpy(ptr->data + (ptr->head * ptr->data_len), data, ptr->data_len);
size_t temp = ptr->head_ptr + 1; size_t temp = ptr->head + 1;
if (temp == ptr->size) { if (temp == ptr->size) {
temp = 0; temp = 0;
} }
ptr->head_ptr = temp; ptr->head = temp;
ptr->len += 1; ptr->len += 1;
} }
void fifo_dequeue(fifo_t *ptr, void *data) { void fifo_dequeue(fifo_t *ptr, void *data) {
if (data) { if (data) {
memcpy(data, ptr->data + (ptr->tail_ptr * ptr->data_len), ptr->data_len); memcpy(data, ptr->data + (ptr->tail * ptr->data_len), ptr->data_len);
} }
size_t temp = ptr->tail_ptr + 1; size_t temp = ptr->tail + 1;
if (temp == ptr->size) { if (temp == ptr->size) {
temp = 0; temp = 0;
} }
ptr->tail_ptr = temp; ptr->tail = temp;
ptr->len -= 1; ptr->len -= 1;
} }
void fifo_poke(fifo_t *ptr, void *data) { void fifo_poke(fifo_t *ptr, void *data) {
memcpy(ptr->data + (ptr->head_ptr * ptr->data_len), data, ptr->data_len); memcpy(ptr->data + (ptr->head * ptr->data_len), data, ptr->data_len);
} }
void fifo_peek(fifo_t *ptr, void *data) { void fifo_peek(fifo_t *ptr, void *data) {
memcpy(data, ptr->data + (ptr->tail_ptr * ptr->data_len), ptr->data_len); memcpy(data, ptr->data + (ptr->tail * ptr->data_len), ptr->data_len);
} }
////////// // Linked List
// list //
//////////
void list_init(list_t *ptr, size_t data_len) { void list_init(list_t *ptr, size_t data_len) {
ptr->head_ptr = NULL; ptr->head = NULL;
ptr->tail_ptr = NULL; ptr->tail = NULL;
ptr->size = 0; ptr->size = 0;
ptr->data_len = data_len; ptr->data_len = data_len;
} }
@ -204,8 +192,8 @@ void list_copy(list_t *dst, list_t *src) {
} }
void list_free(list_t *ptr) { void list_free(list_t *ptr) {
for (list_lnk_t *i = ptr->head_ptr; i; ) { for (list_lnk_t *i = ptr->head; i; ) {
list_lnk_t *j = i->next_ptr; list_lnk_t *j = i->next;
xfree(i); xfree(i);
i = j; i = j;
} }
@ -214,8 +202,8 @@ void list_free(list_t *ptr) {
void list_clear(list_t *ptr) { void list_clear(list_t *ptr) {
list_free(ptr); list_free(ptr);
ptr->head_ptr = NULL; ptr->head = NULL;
ptr->tail_ptr = NULL; ptr->tail = NULL;
ptr->size = 0; ptr->size = 0;
} }
@ -228,15 +216,15 @@ void list_push_front(list_t *ptr, void *data) {
memcpy(tmp->data, data, ptr->data_len); memcpy(tmp->data, data, ptr->data_len);
if (ptr->size++) { if (ptr->size++) {
tmp->next_ptr = ptr->head_ptr; tmp->next = ptr->head;
tmp->prev_ptr = NULL; tmp->prev = NULL;
ptr->head_ptr->prev_ptr = tmp; ptr->head->prev = tmp;
ptr->head_ptr = tmp; ptr->head = tmp;
} else { } else {
tmp->next_ptr = NULL; tmp->next = NULL;
tmp->prev_ptr = NULL; tmp->prev = NULL;
ptr->head_ptr = tmp; ptr->head = tmp;
ptr->tail_ptr = tmp; ptr->tail = tmp;
} }
} }
@ -245,234 +233,84 @@ void list_push_back(list_t *ptr, void *data) {
memcpy(tmp->data, data, ptr->data_len); memcpy(tmp->data, data, ptr->data_len);
if (ptr->size++) { if (ptr->size++) {
tmp->next_ptr = NULL; tmp->next = NULL;
tmp->prev_ptr = ptr->tail_ptr; tmp->prev = ptr->tail;
ptr->tail_ptr->next_ptr = tmp; ptr->tail->next = tmp;
ptr->tail_ptr = tmp; ptr->tail = tmp;
} else { } else {
tmp->next_ptr = NULL; tmp->next = NULL;
tmp->prev_ptr = NULL; tmp->prev = NULL;
ptr->head_ptr = tmp; ptr->head = tmp;
ptr->tail_ptr = tmp; ptr->tail = tmp;
} }
} }
void list_pop_front(list_t *ptr, void *data) { void list_pop_front(list_t *ptr, void *data) {
list_lnk_t *tmp = ptr->head_ptr; list_lnk_t *tmp = ptr->head;
if (data) { if (data) {
memcpy(data, tmp->data, ptr->data_len); memcpy(data, tmp->data, ptr->data_len);
} }
if (tmp->next_ptr) { if (tmp->next) {
tmp->next_ptr->prev_ptr = NULL; tmp->next->prev = NULL;
} }
ptr->head_ptr = tmp->next_ptr; ptr->head = tmp->next;
ptr->size -= 1; ptr->size -= 1;
xfree(tmp); xfree(tmp);
} }
void list_pop_back(list_t *ptr, void *data) { void list_pop_back(list_t *ptr, void *data) {
list_lnk_t *tmp = ptr->tail_ptr; list_lnk_t *tmp = ptr->tail;
if (data) { if (data) {
memcpy(data, tmp->data, ptr->data_len); memcpy(data, tmp->data, ptr->data_len);
} }
tmp->prev_ptr->next_ptr = NULL; tmp->prev->next = NULL;
ptr->tail_ptr = tmp->prev_ptr; ptr->tail = tmp->prev;
ptr->size -= 1; ptr->size -= 1;
xfree(tmp); xfree(tmp);
} }
void list_get_front(list_t *ptr, void *data) { void list_get(list_t *ptr, list_lnk_t *lnk, void *data) {
memcpy(data, ptr->head_ptr->data, ptr->data_len);
}
void list_get_back(list_t *ptr, void *data) {
memcpy(data, ptr->tail_ptr->data, ptr->data_len);
}
void list_set_front(list_t *ptr, void *data) {
memcpy(ptr->head_ptr->data, data, ptr->data_len);
}
void list_set_back(list_t *ptr, void *data) {
memcpy(ptr->tail_ptr->data, data, ptr->data_len);
}
void list_insert(list_t *ptr, void *data, size_t index) {
if (index == 0) {
list_push_front(ptr, data);
} else if (index >= ptr->size) {
list_push_back(ptr, data);
} else if (index < (ptr->size >> 1)) {
list_lnk_t *i = ptr->head_ptr;
while (index) {
i = i->next_ptr;
index -= 1;
}
list_lnk_t *tmp = (list_lnk_t *) xalloc(sizeof(list_lnk_t) + ptr->data_len);
memcpy(tmp->data, data, ptr->data_len);
tmp->next_ptr = i;
tmp->prev_ptr = i->prev_ptr;
i->prev_ptr->next_ptr = tmp;
i->prev_ptr = tmp;
ptr->size += 1;
} else {
list_lnk_t *i = ptr->tail_ptr;
index = ptr->size - index - 1;
while (index) {
i = i->prev_ptr;
index -= 1;
}
list_lnk_t *tmp = (list_lnk_t *) xalloc(sizeof(list_lnk_t) + ptr->data_len);
memcpy(tmp->data, data, ptr->data_len);
tmp->next_ptr = i;
tmp->prev_ptr = i->prev_ptr;
i->prev_ptr->next_ptr = tmp;
i->prev_ptr = tmp;
ptr->size += 1;
}
}
void list_remove(list_t *ptr, void *data, size_t index) {
if (index == 0) {
list_pop_front(ptr, data);
} else if (index >= (ptr->size - 1)) {
list_pop_back(ptr, data);
} else if (index < (ptr->size >> 1)) {
list_lnk_t *i = ptr->head_ptr;
while (index) {
i = i->next_ptr;
index -= 1;
}
if (data) {
memcpy(data, i->data, ptr->data_len);
}
i->prev_ptr->next_ptr = i->next_ptr;
i->next_ptr->prev_ptr = i->prev_ptr;
ptr->size -= 1;
xfree(i);
} else {
list_lnk_t *i = ptr->tail_ptr;
index = ptr->size - index - 1;
while (index) {
i = i->prev_ptr;
index -= 1;
}
if (data) {
memcpy(data, i->data, ptr->data_len);
}
i->prev_ptr->next_ptr = i->next_ptr;
i->next_ptr->prev_ptr = i->prev_ptr;
ptr->size -= 1;
xfree(i);
}
}
void list_get(list_t *ptr, void *data, size_t index) {
if (index == 0) {
list_get_front(ptr, data);
} else if (index >= (ptr->size - 1)) {
list_get_back(ptr, data);
} else if (index < (ptr->size >> 1)) {
list_lnk_t *i = ptr->head_ptr;
while (index) {
i = i->next_ptr;
index -= 1;
}
memcpy(data, i->data, ptr->data_len);
} else {
list_lnk_t *i = ptr->tail_ptr;
index = ptr->size - index - 1;
while (index) {
i = i->prev_ptr;
index -= 1;
}
memcpy(data, i->data, ptr->data_len);
}
}
void list_set(list_t *ptr, void *data, size_t index) {
if (index == 0) {
list_set_front(ptr, data);
} else if (index >= (ptr->size - 1)) {
list_set_back(ptr, data);
} else if (index < (ptr->size >> 1)) {
list_lnk_t *i = ptr->head_ptr;
while (index) {
i = i->next_ptr;
index -= 1;
}
memcpy(i->data, data, ptr->data_len);
} else {
list_lnk_t *i = ptr->tail_ptr;
index = ptr->size - index - 1;
while (index) {
i = i->prev_ptr;
index -= 1;
}
memcpy(i->data, data, ptr->data_len);
}
}
//////////////
// iterator //
//////////////
list_lnk_t *iterator_start_from_head(list_t *ptr) {
return ptr->head_ptr;
}
list_lnk_t *iterator_start_from_tail(list_t *ptr) {
return ptr->tail_ptr;
}
list_lnk_t *iterator_next(list_lnk_t *lnk) {
return lnk->next_ptr;
}
list_lnk_t *iterator_prev(list_lnk_t *lnk) {
return lnk->prev_ptr;
}
void iterator_get(list_t *ptr, list_lnk_t *lnk, void *data) {
memcpy(data, lnk->data, ptr->data_len); memcpy(data, lnk->data, ptr->data_len);
} }
void iterator_set(list_t *ptr, list_lnk_t *lnk, void *data) { void list_set(list_t *ptr, list_lnk_t *lnk, void *data) {
memcpy(lnk->data, data, ptr->data_len); memcpy(lnk->data, data, ptr->data_len);
} }
void list_insert(list_t *ptr, list_lnk_t *lnk, void *data) {
if (ptr->head == lnk) {
list_push_front(ptr, data);
} else if (!lnk) {
list_push_back(ptr, data);
} else {
list_lnk_t *tmp = (list_lnk_t *) xalloc(sizeof(list_lnk_t) + ptr->data_len);
memcpy(tmp->data, data, ptr->data_len);
tmp->next = lnk;
tmp->prev = lnk->prev;
lnk->prev->next = tmp;
lnk->prev = tmp;
ptr->size += 1;
}
}
void list_remove(list_t *ptr, list_lnk_t *lnk, void *data) {
if (ptr->head == lnk) {
list_pop_front(ptr, data);
} else if (ptr->tail == lnk) {
list_pop_back(ptr, data);
} else {
if (data) {
memcpy(data, lnk->data, ptr->data_len);
}
lnk->prev->next = lnk->next;
lnk->next->prev = lnk->prev;
ptr->size -= 1;
xfree(lnk);
}
}

View File

@ -1,8 +1,8 @@
/* /*
* This file is part of the OpenMV project. * This file is part of the OpenMV project.
* *
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io> * Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io> * Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
* *
* This work is licensed under the MIT license, see the file LICENSE for details. * This work is licensed under the MIT license, see the file LICENSE for details.
* *
@ -13,15 +13,11 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
//////////// // Bitmap
// bitmap //
////////////
typedef struct bitmap { typedef struct bitmap {
size_t size; size_t size;
char *data; char *data;
} } bitmap_t;
bitmap_t;
void bitmap_alloc(bitmap_t *ptr, size_t size); void bitmap_alloc(bitmap_t *ptr, size_t size);
void bitmap_free(bitmap_t *ptr); void bitmap_free(bitmap_t *ptr);
@ -31,15 +27,13 @@ bool bitmap_bit_get(bitmap_t *ptr, size_t index);
#define BITMAP_COMPUTE_ROW_INDEX(image, y) (((image)->w) * (y)) #define BITMAP_COMPUTE_ROW_INDEX(image, y) (((image)->w) * (y))
#define BITMAP_COMPUTE_INDEX(row_index, x) ((row_index) + (x)) #define BITMAP_COMPUTE_INDEX(row_index, x) ((row_index) + (x))
////////// // LIFO
// lifo //
//////////
typedef struct lifo { typedef struct lifo {
size_t len, size, data_len; size_t len;
size_t size;
size_t data_len;
char *data; char *data;
} } lifo_t;
lifo_t;
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len); 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_alloc_all(lifo_t *ptr, size_t *size, size_t data_len);
@ -53,15 +47,15 @@ void lifo_dequeue(lifo_t *ptr, void *data);
void lifo_poke(lifo_t *ptr, void *data); void lifo_poke(lifo_t *ptr, void *data);
void lifo_peek(lifo_t *ptr, void *data); void lifo_peek(lifo_t *ptr, void *data);
////////// // FIFO
// fifo //
//////////
typedef struct fifo { typedef struct fifo {
size_t head_ptr, tail_ptr, len, size, data_len; size_t head;
size_t tail;
size_t len;
size_t size;
size_t data_len;
char *data; char *data;
} } fifo_t;
fifo_t;
void fifo_alloc(fifo_t *ptr, size_t size, size_t data_len); void fifo_alloc(fifo_t *ptr, size_t size, size_t data_len);
void fifo_alloc_all(fifo_t *ptr, size_t *size, size_t data_len); void fifo_alloc_all(fifo_t *ptr, size_t *size, size_t data_len);
@ -75,21 +69,19 @@ void fifo_dequeue(fifo_t *ptr, void *data);
void fifo_poke(fifo_t *ptr, void *data); void fifo_poke(fifo_t *ptr, void *data);
void fifo_peek(fifo_t *ptr, void *data); void fifo_peek(fifo_t *ptr, void *data);
////////// // Linked List
// list //
//////////
typedef struct list_lnk { typedef struct list_lnk {
struct list_lnk *next_ptr, *prev_ptr; struct list_lnk *next;
struct list_lnk *prev;
char data[]; char data[];
} } list_lnk_t;
list_lnk_t;
typedef struct list { typedef struct list {
list_lnk_t *head_ptr, *tail_ptr; list_lnk_t *head;
size_t size, data_len; list_lnk_t *tail;
} size_t size;
list_t; size_t data_len;
} list_t;
void list_init(list_t *ptr, size_t data_len); void list_init(list_t *ptr, size_t data_len);
void list_copy(list_t *dst, list_t *src); void list_copy(list_t *dst, list_t *src);
@ -100,24 +92,9 @@ void list_push_front(list_t *ptr, void *data);
void list_push_back(list_t *ptr, void *data); void list_push_back(list_t *ptr, void *data);
void list_pop_front(list_t *ptr, void *data); void list_pop_front(list_t *ptr, void *data);
void list_pop_back(list_t *ptr, void *data); void list_pop_back(list_t *ptr, void *data);
void list_get_front(list_t *ptr, void *data); void list_insert(list_t *ptr, list_lnk_t *lnk, void *data);
void list_get_back(list_t *ptr, void *data); void list_remove(list_t *ptr, list_lnk_t *lnk, void *data);
void list_set_front(list_t *ptr, void *data); #define list_for_each(iterator, list) \
void list_set_back(list_t *ptr, void *data); for (list_lnk_t *iterator = list->head; iterator != NULL; iterator = iterator->next)
void list_insert(list_t *ptr, void *data, size_t index); #define list_get_data(iterator) ((void *) iterator->data)
void list_remove(list_t *ptr, void *data, size_t index);
void list_get(list_t *ptr, void *data, size_t index);
void list_set(list_t *ptr, void *data, size_t index);
//////////////
// iterator //
//////////////
list_lnk_t *iterator_start_from_head(list_t *ptr);
list_lnk_t *iterator_start_from_tail(list_t *ptr);
list_lnk_t *iterator_next(list_lnk_t *lnk);
list_lnk_t *iterator_prev(list_lnk_t *lnk);
void iterator_get(list_t *ptr, list_lnk_t *lnk, void *data);
void iterator_set(list_t *ptr, list_lnk_t *lnk, void *data);
#endif /* __COLLECTIONS_H__ */ #endif /* __COLLECTIONS_H__ */

View File

@ -186,15 +186,13 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
// Reset pixel count. // Reset pixel count.
pixel_count = 0; pixel_count = 0;
if (!other) { if (!other) {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) {
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) {
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x); int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x);
if (COLOR_THRESHOLD_BINARY(pixel, &lnk_data, invert)) { if (COLOR_THRESHOLD_BINARY(pixel, lnk_data, invert)) {
((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++; ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++;
pixel_count++; pixel_count++;
} }
@ -202,9 +200,8 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
} }
} }
} else { } else {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) {
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y), uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y),
@ -212,7 +209,7 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) {
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) ^ IMAGE_GET_BINARY_PIXEL_FAST(other_row_ptr, int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) ^ IMAGE_GET_BINARY_PIXEL_FAST(other_row_ptr,
x); x);
if (COLOR_THRESHOLD_BINARY(pixel, &lnk_data, invert)) { if (COLOR_THRESHOLD_BINARY(pixel, lnk_data, invert)) {
((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++; ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_BINARY_MIN) * mult)]++;
pixel_count++; pixel_count++;
} }
@ -262,15 +259,14 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
// Reset pixel count. // Reset pixel count.
pixel_count = 0; pixel_count = 0;
if (!other) { if (!other) {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) {
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) {
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x); int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x);
if (COLOR_THRESHOLD_GRAYSCALE(pixel, &lnk_data, invert)) { if (COLOR_THRESHOLD_GRAYSCALE(pixel, lnk_data, invert)) {
((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++;
pixel_count++; pixel_count++;
} }
@ -278,9 +274,8 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
} }
} }
} else { } else {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) {
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y), uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y),
@ -290,7 +285,7 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
abs(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, abs(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr,
x) - IMAGE_GET_GRAYSCALE_PIXEL_FAST(other_row_ptr, x) - IMAGE_GET_GRAYSCALE_PIXEL_FAST(other_row_ptr,
x)); x));
if (COLOR_THRESHOLD_GRAYSCALE(pixel, &lnk_data, invert)) { if (COLOR_THRESHOLD_GRAYSCALE(pixel, lnk_data, invert)) {
((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++; ((uint32_t *) out->LBins)[fast_roundf((pixel - COLOR_GRAYSCALE_MIN) * mult)]++;
pixel_count++; pixel_count++;
} }
@ -351,15 +346,14 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
// Reset pixel count. // Reset pixel count.
pixel_count = 0; pixel_count = 0;
if (!other) { if (!other) {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) {
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) { for (int x = roi->x, xx = roi->x + roi->w; x < xx; x++) {
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x); int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
if (COLOR_THRESHOLD_RGB565(pixel, &lnk_data, invert)) { if (COLOR_THRESHOLD_RGB565(pixel, lnk_data, invert)) {
((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; ((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++;
((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; ((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++;
((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; ((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++;
@ -369,9 +363,8 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
} }
} }
} else { } else {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y++) {
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y), uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y),
@ -383,7 +376,7 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
int g = abs(COLOR_RGB565_TO_G6(pixel) - COLOR_RGB565_TO_G6(other_pixel)); int g = abs(COLOR_RGB565_TO_G6(pixel) - COLOR_RGB565_TO_G6(other_pixel));
int b = abs(COLOR_RGB565_TO_B5(pixel) - COLOR_RGB565_TO_B5(other_pixel)); int b = abs(COLOR_RGB565_TO_B5(pixel) - COLOR_RGB565_TO_B5(other_pixel));
pixel = COLOR_R5_G6_B5_TO_RGB565(r, g, b); pixel = COLOR_R5_G6_B5_TO_RGB565(r, g, b);
if (COLOR_THRESHOLD_RGB565(pixel, &lnk_data, invert)) { if (COLOR_THRESHOLD_RGB565(pixel, lnk_data, invert)) {
((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++; ((uint32_t *) out->LBins)[fast_roundf((COLOR_RGB565_TO_L(pixel) - COLOR_L_MIN) * l_mult)]++;
((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++; ((uint32_t *) out->ABins)[fast_roundf((COLOR_RGB565_TO_A(pixel) - COLOR_A_MIN) * a_mult)]++;
((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++; ((uint32_t *) out->BBins)[fast_roundf((COLOR_RGB565_TO_B(pixel) - COLOR_B_MIN) * b_mult)]++;
@ -863,16 +856,15 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out,
long long blob_b = 0; long long blob_b = 0;
long long blob_c = 0; long long blob_c = 0;
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
switch (ptr->pixfmt) { switch (ptr->pixfmt) {
case PIXFORMAT_BINARY: { case PIXFORMAT_BINARY: {
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) {
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) {
if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
blob_x1 = IM_MIN(blob_x1, x); blob_x1 = IM_MIN(blob_x1, x);
blob_y1 = IM_MIN(blob_y1, y); blob_y1 = IM_MIN(blob_y1, y);
blob_x2 = IM_MAX(blob_x2, x); blob_x2 = IM_MAX(blob_x2, x);
@ -892,7 +884,7 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out,
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) {
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) {
if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
blob_x1 = IM_MIN(blob_x1, x); blob_x1 = IM_MIN(blob_x1, x);
blob_y1 = IM_MIN(blob_y1, y); blob_y1 = IM_MIN(blob_y1, y);
blob_x2 = IM_MAX(blob_x2, x); blob_x2 = IM_MAX(blob_x2, x);
@ -912,7 +904,7 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out,
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) {
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) {
if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
blob_x1 = IM_MIN(blob_x1, x); blob_x1 = IM_MIN(blob_x1, x);
blob_y1 = IM_MIN(blob_y1, y); blob_y1 = IM_MIN(blob_y1, y);
blob_x2 = IM_MAX(blob_x2, x); blob_x2 = IM_MAX(blob_x2, x);
@ -1022,16 +1014,15 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out,
int blob_y2 = roi->y; int blob_y2 = roi->y;
int blob_pixels = 0; int blob_pixels = 0;
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) { list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t lnk_data; color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
iterator_get(thresholds, it, &lnk_data);
switch (ptr->pixfmt) { switch (ptr->pixfmt) {
case PIXFORMAT_BINARY: { case PIXFORMAT_BINARY: {
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) {
uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y); uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) {
if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
blob_x1 = IM_MIN(blob_x1, x); blob_x1 = IM_MIN(blob_x1, x);
blob_y1 = IM_MIN(blob_y1, y); blob_y1 = IM_MIN(blob_y1, y);
blob_x2 = IM_MAX(blob_x2, x); blob_x2 = IM_MAX(blob_x2, x);
@ -1053,7 +1044,7 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out,
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) {
uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y); uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) {
if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
blob_x1 = IM_MIN(blob_x1, x); blob_x1 = IM_MIN(blob_x1, x);
blob_y1 = IM_MIN(blob_y1, y); blob_y1 = IM_MIN(blob_y1, y);
blob_x2 = IM_MAX(blob_x2, x); blob_x2 = IM_MAX(blob_x2, x);
@ -1075,7 +1066,7 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out,
for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) { for (int y = roi->y, yy = roi->y + roi->h; y < yy; y += y_stride) {
uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y); uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(ptr, y);
for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) { for (int x = roi->x + (y % x_stride), xx = roi->x + roi->w; x < xx; x += x_stride) {
if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), &lnk_data, invert)) { if (COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x), lnk_data, invert)) {
blob_x1 = IM_MIN(blob_x1, x); blob_x1 = IM_MIN(blob_x1, x);
blob_y1 = IM_MIN(blob_y1, y); blob_y1 = IM_MIN(blob_y1, y);
blob_x2 = IM_MAX(blob_x2, x); blob_x2 = IM_MAX(blob_x2, x);