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.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)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
switch (img->pixfmt) {
case PIXFORMAT_BINARY: {
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 *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
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);
}
}
@ -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);
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
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);
}
}
@ -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);
uint32_t *bmp_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&bmp, y);
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);
}
}

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));
size_t code = 0;
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
switch (ptr->pixfmt) {
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);
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))
&& 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_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)
&& (!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)) {
left--;
}
while ((right < (roi->x + roi->w - 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)) {
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))
&& (ok =
COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, i),
&lnk_data,
lnk_data,
invert))) {
xylr_t context;
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))
&& (ok =
COLOR_THRESHOLD_BINARY(IMAGE_GET_BINARY_PIXEL_FAST(row, i),
&lnk_data,
lnk_data,
invert))) {
xylr_t context;
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);
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))
&& 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_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)
&& (!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)) {
left--;
}
while ((right < (roi->x + roi->w - 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)) {
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))
&& (ok =
COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, i),
&lnk_data,
lnk_data,
invert))) {
xylr_t context;
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))
&& (ok =
COLOR_THRESHOLD_GRAYSCALE(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row, i),
&lnk_data,
lnk_data,
invert))) {
xylr_t context;
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);
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))
&& 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_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)
&& (!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)) {
left--;
}
while ((right < (roi->x + roi->w - 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)) {
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))
&& (ok =
COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, i),
&lnk_data,
lnk_data,
invert))) {
xylr_t context;
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))
&& (ok =
COLOR_THRESHOLD_RGB565(IMAGE_GET_RGB565_PIXEL_FAST(row, i),
&lnk_data,
lnk_data,
invert))) {
xylr_t context;
context.x = x;

View File

@ -1,8 +1,8 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@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.
*
@ -13,10 +13,7 @@
#define CHAR_MASK (CHAR_BITS - 1)
#define CHAR_SHIFT IM_LOG2(CHAR_MASK)
////////////
// bitmap //
////////////
// Bitmap
void bitmap_alloc(bitmap_t *ptr, size_t size) {
ptr->size = size;
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;
}
//////////
// lifo //
//////////
// LIFO
void lifo_alloc(lifo_t *ptr, size_t size, size_t data_len) {
ptr->len = 0;
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);
}
//////////
// fifo //
//////////
// FIFO
void fifo_alloc(fifo_t *ptr, size_t size, size_t data_len) {
ptr->head_ptr = 0;
ptr->tail_ptr = 0;
ptr->head = 0;
ptr->tail = 0;
ptr->len = 0;
ptr->size = size;
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->size = tmp_size / data_len;
ptr->len = 0;
ptr->tail_ptr = 0;
ptr->head_ptr = 0;
ptr->tail = 0;
ptr->head = 0;
*size = ptr->size;
}
@ -135,8 +126,8 @@ void fifo_free(fifo_t *ptr) {
}
void fifo_clear(fifo_t *ptr) {
ptr->head_ptr = 0;
ptr->tail_ptr = 0;
ptr->head = 0;
ptr->tail = 0;
ptr->len = 0;
}
@ -153,48 +144,45 @@ bool fifo_is_not_full(fifo_t *ptr) {
}
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) {
temp = 0;
}
ptr->head_ptr = temp;
ptr->head = temp;
ptr->len += 1;
}
void fifo_dequeue(fifo_t *ptr, void *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) {
temp = 0;
}
ptr->tail_ptr = temp;
ptr->tail = temp;
ptr->len -= 1;
}
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) {
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);
}
//////////
// list //
//////////
// Linked List
void list_init(list_t *ptr, size_t data_len) {
ptr->head_ptr = NULL;
ptr->tail_ptr = NULL;
ptr->head = NULL;
ptr->tail = NULL;
ptr->size = 0;
ptr->data_len = data_len;
}
@ -204,8 +192,8 @@ void list_copy(list_t *dst, list_t *src) {
}
void list_free(list_t *ptr) {
for (list_lnk_t *i = ptr->head_ptr; i; ) {
list_lnk_t *j = i->next_ptr;
for (list_lnk_t *i = ptr->head; i; ) {
list_lnk_t *j = i->next;
xfree(i);
i = j;
}
@ -214,8 +202,8 @@ void list_free(list_t *ptr) {
void list_clear(list_t *ptr) {
list_free(ptr);
ptr->head_ptr = NULL;
ptr->tail_ptr = NULL;
ptr->head = NULL;
ptr->tail = NULL;
ptr->size = 0;
}
@ -228,15 +216,15 @@ void list_push_front(list_t *ptr, void *data) {
memcpy(tmp->data, data, ptr->data_len);
if (ptr->size++) {
tmp->next_ptr = ptr->head_ptr;
tmp->prev_ptr = NULL;
ptr->head_ptr->prev_ptr = tmp;
ptr->head_ptr = tmp;
tmp->next = ptr->head;
tmp->prev = NULL;
ptr->head->prev = tmp;
ptr->head = tmp;
} else {
tmp->next_ptr = NULL;
tmp->prev_ptr = NULL;
ptr->head_ptr = tmp;
ptr->tail_ptr = tmp;
tmp->next = NULL;
tmp->prev = NULL;
ptr->head = tmp;
ptr->tail = tmp;
}
}
@ -245,234 +233,84 @@ void list_push_back(list_t *ptr, void *data) {
memcpy(tmp->data, data, ptr->data_len);
if (ptr->size++) {
tmp->next_ptr = NULL;
tmp->prev_ptr = ptr->tail_ptr;
ptr->tail_ptr->next_ptr = tmp;
ptr->tail_ptr = tmp;
tmp->next = NULL;
tmp->prev = ptr->tail;
ptr->tail->next = tmp;
ptr->tail = tmp;
} else {
tmp->next_ptr = NULL;
tmp->prev_ptr = NULL;
ptr->head_ptr = tmp;
ptr->tail_ptr = tmp;
tmp->next = NULL;
tmp->prev = NULL;
ptr->head = tmp;
ptr->tail = tmp;
}
}
void list_pop_front(list_t *ptr, void *data) {
list_lnk_t *tmp = ptr->head_ptr;
list_lnk_t *tmp = ptr->head;
if (data) {
memcpy(data, tmp->data, ptr->data_len);
}
if (tmp->next_ptr) {
tmp->next_ptr->prev_ptr = NULL;
if (tmp->next) {
tmp->next->prev = NULL;
}
ptr->head_ptr = tmp->next_ptr;
ptr->head = tmp->next;
ptr->size -= 1;
xfree(tmp);
}
void list_pop_back(list_t *ptr, void *data) {
list_lnk_t *tmp = ptr->tail_ptr;
list_lnk_t *tmp = ptr->tail;
if (data) {
memcpy(data, tmp->data, ptr->data_len);
}
tmp->prev_ptr->next_ptr = NULL;
ptr->tail_ptr = tmp->prev_ptr;
tmp->prev->next = NULL;
ptr->tail = tmp->prev;
ptr->size -= 1;
xfree(tmp);
}
void list_get_front(list_t *ptr, 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) {
void list_get(list_t *ptr, list_lnk_t *lnk, void *data) {
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);
}
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.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@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.
*
@ -13,15 +13,11 @@
#include <stdbool.h>
#include <stddef.h>
////////////
// bitmap //
////////////
// Bitmap
typedef struct bitmap {
size_t size;
char *data;
}
bitmap_t;
} bitmap_t;
void bitmap_alloc(bitmap_t *ptr, size_t size);
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_INDEX(row_index, x) ((row_index) + (x))
//////////
// lifo //
//////////
// LIFO
typedef struct lifo {
size_t len, size, data_len;
size_t len;
size_t size;
size_t data_len;
char *data;
}
lifo_t;
} 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);
@ -53,15 +47,15 @@ void lifo_dequeue(lifo_t *ptr, void *data);
void lifo_poke(lifo_t *ptr, void *data);
void lifo_peek(lifo_t *ptr, void *data);
//////////
// fifo //
//////////
// 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;
}
fifo_t;
} fifo_t;
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);
@ -75,21 +69,19 @@ void fifo_dequeue(fifo_t *ptr, void *data);
void fifo_poke(fifo_t *ptr, void *data);
void fifo_peek(fifo_t *ptr, void *data);
//////////
// list //
//////////
// Linked List
typedef struct list_lnk {
struct list_lnk *next_ptr, *prev_ptr;
struct list_lnk *next;
struct list_lnk *prev;
char data[];
}
list_lnk_t;
} list_lnk_t;
typedef struct list {
list_lnk_t *head_ptr, *tail_ptr;
size_t size, data_len;
}
list_t;
list_lnk_t *head;
list_lnk_t *tail;
size_t size;
size_t data_len;
} list_t;
void list_init(list_t *ptr, size_t data_len);
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_pop_front(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_get_back(list_t *ptr, void *data);
void list_set_front(list_t *ptr, void *data);
void list_set_back(list_t *ptr, void *data);
void list_insert(list_t *ptr, void *data, size_t index);
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);
void list_insert(list_t *ptr, list_lnk_t *lnk, void *data);
void list_remove(list_t *ptr, list_lnk_t *lnk, void *data);
#define list_for_each(iterator, list) \
for (list_lnk_t *iterator = list->head; iterator != NULL; iterator = iterator->next)
#define list_get_data(iterator) ((void *) iterator->data)
#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.
pixel_count = 0;
if (!other) {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
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);
for (int x = roi->x, xx = roi->x + roi->w; x < xx; 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)]++;
pixel_count++;
}
@ -202,9 +200,8 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
}
}
} else {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
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),
@ -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++) {
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) ^ IMAGE_GET_BINARY_PIXEL_FAST(other_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)]++;
pixel_count++;
}
@ -262,15 +259,14 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
// Reset pixel count.
pixel_count = 0;
if (!other) {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
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);
for (int x = roi->x, xx = roi->x + roi->w; x < xx; 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)]++;
pixel_count++;
}
@ -278,9 +274,8 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
}
}
} else {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
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),
@ -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,
x) - IMAGE_GET_GRAYSCALE_PIXEL_FAST(other_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)]++;
pixel_count++;
}
@ -351,15 +346,14 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
// Reset pixel count.
pixel_count = 0;
if (!other) {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
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);
for (int x = roi->x, xx = roi->x + roi->w; x < xx; 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->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)]++;
@ -369,9 +363,8 @@ void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_
}
}
} else {
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
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),
@ -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 b = abs(COLOR_RGB565_TO_B5(pixel) - COLOR_RGB565_TO_B5(other_pixel));
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->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)]++;
@ -863,16 +856,15 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out,
long long blob_b = 0;
long long blob_c = 0;
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
switch (ptr->pixfmt) {
case PIXFORMAT_BINARY: {
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);
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_y1 = IM_MIN(blob_y1, y);
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) {
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) {
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_y1 = IM_MIN(blob_y1, y);
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) {
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) {
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_y1 = IM_MIN(blob_y1, y);
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_pixels = 0;
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
list_for_each(it, thresholds) {
color_thresholds_list_lnk_data_t *lnk_data = list_get_data(it);
switch (ptr->pixfmt) {
case PIXFORMAT_BINARY: {
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);
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_y1 = IM_MIN(blob_y1, y);
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) {
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) {
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_y1 = IM_MIN(blob_y1, y);
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) {
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) {
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_y1 = IM_MIN(blob_y1, y);
blob_x2 = IM_MAX(blob_x2, x);