From 47549b6f4b071b91ce3eaf3ffb5cd4aa9a97eddf Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 18 Apr 2012 22:26:37 +0200 Subject: Rename gauss_cv to cvg --- cvg.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 cvg.c (limited to 'cvg.c') diff --git a/cvg.c b/cvg.c new file mode 100644 index 0000000..aaad048 --- /dev/null +++ b/cvg.c @@ -0,0 +1,249 @@ +#include +#include +#include +#include +#include + +struct cvg { + GtkWidget *drawing_area1; + GtkWidget *drawing_area2; + GtkButton *gauss_btn; + GtkButton *open_btn; + IplImage *image; + IplImage *output; + cairo_surface_t *input_surface; + cairo_surface_t *output_surface; +}; + +static cairo_surface_t * +cairo_surface_create_from_ipl_image(IplImage *image) +{ + cairo_surface_t *surface; + guchar *row1, *row2, *p1, *p2; + int x, y; + + surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, + image->width, image->height); + row1 = (guchar *) image->imageData; + row2 = cairo_image_surface_get_data(surface); + for (y = 0; y < image->height; ++y) { + p1 = row1; + p2 = row2; + for (x = 0; x < image->width; ++x) { + memcpy(p2, p1, 3); + + p1 += image->nChannels; + p2 += 4; + } + row1 += image->widthStep; + row2 += cairo_image_surface_get_stride(surface); + } + + return surface; +} + +static inline double +min3(double x1, double x2, double x3) +{ + return MIN(MIN(x1, x2), x3); +} + +static void +scale_centered(cairo_t *cr, double w, double h, double sw, double sh) +{ + double scale = min3(sw / w, sh / h, 1.0); + + cairo_translate(cr, (sw - scale * w) / 2.0, (sh - scale * h) / 2.0); + cairo_scale(cr, scale, scale); +} + +gboolean +draw(GtkWidget *widget, cairo_t *cr, gpointer userdata) +{ + struct cvg *cvg = userdata; + cairo_surface_t *surface; + + if (widget == cvg->drawing_area1) + surface = cvg->input_surface; + else + surface = cvg->output_surface; + + if (surface) { + scale_centered(cr, + cairo_image_surface_get_width(surface), + cairo_image_surface_get_height(surface), + gtk_widget_get_allocated_width(widget), + gtk_widget_get_allocated_height(widget)); + cairo_set_source_surface(cr, surface, 0, 0); + } else { + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0); + } + cairo_paint(cr); + + return FALSE; +} + +static void +destroy_images(struct cvg *cvg) +{ + if (cvg->image) + cvReleaseImage(&cvg->image); + if (cvg->output) + cvReleaseImage(&cvg->output); + + if (cvg->input_surface) + cairo_surface_destroy(cvg->input_surface); + cvg->input_surface = NULL; + if (cvg->output_surface) + cairo_surface_destroy(cvg->output_surface); + cvg->output_surface = NULL; +} + +gboolean +key_event(GtkWidget *widget, GdkEventKey *event, gpointer userdata) +{ + struct cvg *cvg = userdata; + + switch (event->type) { + case GDK_KEY_RELEASE: + switch (event->keyval) { + case GDK_KEY_g: + g_signal_emit_by_name(cvg->gauss_btn, "released", NULL); + g_signal_emit_by_name(cvg->gauss_btn, "clicked", NULL); + break; + case GDK_KEY_o: + g_signal_emit_by_name(cvg->open_btn, "released", NULL); + g_signal_emit_by_name(cvg->open_btn, "clicked", NULL); + break; + } + return FALSE; + case GDK_KEY_PRESS: + switch (event->keyval) { + case GDK_KEY_g: + g_signal_emit_by_name(cvg->gauss_btn, "pressed", NULL); + break; + case GDK_KEY_o: + g_signal_emit_by_name(cvg->open_btn, "pressed", NULL); + break; + case GDK_KEY_d: + destroy_images(cvg); + gtk_widget_queue_draw(cvg->drawing_area1); + gtk_widget_queue_draw(cvg->drawing_area2); + break; + case GDK_KEY_q: + gtk_main_quit(); + break; + } + return FALSE; + default: + return TRUE; + } +} + +static void +open_file(struct cvg *cvg, const gchar *file) +{ + if (cvg->image) + cvReleaseImage(&cvg->image); + if (cvg->input_surface) + cairo_surface_destroy(cvg->input_surface); + + cvg->image = cvLoadImage(file, CV_LOAD_IMAGE_COLOR); + if (!cvg->image) + return; + cvg->input_surface = cairo_surface_create_from_ipl_image(cvg->image); +} + +void +file_set(GtkFileChooserButton *widget, gpointer userdata) +{ + struct cvg *cvg = userdata; + gchar *filename; + + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)); + open_file(cvg, filename); + g_free(filename); + + gtk_widget_queue_draw(cvg->drawing_area1); +} + +void +on_gauss_button_click(GtkButton *button, gpointer userdata) +{ + struct cvg *cvg = userdata; + + if (!cvg->image) + return; + + if (cvg->output) + cvReleaseImage(&cvg->output); + + cvg->output = cvCreateImage(cvGetSize(cvg->image), IPL_DEPTH_8U, 3); + cvSmooth(cvg->image, cvg->output, CV_GAUSSIAN, 9, 9, 0, 0); + + if (cvg->output_surface) + cairo_surface_destroy(cvg->output_surface); + cvg->output_surface = cairo_surface_create_from_ipl_image(cvg->output); + + gtk_widget_queue_draw(cvg->drawing_area2); +} + +void +destroy(GtkWidget *widget, gpointer userdata) +{ + gtk_main_quit(); +} + +static void +find_button(GtkWidget *widget, gpointer data) +{ + GtkButton **p = data; + + if (GTK_IS_BUTTON(widget)) + *p = GTK_BUTTON(widget); +} + +int +main(int argc, char *argv[]) +{ + struct cvg cvg; + GtkBuilder *builder; + GObject *file_chooser; + gchar *path, *file; + + memset(&cvg, 0, sizeof cvg); + gtk_init(&argc, &argv); + + if (argc >= 2) + open_file(&cvg, argv[argc-1]); + + builder = gtk_builder_new(); + path = g_path_get_dirname(argv[0]); + file = g_build_filename(path, "cvg.ui", NULL); + gtk_builder_add_from_file(builder, file, NULL); + g_free(path); + g_free(file); + gtk_builder_connect_signals(builder, &cvg); + + cvg.drawing_area1 = GTK_WIDGET(gtk_builder_get_object(builder, + "drawingarea1")); + cvg.drawing_area2 = GTK_WIDGET(gtk_builder_get_object(builder, + "drawingarea2")); + cvg.gauss_btn = GTK_BUTTON(gtk_builder_get_object(builder, "gauss")); + file_chooser = gtk_builder_get_object(builder, "file-chooser"); + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser), + g_get_current_dir()); + /* There is no way to retreive the GtkButton from GtkFileChooserButton, + * Try to find a GtkButton in the inherited GtkContainer. + */ + gtk_container_forall(GTK_CONTAINER(file_chooser), + find_button, &cvg.open_btn); + + gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "win"))); + g_object_unref(builder); + gtk_main(); + + destroy_images(&cvg); + + return 0; +} -- cgit