From 701fccdf65e3a1fe2f7a8f9639ba1b8c33ffe7dc Mon Sep 17 00:00:00 2001 From: antifallobst Date: Tue, 21 Mar 2023 11:00:17 +0100 Subject: [PATCH] the algorithm now saves the best direction for every node, while generating the distances array --- bench_mask.png | Bin 0 -> 5441 bytes main.c | 96 +++++++++++++++++-------------------------------- paris_mask.png | Bin 7255 -> 7742 bytes 3 files changed, 32 insertions(+), 64 deletions(-) create mode 100644 bench_mask.png diff --git a/bench_mask.png b/bench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..42cb0fc22d12755002f0d2638fb6c72cf0a86f59 GIT binary patch literal 5441 zcmeHLc~BE+7H?n_fk6e)aaAM}j}b9RcMc%g1i=I$Vh|yM)01+L9 z89Y%J@WNwMlo{{WYG zsCYd=BTS?cf=ms+ZP66np8DzP&ZFtf@{PltYyVz(k+O|UT6`-wVdJKs8ynv{e(U5k z-#G#L;Kbgf}`u*pRZ(YIgxm*xMJ&Tzn#YxMy_@V z#*_XB+8*vzEoe;-|3^gT4w5*%|9sfS+Q`$_zPR$eRcZUkE~K^B$(kw?@q^o-|%`v9iKY@;a^Vg3{zNx%t4z>xKEYCn_4x-I!}TPqBXf zW-@e-fBWaQj%nNC=cu2+!+ag~Wkf&xyqp!VuX^&l{oW;+Bg$GtqXdmNG2$J>M~+7;jrKwsWz;z3!Cs*`JFet|=2&pYv-LuG(--rhf;YUXJNr z6t+*kdUtSBmYcZe(|M_`V!Lbd>13NMrNc;u)twcf5YkAoI7BKI_vAjv_}s5Ihyp8p z$5k&5s~&b}X!!8x^C8=t^XQq!?fnl7U$!dTbvCmjb+V&0J!8+k1^O1O@aet#hx1qF z(}pCal$`W-KN+~TGsvEy5PCnWDOyoSf8T26Z{5Xk|$))8F1X zlC?9tb>ocaU9YO6ea@v6MDChv%zcj4khxH~>fS6}n@7x&*PB`w1Z9k~vblY>IwmOW zbxN)4lD9vtm)*)r<*rH`Z<@YGcfopPvG4Qj`mc;`-w*T6J~^uivi;_)X+=@}*G+fs zG~GU<%I@fZQXUx&@1AJ?4d_uO67-_^ve^Pmr(vSFPC+nD8a?P$5G0&#(xX@uLD3Y1 ziqwke&&$rxX(TS9NAP5@OfM#ul7R^ZA}k?TjwM84e4IYr$6ja>000d^p)`|5tu+cv zBDw`v0LJEJ7M*4hp`t|e`LYn2SZ5$;Tqc(ZGyF|tESv6QPZJt&r65!?vl{};MD(Q; zr5CVRadC0XI1W>1P_Ym`pU;BXEH;|~BpAkcErpsGTH^#WL>GpHFk%K$Pmww;&5VgE zbTO2OP6zw69{)6YnXDIHYwTtL@WC>ndKSWjSsD$iuZEHGj|Cvz4*jl%Q4U%(9t^%__;h12i&Y(fTagrKTMX>Z*m1V7vxm7o*>K!HgC%n`5=IRXn1F9FQ=fDr-Q zM_z}M%J}~#Z7v>~uib$j!aYz9VnaR~xO0ma_^(TzGK z6^9xKKNa8+a0SxS!WC_b<)GaAOUErG%%=bdW566nFJTDMO&F^?V3xUO^h7LV{RbyP zi$I?y1N6GqK=T5sDK8rul0)QSc@=^Q_&^18UM=|hG!UNegK-Whx z@KM48+4Vo8%l^Z4iqL|8L2=-+G{}Rk0~f8qil6|A<;n%MiOZ6~$W9;lr4fQ0Mwq`= zP5UIxUs>$-yh5a&WbVpvqlsVR!F+GSA998F&U5 d`2S`=Xj9k>S*_i%bHCY7seiDfV8)Wve*+~c{x$#r literal 0 HcmV?d00001 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 9734aee32be7035fd44b2021b62b7d9b66171006..2970effdc1888795f306c5805089aa753c45c9cf 100644 GIT binary patch delta 3573 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 delta 3299 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 h9W|032^fI8d;)