#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); }