#include #include #include /* no strcmp equivalent in glib ? */ #include "filter_tabs.h" #include "tabs.h" #include "colors.h" GtkWidget * create_filter_tree_view( GtkWidget *tab_group ) { GtkWidget *tree_view; GtkTreeSelection *filter_selection; GtkCellRenderer *cell; GtkTreeViewColumn *column1, *column2, *column3, *column4, *column5; tree_view = gtk_tree_view_new (); filter_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); gtk_tree_selection_set_mode (filter_selection, GTK_SELECTION_SINGLE); cell = gtk_cell_renderer_text_new (); /* add columns to the tree view */ column1 = gtk_tree_view_column_new_with_attributes ("Espace", cell, "text", COLORSPACE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column1)); column2 = gtk_tree_view_column_new_with_attributes ("Composante", cell, "text", COMPOSANT_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column2)); column3 = gtk_tree_view_column_new_with_attributes ("Min", cell, "text", MIN_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column3)); column4 = gtk_tree_view_column_new_with_attributes ("Max", cell, "text", MAX_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column4)); column5 = gtk_tree_view_column_new_with_attributes ("Invert", cell, "text", INVERT_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column5)); /* add pointer to the tree_view in the tab_group */ g_object_set_data(G_OBJECT (tab_group), "tree_view", tree_view); g_object_set_data(G_OBJECT (tab_group), "filter_selection", filter_selection); return tree_view; } GtkWidget * add_filter_tab( GtkWidget *tab_group ) { GtkWidget *tab; GtkListStore *filter_list; GtkWidget *tree_view; guint num, value, color_r, color_g, color_b; tab = add_tab(TAB_TEMP_NAME, tab_group); num = get_number_of_tabs(tab_group); value = DEFAULT_VALUE_NOT_FILTERED; color_r = DEFAULT_RED_NOT_FILTERED; color_g = DEFAULT_BLUE_NOT_FILTERED; color_b = DEFAULT_GREEN_NOT_FILTERED; tree_view = g_object_get_data(G_OBJECT (tab_group), "tree_view"); filter_list = gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UCHAR, G_TYPE_UCHAR, G_TYPE_BOOLEAN); /* add pointer to the filter_list in the new tab */ g_object_set_data(G_OBJECT (tab), "filter_list", filter_list); /* tab number, default value and color */ g_object_set_data(G_OBJECT (tab), "number", (gpointer) num); g_object_set_data(G_OBJECT (tab), "eprom_value", (gpointer) value); g_object_set_data(G_OBJECT (tab), "color_r", (gpointer) color_r); g_object_set_data(G_OBJECT (tab), "color_g", (gpointer) color_g); g_object_set_data(G_OBJECT (tab), "color_b", (gpointer) color_b); update_filter_tab_name(tab); select_tab(tab, NULL); set_list_in_tree_view(tab, tree_view); g_signal_connect (G_OBJECT (tab), "clicked", G_CALLBACK (set_list_in_tree_view), tree_view); return tab; } void set_list_in_tree_view( GtkWidget *tab, gpointer data ) { GtkListStore *filter_list; GtkWidget *tree_view; tree_view = (GtkWidget *) (data); filter_list = g_object_get_data(G_OBJECT (tab), "filter_list"); gtk_tree_view_set_model(GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (filter_list)); } void update_filter_tab_name( GtkWidget *tab ) { gchar *name; guchar num, value, color_r, color_g, color_b; num = (guint) g_object_get_data(G_OBJECT (tab), "number"); value = (guint) g_object_get_data(G_OBJECT (tab), "eprom_value"); /* convert 16 bit colors to 8 bit colors */ color_r = (guint) g_object_get_data(G_OBJECT (tab), "color_r") >> 8; color_g = (guint) g_object_get_data(G_OBJECT (tab), "color_g") >> 8; color_b = (guint) g_object_get_data(G_OBJECT (tab), "color_b") >> 8; name = malloc((TAB_NAME_MAX_LENGTH + 1)*sizeof(gchar)); if (tab == NULL) { fprintf(stderr, "Impossible d'allouer de la mémoire pour le nom de l'onglet.\n"); exit(EXIT_FAILURE); } g_snprintf(name, TAB_NAME_MAX_LENGTH + 1, TAB_NAME, num, value, color_r, color_g, color_b); gtk_button_set_label(GTK_BUTTON (tab), name); free(name); } GtkListStore * get_selected_filter_list( GtkWidget *tab_group ) { GtkWidget * tab; tab = g_object_get_data(G_OBJECT (tab_group), "selected_tab"); return (tab ? g_object_get_data(G_OBJECT (tab), "filter_list") : NULL); } void get_value_and_color_of_pixel( GtkWidget *tab_group, guchar *r, guchar *g, guchar *b, guchar *eprom_value, guchar *color_r, guchar *color_g, guchar *color_b) { GList *tabs; guchar h, s, l, x, y, z, l_star, u_star, v_star, a_star, b_star; guchar value; guchar col_r, col_g, col_b; /* default value when not filtered */ value = DEFAULT_VALUE_NOT_FILTERED; /* convert 16 bit colors to 8 bit colors */ col_r = DEFAULT_RED_NOT_FILTERED >> 8; col_g = DEFAULT_GREEN_NOT_FILTERED >> 8; col_b = DEFAULT_BLUE_NOT_FILTERED >> 8; /* get the decomposition of the RGB pixel in multiple color spaces */ point_rgb2hslxyzluvab( r, g, b, &h, &s, &l, &x, &y, &z, &l_star, &u_star, &v_star, &a_star, &b_star); tabs = GTK_BOX (tab_group)->children; /* for each filter */ while (tabs) { GtkListStore * filter_list; GtkTreeIter iter; GtkBoxChild *child; GtkWidget *tab; gboolean valid; gboolean point_matchs_filter; child = tabs->data; tab = child->widget; filter_list = g_object_get_data(G_OBJECT (tab), "filter_list"); /* Get the first iter in the list */ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filter_list), &iter); /* if there is no condition for this filter, skip it */ if (!valid) { /* next filter */ tabs = tabs->next; continue; } point_matchs_filter = TRUE; while (valid && point_matchs_filter) { gboolean point_matchs_condition; char *colorspace, *composant; guchar min, max; gboolean invert; guchar comp = 0; gtk_tree_model_get (GTK_TREE_MODEL (filter_list), &iter, COLORSPACE_COLUMN, &colorspace, COMPOSANT_COLUMN, &composant, MIN_COLUMN, &min, MAX_COLUMN, &max, INVERT_COLUMN, &invert, -1); if (strcmp (composant, "R") == 0) comp = *r; else if (strcmp (composant, "G") == 0) comp = *g; else if (strcmp (composant, "B") == 0) comp = *b; else if (strcmp (composant, "H") == 0) comp = h; else if (strcmp (composant, "S") == 0) comp = s; else if (strcmp (composant, "L") == 0) comp = l; else if (strcmp (composant, "X") == 0) comp = x; else if (strcmp (composant, "Y") == 0) comp = y; else if (strcmp (composant, "Z") == 0) comp = z; else if (strcmp (composant, "L*") == 0) comp = l_star; else if (strcmp (composant, "U") == 0) comp = u_star; else if (strcmp (composant, "V") == 0) comp = v_star; else if (strcmp (composant, "A") == 0) comp = a_star; else if (strcmp (composant, "B") == 0) comp = b_star; g_free (colorspace); g_free (composant); /* good if : min <= comp <= max */ point_matchs_condition = (comp >= min) && (comp <= max); if (invert) point_matchs_condition = !point_matchs_condition; point_matchs_filter = point_matchs_filter && point_matchs_condition; /* next condition */ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (filter_list), &iter); } if (point_matchs_filter) { value = (guint) g_object_get_data(G_OBJECT (tab), "eprom_value"); /* convert 16 bit colors to 8 bit colors */ col_r = (guint) g_object_get_data(G_OBJECT (tab), "color_r") >> 8; col_g = (guint) g_object_get_data(G_OBJECT (tab), "color_g") >> 8; col_b = (guint) g_object_get_data(G_OBJECT (tab), "color_b") >> 8; } /* next filter */ tabs = tabs->next; } if (eprom_value) *eprom_value = value; if (color_r) *color_r = col_r; if (color_g) *color_g = col_g; if (color_b) *color_b = col_b; } void empty_filter_list( GtkWidget *tab_group ) { GList *tabs; tabs = GTK_BOX (tab_group)->children; /* for each filter */ while (tabs) { GtkBoxChild *child; GtkWidget *tab; child = tabs->data; tab = child->widget; remove_tab(tab, NULL); /* next filter */ tabs = GTK_BOX (tab_group)->children; } g_object_set_data(G_OBJECT (tab_group), "selected_tab", NULL); } void save_filter_list( GtkWidget *tab_group, gchar * filename ) { GList *tabs; FILE * f; guint filter_count; f = fopen(filename, "w"); if (!f) { fprintf(stderr, "Impossible d'ouvrir \"%s\"\n", filename); exit(EXIT_FAILURE); } tabs = GTK_BOX (tab_group)->children; filter_count = 0; /* for each filter */ while (tabs) { filter_count++; /* next filter */ tabs = tabs->next; } fprintf(f, "Filtres:\t%u\n", filter_count); tabs = GTK_BOX (tab_group)->children; /* for each filter */ while (tabs) { GtkListStore * filter_list; GtkTreeIter iter; GtkBoxChild *child; GtkWidget *tab; gboolean valid; guint value, col_r, col_g, col_b; guint condition_count; child = tabs->data; tab = child->widget; filter_list = g_object_get_data(G_OBJECT (tab), "filter_list"); value = (guint) g_object_get_data(G_OBJECT (tab), "eprom_value"); /* keep 16 bit colors */ col_r = (guint) g_object_get_data(G_OBJECT (tab), "color_r"); col_g = (guint) g_object_get_data(G_OBJECT (tab), "color_g"); col_b = (guint) g_object_get_data(G_OBJECT (tab), "color_b"); /* Get the first iter in the list */ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filter_list), &iter); condition_count = 0; while (valid) { condition_count++; /* next condition */ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (filter_list), &iter); } fprintf(f, "Filtre\t%u\t%u\t%u\t%u\t%u\n", value, col_r, col_g, col_b, condition_count); /* Get the first iter in the list */ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filter_list), &iter); while (valid) { char *colorspace, *composant; guchar min, max; gboolean invert; gtk_tree_model_get (GTK_TREE_MODEL (filter_list), &iter, COLORSPACE_COLUMN, &colorspace, COMPOSANT_COLUMN, &composant, MIN_COLUMN, &min, MAX_COLUMN, &max, INVERT_COLUMN, &invert, -1); fprintf(f, "\t%s\t%s\t%u\t%u\t%c\n", colorspace, composant, min, max, (invert ? 'y' : 'n')); g_free (colorspace); g_free (composant); /* next condition */ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (filter_list), &iter); } /* next filter */ tabs = tabs->next; } fclose(f); } void load_filter_list( GtkWidget *tab_group, gchar * filename ) { FILE * f; GtkWidget *tab; guint filter_count, i; GtkTreeSelection *filter_selection; filter_selection = g_object_get_data(G_OBJECT (tab_group), "filter_selection"); empty_filter_list(tab_group); f = fopen(filename, "r"); if (!f) { fprintf(stderr, "Impossible d'ouvrir \"%s\"\n", filename); exit(EXIT_FAILURE); } fscanf(f, "Filtres:\t%u\n", &filter_count); for (i=0; i