diff --git a/bench_mask.png b/bench_mask.png new file mode 100644 index 0000000..42cb0fc Binary files /dev/null and b/bench_mask.png differ diff --git a/main.c b/main.c index 7ac8f91..f25aa07 100644 --- a/main.c +++ b/main.c @@ -7,17 +7,20 @@ #include #include "gfx.h" -#define DEBUG_BUILD 0 - #define MASK_MULTIPLIER 50 +typedef struct { + int32_t distance; + int8_t direction; +} distance_T; + typedef struct { uint32_t width; uint32_t height; uint32_t new_width; uint32_t new_height; uint32_t* buffer; - int32_t* dist_buffer; + distance_T* dist_buffer; uint32_t* mask_buffer; } image_T; @@ -48,7 +51,7 @@ image_T* image_load(const char* filename, const char* filename_mask) { image_T* image = malloc(sizeof(image_T)); image->mask_buffer = img_load_pixels(filename_mask, (int*)&image->width, (int*)&image->height, IMG_FMT_RGBA32); 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)); + image->dist_buffer = calloc(image->width * image->height, sizeof(distance_T)); image->new_width = image->width; image->new_height = image->height; } @@ -63,24 +66,24 @@ void image_destruct(image_T* image) { } void image_calculate_dist_buffer(image_T* image) { - memset(image->dist_buffer, 0, image->height * image->width * sizeof(int32_t)); + memset(image->dist_buffer, 0, image->width * sizeof(distance_T)); - uint32_t* last_row = image->buffer; - uint32_t* pixel_row = &last_row[image->width]; - int32_t* dist_last_row = image->dist_buffer; - int32_t* dist_pixel_row = &dist_last_row[image->width]; + uint32_t* last_row = image->buffer; + uint32_t* pixel_row = &last_row[image->width]; + distance_T* dist_last_row = image->dist_buffer; + distance_T* dist_pixel_row = &dist_last_row[image->width]; for (int y = 1; y < image->new_height; y++) { for (int x = 0; x < image->new_width; x++) { uint32_t pixel = pixel_row[x]; - int32_t shortest_dist; - bool found_dist = false; + distance_T shortest_dist; + bool found_dist = false; for (int i = (x > 0 ? -1 : 0); i < (x < image->new_width-1 ? 2 : 1); i++) { - int32_t dist = pixel_distance(pixel, last_row[x + i], image->mask_buffer[(y * image->width) + x + i]) + dist_last_row[x + i]; + int32_t dist = pixel_distance(pixel, last_row[x + i], image->mask_buffer[(y * image->width) + x + i]) + dist_last_row[x + i].distance; - if (!found_dist || shortest_dist > dist) { - shortest_dist = dist; + if (!found_dist || shortest_dist.distance > dist) { + shortest_dist = (distance_T){dist, (int8_t)i}; found_dist = true; } } @@ -96,13 +99,13 @@ void image_calculate_dist_buffer(image_T* image) { } uint32_t image_find_best_line(image_T* image) { - int32_t* row = &image->dist_buffer[(image->new_height-1) * image->width]; - uint32_t line_id = 0; - int32_t shortest_dist; - bool found_dist = false; + distance_T* row = &image->dist_buffer[(image->new_height-1) * image->width]; + uint32_t line_id = 0; + distance_T shortest_dist; + bool found_dist = false; for (uint32_t x = 0; x < image->new_width; x++) { - if (!found_dist || shortest_dist > row[x]) { + if (!found_dist || shortest_dist.distance > row[x].distance) { shortest_dist = row[x]; line_id = x; found_dist = true; @@ -116,19 +119,8 @@ void image_cut_line(image_T* image, uint32_t line_id) { uint32_t x = line_id; for (uint32_t y = image->height-1; y > 0; y--) { - int32_t shortest_dist; - int8_t offset; - bool found_dist = false; - for (int i = (x > 0 ? -1 : 0); i < (x < image->new_width-1 ? 2 : 1); i++) { - int32_t dist = image->dist_buffer[(image->width * y) + x + i]; - - if (!found_dist || shortest_dist > dist) { - shortest_dist = dist; - offset = (int8_t)i; - found_dist = true; - } - } - x += offset; + distance_T dist = image->dist_buffer[(image->width * y) + x]; + x += dist.direction; memcpy(&image->buffer[(image->width * y) + x], &image->buffer[(image->width * y) + x + 1], (image->new_width - x) * sizeof(uint32_t)); memcpy(&image->mask_buffer[(image->width * y) + x], &image->mask_buffer[(image->width * y) + x + 1], (image->new_width - x) * sizeof(uint32_t)); gfx_color(0, 0xFF, 0); @@ -140,55 +132,31 @@ void image_cut_line(image_T* image, uint32_t line_id) { } void image_dump(image_T* image) { - #if DEBUG_BUILD - printf("Pixels:\n"); - #endif for (int y = 0; y < image->new_height; y++) { - uint32_t* pixel_row = &image->buffer[y * image->width]; + uint32_t *pixel_row = &image->buffer[y * image->width]; - #if DEBUG_BUILD - printf(" "); - #endif for (int x = 0; x < image->new_width; x++) { - #if DEBUG_BUILD - printf("%x ", pixel_row[x]); - #endif - gfx_color((uint8_t)(pixel_row[x] & 0xFF), - (uint8_t)((pixel_row[x] >> 8) & 0xFF), - (uint8_t)((pixel_row[x] >> 16) & 0xFF)); + gfx_color((uint8_t) (pixel_row[x] & 0xFF), + (uint8_t) ((pixel_row[x] >> 8) & 0xFF), + (uint8_t) ((pixel_row[x] >> 16) & 0xFF)); gfx_point(x, y); } - - #if DEBUG_BUILD - printf("\n"); - #endif } gfx_color(0, 0, 0); - for (int y = 0; y < image->new_height*2; y++) { + for (int y = 0; y < image->new_height; y++) { gfx_point(image->new_width, y); } gfx_flush(); -#if DEBUG_BUILD - printf("Distances:\n"); - for (int y = 0; y < image->height; y++) { - uint32_t* dist_row = &image->dist_buffer[y * image->width]; - - printf(" "); - for (int x = 0; x < image->width; x++) { - printf("%x ", dist_row[x]); - } - printf("\n"); - } -#endif } -int main() { + +int main(int argc, char* argv[]) { printf("Line Cutter - Juniorcamp Informatik\n"); - image_T* image = image_load("../paris.png", "../paris_mask.png"); + image_T* image = image_load("../bench.png", "../bench_mask.png"); gfx_open(800, 600, "Juniorcamp Informatik - Line Cutter"); image_dump(image); diff --git a/paris_mask.png b/paris_mask.png index 9734aee..2970eff 100644 Binary files a/paris_mask.png and b/paris_mask.png differ