From c61bb864c026d26a393f2a09c82de9bbc5043c6f Mon Sep 17 00:00:00 2001 From: Christian C Date: Tue, 4 Mar 2025 19:10:07 -0800 Subject: Modularization --- src/lib/algo/flood_fill.c | 34 ++++++++++++++++++++++++++++++++ src/lib/color.c | 39 +++++++++++++++++++++++++++++++++++++ src/lib/dir.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib/time.c | 13 +++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 src/lib/algo/flood_fill.c create mode 100644 src/lib/color.c create mode 100644 src/lib/dir.c create mode 100644 src/lib/time.c (limited to 'src/lib') diff --git a/src/lib/algo/flood_fill.c b/src/lib/algo/flood_fill.c new file mode 100644 index 0000000..91f94ad --- /dev/null +++ b/src/lib/algo/flood_fill.c @@ -0,0 +1,34 @@ +#include + +//----------------------------------------------- +// Flood +// Floods a mask from a given set of image to determine the contiguous regions +// 1. Check that the (x,y) is within the picture +// 2. Check if the (x,y) coordinate in the mask is unused +// 3. Check if the (x,y) coordinate in the image is non-background +// 4. Check if the (x,y) coordinate in the image is the same color as the fill color +// 5. If all hold, set the label for the pixel, and check each neighbor +// Otherwise, stop flooding +bool_t flood(uint8_t* image, uint16_t* mask, size_t width, size_t height, size_t channels, size_t x, size_t y, uint8_t* fill_color, uint16_t label) +{ + if ((x >= width) | (y >= height)) { + return FALSE; + } + size_t coord = x + y*width; + if (mask[coord] != 0) { + return FALSE; + } + if (color_zero(&(image[coord*channels]), channels)) { + return FALSE; + } + if (color_equal(&(image[coord*channels]), fill_color, channels)) { + mask[coord] = label; + flood(image, mask, width, height, channels, x, y+1, fill_color, label); + flood(image, mask, width, height, channels, x, y-1, fill_color, label); + flood(image, mask, width, height, channels, x+1, y, fill_color, label); + flood(image, mask, width, height, channels, x-1, y, fill_color, label); + return TRUE; + } + return FALSE; +} + diff --git a/src/lib/color.c b/src/lib/color.c new file mode 100644 index 0000000..035a3e9 --- /dev/null +++ b/src/lib/color.c @@ -0,0 +1,39 @@ +#include +#include +#include + +//----------------------------------------------- +// Color Equal to Background +// Background: zeros in RGB, alpha can be whatever +bool_t color_zero(uint8_t* color1, size_t channels) { + for (size_t idx = 0; idx < channels; idx++) { + if (idx == 3) { + break; + } + if (color1[idx] != 0) { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------- +// Color Equality +// Determine if two colors are identical +bool_t color_equal(uint8_t* color1, uint8_t* color2, size_t channels) { + for (size_t idx = 0; idx < channels; idx++) { + if (color1[idx] != color2[idx]) { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------- +// Print out the `channels` length color vector +void print_color(uint8_t* color, size_t channels) { + for (size_t index = 0; index < channels; index++) { + printf("%hhu ", color[index]); + } + printf("\n"); +} diff --git a/src/lib/dir.c b/src/lib/dir.c new file mode 100644 index 0000000..150d5bf --- /dev/null +++ b/src/lib/dir.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include + +//----------------------------------------------- +// Is directory +bool_t is_directory(char* dirname) { + struct stat st; + if (stat(dirname, &st) == 0) { + if (S_ISDIR(st.st_mode)) { + return TRUE; + } + } + return FALSE; +} + +//----------------------------------------------- +// List directory +char** lsdir(char* dirname) { + DIR *d; + struct dirent *dir; + d = opendir(dirname); + char** file_names = (char**)malloc(sizeof(char*)); + if (!file_names) { + return NULL; + } + file_names[0] = NULL; + size_t file_count = 0; + if (d) { + while ((dir = readdir(d)) != NULL) { + if (dir->d_type == DT_REG) { + // When a regular file is reached + /// Create space for it in the list + file_names = realloc(file_names, (file_count+1+1)*sizeof(char*)); + /// Create space for the name + file_names[file_count] = calloc(strlen(dir->d_name)+1, sizeof(char)); + /// Copy the name + strcpy(file_names[file_count], dir->d_name); + /// Mark the end of the file list with a NULL entry + file_names[++file_count] = NULL; + } + } + return file_names; + } + return NULL; +} + diff --git a/src/lib/time.c b/src/lib/time.c new file mode 100644 index 0000000..2e5777b --- /dev/null +++ b/src/lib/time.c @@ -0,0 +1,13 @@ +#include + +//----------------------------------------------- +// Difference in Time +// Compute the difference between timespec structs +double diff_time(struct timespec *time1, struct timespec *time0) { + return (time1->tv_sec - time0->tv_sec) + + (time1->tv_nsec - time0->tv_nsec) / 1000000000.0; +} + +void get_time(struct timespec *ts) { + timespec_get(ts, TIME_UTC); +} -- cgit v1.2.1