#include #include #include #include #include #include #define DEBUG_BUILD 0 typedef struct { uint32_t width; uint32_t height; 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"); // image_T* image = image_load("../paris.png"); 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); // image_destruct(image); free(image->dist_buffer); free(image); return 0; }