From 7f9b9b0ec979c9f35c1b922412c7b2731a3a6c66 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 14 Mar 2012 18:34:03 +0100 Subject: Add initial wimmel program --- wimmel.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 wimmel.c (limited to 'wimmel.c') diff --git a/wimmel.c b/wimmel.c new file mode 100644 index 0000000..712dacb --- /dev/null +++ b/wimmel.c @@ -0,0 +1,158 @@ +#include +#include +#include + +#include "util.h" + +static void +find_image_in_wimmel(GdkPixbuf *wimmel, GdkPixbuf *match, GdkPixbuf *output) +{ + int wimmel_width, wimmel_height; + int width, height; + int i, j, k, n; + int difference, barrier; + + wimmel_width = gdk_pixbuf_get_width(wimmel); + wimmel_height = gdk_pixbuf_get_height(wimmel); + width = gdk_pixbuf_get_width(match); + height = gdk_pixbuf_get_height(match); + + barrier = width * height / 2; + + for (j = 0; j < wimmel_height - height; ++j) { + for (i = 0; i < wimmel_width - width; ++i) { + + difference = 0; + for (n = 0; n < height; ++n) { + for (k = 0; k < width; ++k) { + color_t color = get_pixel(wimmel, POINT(i + k, j + n)); + color_t color_orig = get_pixel(match, POINT(k, n)); + +#if 1 + if (abs(color.r - color_orig.r) > 50 || + abs(color.g - color_orig.g) > 50 || + abs(color.b - color_orig.b) > 50) { + difference++; + if (difference > barrier) + break; + } +#else + difference += + abs(color.r - color_orig.r) + + abs(color.g - color_orig.g) + + abs(color.b - color_orig.b); + if (difference > barrier * 300) + break; +#endif + } + } + +#if 0 + if (difference < barrier * 300) { +#else + if (difference < barrier) { +#endif + g_print("kleeblatt @ %d, %d; difference: %d\n", i, j, difference); + color_t color = COLOR(255, 0, 0, 0); + for (k = i; k < i+width; k++) { + put_pixel(output, POINT(k, j), color); + put_pixel(output, POINT(k, j+height), color); + } + for (n = j; n < j+height; n++) { + put_pixel(output, POINT(i, n), color); + put_pixel(output, POINT(i+width, n), color); + } + } + } + } +} +struct find_params { + GdkPixbuf *wimmel; + GdkPixbuf *match; + GdkPixbuf *output; +}; + +static gpointer +find_thread(gpointer data) +{ + struct find_params *params = data; + + find_image_in_wimmel(params->wimmel, params->match, params->output); + g_object_unref(params->wimmel); + g_object_unref(params->match); + g_object_unref(params->output); + + free(params); + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + char *file; + GdkPixbuf *wimmel, *output; + GdkPixbuf *match_tmp, *match; + int i, j; + int x1, y1, mwidth, mheight, width, height; +#define N 4 +#define K 4 + GThread *thread[N][K]; + + g_type_init(); + + if (argc < 5) + exit(EXIT_FAILURE); + + file = argv[1]; + x1 = atoi(argv[2]); + y1 = atoi(argv[3]); + mwidth = atoi(argv[4]); + mheight = atoi(argv[5]); + + wimmel = gdk_pixbuf_new_from_file(file, NULL); + if (!wimmel) + exit(EXIT_FAILURE); + + output = gdk_pixbuf_copy(wimmel); + + match_tmp = gdk_pixbuf_new_subpixbuf(wimmel, x1, y1, mwidth, mheight); + match = gdk_pixbuf_copy(match_tmp); + g_object_unref(match_tmp); + + width = gdk_pixbuf_get_width(wimmel); + height = gdk_pixbuf_get_height(wimmel); + + int step_x = width / N, step_y = height / K; + int x, y; + for (i = 0, x = 0; i < N; ++i, x += step_x) { + for (j = 0, y = 0; j < K; ++j, y += step_y) { + struct find_params *params = malloc(sizeof (struct find_params));; + if (!params) + exit(EXIT_FAILURE); + + int w = step_x + mwidth; + int h = step_y + mheight; + + if (x + w > width) + w = width - x; + if (y + h > height) + h = height - y; + + params->wimmel = gdk_pixbuf_new_subpixbuf(wimmel, x, y, w, h); + params->output = gdk_pixbuf_new_subpixbuf(output, x, y, w, h); + params->match = g_object_ref(match); + + thread[i][j] = g_thread_create(find_thread, params, TRUE, NULL); + } + } + + for (i = 0; i < N; ++i) + for (j = 0; j < K; ++j) + g_thread_join(thread[i][j]); + + gdk_pixbuf_save(output, "output.png", "png", NULL, NULL); + g_object_unref(wimmel); + g_object_unref(output); + g_object_unref(match); +} -- cgit