diff --git a/CMakeLists.txt b/CMakeLists.txt index d573ae2..8ff91bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,4 +5,5 @@ set(CMAKE_C_STANDARD 99) add_executable(Juniorcamp main.c) -target_link_libraries(Juniorcamp imago) \ No newline at end of file +target_link_libraries(Juniorcamp imago m) +target_link_directories(Juniorcamp PRIVATE /usr/local/lib/) \ No newline at end of file diff --git a/main.c b/main.c index 94ad514..b58cb22 100644 --- a/main.c +++ b/main.c @@ -1,26 +1,150 @@ #include #include #include +#include +#include #include +#define DEBUG_BUILD 0 + typedef struct { uint32_t width; uint32_t height; - uint8_t* buffer; + uint32_t* buffer; + uint32_t* dist_buffer; } image_T; +uint32_t pixel_distance(uint32_t pixel_a, uint32_t pixel_b) { + uint8_t r_a = (pixel_a) & 0xFF; + uint8_t g_a = (pixel_a >> 8) & 0xFF; + uint8_t b_a = (pixel_a >> 16) & 0xFF; + + uint8_t r_b = (pixel_b) & 0xFF; + uint8_t g_b = (pixel_b >> 8) & 0xFF; + uint8_t b_b = (pixel_b >> 16) & 0xFF; + + uint32_t dist = (uint32_t)sqrt(pow(r_a - r_b, 2) + + pow(g_a - g_b, 2) + + pow(b_a - b_b, 2)); + + #if DEBUG_BUILD + printf(" %x %x %x --> %x %x %x = %d\n", r_a, g_a, b_a, r_b, g_b, b_b, dist); + #endif + + return dist; +} + +image_T* image_load(const char* filename) { + printf("loading '%s'...\n", filename); + + image_T* image = malloc(sizeof(image_T)); + image->buffer = img_load_pixels(filename, (int*)&image->width, (int*)&image->height, IMG_FMT_RGBA32); + image->dist_buffer = calloc(image->width * image->height, sizeof(uint32_t)); +} + +void image_destruct(image_T* image) { + printf("destructing resources\n"); + + img_free_pixels(image->buffer); + free(image->dist_buffer); + free(image); +} + +void image_calculate_dist_buffer(image_T* image) { + memset(image->dist_buffer, 0, image->height * image->width * sizeof(uint32_t)); + + uint32_t* last_row = image->buffer; + uint32_t* pixel_row = &last_row[image->height+1]; + uint32_t* dist_last_row = image->dist_buffer; + uint32_t* dist_pixel_row = &dist_last_row[image->height+1]; + + for (int y = 1; y < image->height; y++) { + #if DEBUG_BUILD + printf(" Y\n"); + #endif + for (int x = 0; x < image->width; x++) { + uint32_t pixel = pixel_row[x]; + + #if DEBUG_BUILD + printf(" X\n"); + #endif + + int32_t shortest_dist = -1; + for (int i = (x > 0 ? -1 : 0); i < (x < image->width-1 ? 2 : 1); i++) { + uint32_t dist = pixel_distance(pixel, last_row[x + i]) + dist_last_row[x + i]; + + if (shortest_dist == -1 || shortest_dist > dist) { + shortest_dist = (int32_t)dist; + } + + #if DEBUG_BUILD + printf(" 0x%x - %d\n", dist, x+i); + #endif + } + #if DEBUG_BUILD + printf(" 0x%x\n", shortest_dist); + #endif + + dist_pixel_row[x] = shortest_dist; + } + + last_row = pixel_row; + pixel_row = &last_row[image->height+1]; + dist_last_row = dist_pixel_row; + dist_pixel_row = &dist_last_row[image->height+1]; + } +} + +void image_dump(image_T* image) { + printf("Pixels:\n"); + for (int y = 0; y < image->height; y++) { + uint32_t* pixel_row = &image->buffer[y * (image->height+1)]; + + printf(" "); + for (int x = 0; x < image->width; x++) { + printf("%x ", pixel_row[x]); + } + + printf("\n"); + } + + printf("Distances:\n"); + for (int y = 0; y < image->height; y++) { + uint32_t* dist_row = &image->dist_buffer[y * (image->height+1)]; + + printf(" "); + for (int x = 0; x < image->width; x++) { + printf("%x ", dist_row[x]); + } + + printf("\n"); + } +} + +uint32_t test_array[12] = { + 0x00000001, 0x00000003, 0x00000005, 0x00000001, + 0x00000001, 0x00000007, 0x00000001, 0x00000002, + 0x0000000A, 0x00000003, 0x00000002, 0x00000005 +}; + int main() { printf("Line Cutter - Juniorcamp Informatik\n"); - const char* filename = "../paris.png"; +// image_T* image = image_load("../paris.png"); - printf("loading '%s'...\n", filename); - image_T image; - image.buffer = img_load_pixels(filename, (int*)&image.width, (int*)&image.height, IMG_FMT_RGBA32); + image_T* image = malloc(sizeof(image_T)); + image->height = 3; + image->width = 4; + image->buffer = test_array; + image->dist_buffer = calloc(image->width * image->height, sizeof(uint32_t)); + + image_calculate_dist_buffer(image); + image_dump(image); - printf("destructing resources\n"); - img_free_pixels(image.buffer); +// image_destruct(image); + free(image->dist_buffer); + free(image); return 0; }