00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "stat.h"
00030
00031
00032 static void stat_window_connect_signals(heraia_plugin_t *plugin);
00033
00034 static void statw_close_clicked(GtkWidget *widget, gpointer data);
00035 static void destroy_stat_window(GtkWidget *widget, GdkEvent *event, gpointer data);
00036
00037 static void statw_save_as_clicked(GtkWidget *widget, gpointer data);
00038 static void statw_export_to_csv_clicked(GtkWidget *widget, gpointer data);
00039 static void statw_export_to_gnuplot_clicked(GtkWidget *widget, gpointer data);
00040 static void statw_export_to_pcv_clicked(GtkWidget *widget, gpointer data);
00041
00042 static gchar *stat_select_file_to_save(gchar *window_text);
00043 static void histo_radiobutton_toggled(GtkWidget *widget, gpointer data);
00044 static gboolean delete_stat_window_event(GtkWidget *widget, GdkEvent *event, gpointer data );
00045 static void realize_some_numerical_stat(heraia_window_t *main_struct, heraia_plugin_t *plugin);
00046 static void init_stats_histos(heraia_plugin_t *plugin);
00047 static void set_statw_button_state(GladeXML *xml, gboolean sensitive);
00048 static void populate_stats_histos(heraia_window_t *main_struct, heraia_plugin_t *plugin);
00049 static void calc_infos_histo_1D(stat_t *extra);
00050 static void calc_infos_histo_2D(stat_t *extra);
00051 static void init_stats_pixbufs(stat_t *extra);
00052 static void make_pixbufs_from_histos(stat_t *extra);
00053 static void plot_in_pixbuf(GdkPixbuf *pixbuf, gint64 x, gint64 y, guchar red, guchar green, guchar blue, guchar alpha);
00054 static void do_pixbuf_1D_from_histo1D(stat_t *extra);
00055 static void do_pixbuf_2D_from_histo2D(stat_t *extra, guint max_2D);
00056
00057
00058
00059
00060
00061
00062
00063
00064 heraia_plugin_t *heraia_plugin_init(heraia_plugin_t *plugin)
00065 {
00066 stat_t *extra = NULL;
00067 window_prop_t *stat_prop = NULL;
00068
00069 plugin->state = PLUGIN_STATE_INITIALIZING;
00070 plugin->xml = NULL;
00071
00072 plugin->info->api_version = API_VERSION;
00073 plugin->info->type = PLUGIN_TYPE;
00074 plugin->info->priority = HERAIA_PRIORITY_DEFAULT;
00075 plugin->info->name = PLUGIN_NAME;
00076 plugin->info->version = PLUGIN_VERSION;
00077 plugin->info->summary = PLUGIN_SUMMARY;
00078 plugin->info->description = PLUGIN_DESCRIPTION;
00079 plugin->info->author = PLUGIN_AUTHOR;
00080 plugin->info->homepage = PLUGIN_HOMEPAGE;
00081
00082 plugin->init_proc = init;
00083 plugin->quit_proc = quit;
00084 plugin->run_proc = run;
00085 plugin->refresh_proc = refresh;
00086
00087 plugin->filter->extensions = NULL;
00088 plugin->filter->import = NULL;
00089 plugin->filter->export = NULL;
00090
00091
00092 extra = (stat_t *) g_malloc0 (sizeof(stat_t));
00093 extra->infos_1D = (histo_infos_t *) g_malloc0 (sizeof(histo_infos_t));
00094 extra->infos_2D = (histo_infos_t *) g_malloc0 (sizeof(histo_infos_t));
00095
00096
00097 stat_prop = (window_prop_t *) g_malloc0(sizeof(window_prop_t));
00098 stat_prop->displayed = FALSE;
00099 stat_prop->x = 0;
00100 stat_prop->y = 0;
00101
00102 plugin->win_prop = stat_prop;
00103
00104 plugin->extra = extra;
00105
00106
00107 return plugin;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117 void init(heraia_window_t *main_struct)
00118 {
00119 heraia_plugin_t *plugin = NULL;
00120
00121 log_message(main_struct, G_LOG_LEVEL_INFO, "Initializing plugin %s", PLUGIN_NAME);
00122
00123 plugin = find_plugin_by_name(main_struct->plugins_list, PLUGIN_NAME);
00124
00125 if (plugin != NULL)
00126 {
00127
00128 log_message(main_struct, G_LOG_LEVEL_INFO, "Plugin from %s found !", plugin->info->author);
00129 if (load_plugin_glade_xml(main_struct, plugin) == TRUE)
00130 {
00131 log_message(main_struct, G_LOG_LEVEL_INFO, "%s xml interface loaded.", plugin->info->name);
00132 }
00133 else
00134 {
00135 log_message(main_struct, G_LOG_LEVEL_WARNING, "Unable to load %s xml interface.", plugin->info->name);
00136 }
00137
00138
00139 set_statw_button_state(plugin->xml, FALSE);
00140
00141
00142 if (plugin->win_prop->displayed == FALSE)
00143 {
00144 gtk_widget_hide(GTK_WIDGET(glade_xml_get_widget(plugin->xml, "stat_window")));
00145 }
00146 else
00147 {
00148 gtk_check_menu_item_set_active(plugin->cmi_entry, TRUE);
00149 }
00150
00151
00152 stat_window_connect_signals(plugin);
00153
00154 }
00155 }
00156
00157
00158
00159
00160
00161
00162 void quit(void)
00163 {
00164 g_print("Quitting %s\n", PLUGIN_NAME);
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 void run(GtkWidget *widget, gpointer data)
00175 {
00176 heraia_window_t *main_struct = (heraia_window_t *) data;
00177 heraia_plugin_t *plugin = NULL;
00178
00179
00180 plugin = find_plugin_by_name(main_struct->plugins_list, PLUGIN_NAME);
00181
00182 if (plugin != NULL)
00183 {
00184 show_hide_widget(GTK_WIDGET(glade_xml_get_widget(plugin->xml, "stat_window")),
00185 gtk_check_menu_item_get_active(plugin->cmi_entry), plugin->win_prop);
00186 if (gtk_check_menu_item_get_active(plugin->cmi_entry) == TRUE)
00187 {
00188 plugin->state = PLUGIN_STATE_RUNNING;
00189 realize_some_numerical_stat(main_struct, plugin);
00190 }
00191 else
00192 {
00193 plugin->state = PLUGIN_STATE_NONE;
00194 }
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 static void set_statw_button_state(GladeXML *xml, gboolean sensitive)
00205 {
00206 if (xml != NULL)
00207 {
00208 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "statw_save_as"), sensitive);
00209 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "statw_export_to_csv"), sensitive);
00210 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "statw_export_to_gnuplot"), sensitive);
00211 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "statw_export_to_pcv"), sensitive);
00212 }
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 void refresh(heraia_window_t *main_struct, void *data)
00224 {
00225 heraia_plugin_t *plugin = (heraia_plugin_t *) data;
00226
00227 if (main_struct != NULL && plugin != NULL)
00228 {
00229 if (main_struct->event == HERAIA_REFRESH_NEW_FILE || main_struct->event == HERAIA_REFRESH_TAB_CHANGED)
00230 {
00231 set_statw_button_state(plugin->xml, TRUE);
00232 plugin->run_proc(NULL, (gpointer) main_struct);
00233 }
00234 }
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 static gboolean delete_stat_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
00252 {
00253 statw_close_clicked(widget, data);
00254
00255 return TRUE;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 static void destroy_stat_window(GtkWidget *widget, GdkEvent *event, gpointer data)
00267 {
00268 statw_close_clicked(widget, data);
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 static void statw_close_clicked(GtkWidget *widget, gpointer data)
00278 {
00279 heraia_plugin_t *plugin = (heraia_plugin_t *) data;
00280
00281 if (plugin != NULL)
00282 {
00283 show_hide_widget(GTK_WIDGET(glade_xml_get_widget(plugin->xml, "stat_window")), FALSE, plugin->win_prop);
00284 gtk_check_menu_item_set_active(plugin->cmi_entry, FALSE);
00285 }
00286 }
00287
00288
00289
00290
00291
00292
00293
00294 static void statw_save_as_clicked(GtkWidget *widget, gpointer data)
00295 {
00296 heraia_plugin_t *plugin = (heraia_plugin_t *) data;
00297 GtkImage *image = NULL;
00298 GdkPixbuf *pixbuf = NULL;
00299 gchar *filename = NULL;
00300 GError **error = NULL;
00301
00302 if (plugin != NULL)
00303 {
00304 image = GTK_IMAGE(glade_xml_get_widget(plugin->xml, "histo_image"));
00305 pixbuf = gtk_image_get_pixbuf(image);
00306
00307 filename = stat_select_file_to_save("Enter filename's to save the image to");
00308 if (filename != NULL)
00309 {
00310 gdk_pixbuf_save(pixbuf, filename, "png", error, "compression", "9", NULL);
00311 g_free(filename);
00312 }
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 static gchar *stat_select_file_to_save(gchar *window_text)
00323 {
00324
00325 GtkFileChooser *file_chooser = NULL;
00326 gint response_id = 0;
00327 gchar *filename;
00328
00329 file_chooser = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(window_text, NULL,
00330 GTK_FILE_CHOOSER_ACTION_SAVE,
00331 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00332 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
00333 NULL));
00334
00335
00336
00337
00338
00339 gtk_window_set_modal(GTK_WINDOW(file_chooser), TRUE);
00340 gtk_file_chooser_set_select_multiple(file_chooser, FALSE);
00341
00342
00343 response_id = gtk_dialog_run(GTK_DIALOG(file_chooser));
00344
00345 switch (response_id)
00346 {
00347 case GTK_RESPONSE_OK:
00348 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
00349
00350 break;
00351 case GTK_RESPONSE_CANCEL:
00352 default:
00353 filename = NULL;
00354 break;
00355 }
00356
00357
00358
00359 gtk_widget_destroy(GTK_WIDGET(file_chooser));
00360 return filename;
00361 }
00362
00363
00364
00365
00366
00367
00368 static void statw_export_to_csv_clicked(GtkWidget *widget, gpointer data)
00369 {
00370 heraia_plugin_t *plugin = (heraia_plugin_t *) data;
00371 stat_t *extra = NULL;
00372 gchar *filename = NULL;
00373 FILE *fp = NULL;
00374 guint i = 0;
00375 guint j = 0;
00376
00377 if (plugin != NULL)
00378 {
00379 extra = (stat_t *) plugin->extra;
00380
00381 filename = stat_select_file_to_save("Enter filename to export data as CSV to");
00382
00383 if (filename != NULL)
00384 {
00385 fp = g_fopen(filename, "w+");
00386 }
00387
00388 if (fp != NULL && extra != NULL)
00389 {
00390 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(plugin->xml, "rb_1D"))) == TRUE)
00391 {
00392
00393 fprintf(fp, "\"Byte\";\"Count\"\n");
00394
00395 for (i=0; i<=255; i++)
00396 {
00397 fprintf(fp, "%d;%Ld\n", i, extra->histo1D[i]);
00398 }
00399
00400 }
00401 else
00402 {
00403
00404 fprintf(fp, "\"Byte/Byte\";");
00405 for (j=0; j<255; j++)
00406 {
00407 fprintf(fp, "\"%d\";", j);
00408 }
00409 fprintf(fp, "\"%d\"\n", 255);
00410
00411 for (i=0; i<=255; i++)
00412 {
00413 fprintf(fp, "\"%d\";", i);
00414 for (j=0 ; j<255; j++)
00415 {
00416 fprintf(fp, "\"%Ld\";", extra->histo2D[i][j]);
00417 }
00418 fprintf(fp, "\"%Ld\"\n", extra->histo2D[i][255]);
00419 }
00420 }
00421 fclose(fp);
00422 }
00423 if (filename != NULL)
00424 {
00425 g_free(filename);
00426 }
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435 static void statw_export_to_gnuplot_clicked(GtkWidget *widget, gpointer data)
00436 {
00437 heraia_plugin_t *plugin = (heraia_plugin_t *) data;
00438 stat_t *extra = NULL;
00439 gchar *filename = NULL;
00440 FILE *fp = NULL;
00441 guint i = 0;
00442 guint j = 0;
00443
00444 if (plugin != NULL)
00445 {
00446 extra = (stat_t *) plugin->extra;
00447
00448 filename = stat_select_file_to_save("Enter filename to export data as gnuplot to");
00449
00450 if (filename != NULL)
00451 {
00452 fp = g_fopen(filename, "w+");
00453 }
00454
00455 if (fp != NULL && extra != NULL)
00456 {
00457
00458 fprintf(fp, "set terminal png transparent nocrop enhanced small size 1280,960\n");
00459 fprintf(fp, "set output '%s.png'\n", g_path_get_basename(filename));
00460 fprintf(fp, "set xrange [-10:265]\n");
00461 fprintf(fp, "set xlabel 'Bytes'\n");
00462
00463 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(plugin->xml, "rb_1D"))) == TRUE)
00464 {
00465
00466 fprintf(fp, "set title 'Classical histogram'\n");
00467 fprintf(fp, "set ylabel 'Count'\n");
00468 fprintf(fp, "plot '-' title 'Byte count' with impulses\n");
00469
00470 for (i=0; i<=255; i++)
00471 {
00472 fprintf(fp, "%Ld\n", extra->histo1D[i]);
00473 }
00474 fprintf(fp, "e\n");
00475 }
00476 else
00477 {
00478
00479 fprintf(fp, "set title 'Heatmap histogram'\n");
00480 fprintf(fp, "set bar 1.000000\n");
00481 fprintf(fp, "set style rectangle back fc lt -3 fillstyle solid 1.00 border -1\n");
00482 fprintf(fp, "unset key\n");
00483 fprintf(fp, "set view map\n");
00484 fprintf(fp, "set yrange [-10:265]\n");
00485 fprintf(fp, "set ylabel 'Bytes'\n");
00486 fprintf(fp, "set palette rgbformulae 36, 13, 15\n");
00487 fprintf(fp, "splot '-' matrix with image\n");
00488
00489 for (i=0; i<=255; i++)
00490 {
00491 for (j=0; j<=255; j++)
00492 {
00493 fprintf(fp, "%Ld ", extra->histo2D[i][j]);
00494 }
00495 fprintf(fp, "\n");
00496 }
00497
00498 fprintf(fp, "e\n");
00499 fprintf(fp, "e\n");
00500 }
00501 fclose(fp);
00502 }
00503 if (filename != NULL)
00504 {
00505 g_free(filename);
00506 }
00507 }
00508 }
00509
00510
00511
00512
00513
00514
00515 static void statw_export_to_pcv_clicked(GtkWidget *widget, gpointer data)
00516 {
00517 heraia_plugin_t *plugin = (heraia_plugin_t *) data;
00518 stat_t *extra = NULL;
00519 gchar *filename = NULL;
00520 FILE *fp = NULL;
00521 guint i = 0;
00522 guint j = 0;
00523
00524 if (plugin != NULL)
00525 {
00526 extra = (stat_t *) plugin->extra;
00527
00528 filename = stat_select_file_to_save("Enter filename to export data as PCV to");
00529
00530 if (filename != NULL)
00531 {
00532 fp = g_fopen(filename, "w+");
00533 }
00534
00535 if (fp != NULL && extra != NULL)
00536 {
00537 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(plugin->xml, "rb_1D"))) == TRUE)
00538 {
00539
00540 fprintf(fp, "header {\n");
00541 fprintf(fp, "\theight = \"960\";\n");
00542 fprintf(fp, "\twidth = \"1280\";\n");
00543 fprintf(fp, "\ttitle = \"Classical histogram\";\n");
00544 fprintf(fp, "}\n");
00545 fprintf(fp, "axes {\n");
00546 fprintf(fp, "\tinteger b [label=\"Bytes\"];\n");
00547 fprintf(fp, "\tinteger c [label=\"Byte count\"];\n");
00548 fprintf(fp, "}\n");
00549 fprintf(fp, "data {\n");
00550
00551 for (i=0; i<=255; i++)
00552 {
00553 fprintf(fp, "\tb=\"%d\", c=\"%Ld\";\n", i, extra->histo1D[i]);
00554 }
00555 fprintf(fp, "}\n");
00556 }
00557 else
00558 {
00559
00560 fprintf(fp, "header {\n");
00561 fprintf(fp, "\theight = \"960\";\n");
00562 fprintf(fp, "\twidth = \"1280\";\n");
00563 fprintf(fp, "\ttitle = \"Classical histogram\";\n");
00564 fprintf(fp, "}\n");
00565 fprintf(fp, "axes {\n");
00566 fprintf(fp, "\tchar a [label=\"Bytes\"];\n");
00567 fprintf(fp, "\tport c [label=\"Byte count\"];\n");
00568 fprintf(fp, "\tchar b [label=\"Bytes\"];\n");
00569 fprintf(fp, "}\n");
00570 fprintf(fp, "data {\n");
00571
00572 for (i=0; i<=255; i++)
00573 {
00574 for (j=0; j<=255; j++)
00575 {
00576 if (extra->histo2D[i][j] == extra->infos_2D->max)
00577 {
00578 fprintf(fp, "\ta=\"%d\", c=\"%Ld\", b=\"%d\" [color=\"red\"];\n", i, extra->histo2D[i][j], j);
00579 }
00580 else
00581 {
00582 if (extra->histo2D[i][j] == extra->infos_2D->min)
00583 {
00584 fprintf(fp, "\ta=\"%d\", c=\"%Ld\", b=\"%d\" [color=\"green\"];\n", i, extra->histo2D[i][j], j);
00585 }
00586 else
00587 {
00588 fprintf(fp, "\ta=\"%d\", c=\"%Ld\", b=\"%d\";\n", i, extra->histo2D[i][j], j);
00589 }
00590 }
00591 }
00592 }
00593 fprintf(fp, "}\n");
00594 }
00595 fclose(fp);
00596 }
00597 if (filename != NULL)
00598 {
00599 g_free(filename);
00600 }
00601 }
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611 static void histo_radiobutton_toggled(GtkWidget *widget, gpointer data)
00612 {
00613 heraia_plugin_t *plugin = (heraia_plugin_t *) data;
00614
00615 if (plugin != NULL)
00616 {
00617 GtkImage *image = GTK_IMAGE(glade_xml_get_widget(plugin->xml, "histo_image"));
00618 stat_t *extra = (stat_t *) plugin->extra;
00619
00620 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(plugin->xml, "rb_1D"))) == TRUE)
00621 gtk_image_set_from_pixbuf(image, extra->pixbuf_1D);
00622 else
00623 {
00624 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(plugin->xml, "rb_2D"))) == TRUE)
00625 gtk_image_set_from_pixbuf(image, extra->pixbuf_2D);
00626 }
00627 }
00628 }
00629
00630
00631
00632
00633
00634
00635 static void stat_window_connect_signals(heraia_plugin_t *plugin)
00636 {
00637
00638 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "stat_window")), "delete_event",
00639 G_CALLBACK(delete_stat_window_event), plugin);
00640
00641 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "stat_window")), "destroy",
00642 G_CALLBACK(destroy_stat_window), plugin);
00643
00644
00645 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "statw_close_b")), "clicked",
00646 G_CALLBACK(statw_close_clicked), plugin);
00647
00648
00649 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "rb_1D")), "toggled",
00650 G_CALLBACK(histo_radiobutton_toggled), plugin);
00651
00652 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "rb_2D")), "toggled",
00653 G_CALLBACK(histo_radiobutton_toggled), plugin);
00654
00655
00656 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "statw_save_as")), "clicked",
00657 G_CALLBACK(statw_save_as_clicked), plugin);
00658
00659
00660 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "statw_export_to_csv")), "clicked",
00661 G_CALLBACK(statw_export_to_csv_clicked), plugin);
00662
00663
00664 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "statw_export_to_gnuplot")), "clicked",
00665 G_CALLBACK(statw_export_to_gnuplot_clicked), plugin);
00666
00667
00668 g_signal_connect(G_OBJECT(glade_xml_get_widget(plugin->xml, "statw_export_to_pcv")), "clicked",
00669 G_CALLBACK(statw_export_to_pcv_clicked), plugin);
00670
00671
00672 }
00673
00674
00675
00676
00677
00678
00679
00680 static void realize_some_numerical_stat(heraia_window_t *main_struct, heraia_plugin_t *plugin)
00681 {
00682 struct stat *stat_buf;
00683 gchar buf[42];
00684 gchar *filename = NULL;
00685 stat_t *extra = NULL;
00686 GtkTextView *textview = GTK_TEXT_VIEW(glade_xml_get_widget(plugin->xml, "statw_textview"));
00687
00688 if (main_struct != NULL && main_struct->current_doc != NULL)
00689 {
00690 filename = doc_t_document_get_filename(main_struct->current_doc);
00691 }
00692
00693 if (filename != NULL)
00694 {
00695 log_message(main_struct, G_LOG_LEVEL_INFO, "Calculating stats on %s", filename);
00696
00697 stat_buf = (struct stat *) g_malloc0 (sizeof(struct stat));
00698 g_lstat(filename, stat_buf);
00699 if (S_ISREG(stat_buf->st_mode))
00700 {
00701 kill_text_from_textview(textview);
00702 add_text_to_textview(textview, "File size : %Ld bytes\n\n", stat_buf->st_size);
00703 ctime_r(&(stat_buf->st_mtime), buf);
00704 add_text_to_textview(textview, "Last intern modification : %s", buf);
00705 ctime_r(&(stat_buf->st_atime), buf);
00706 add_text_to_textview(textview, "Last acces to the file : %s", buf);
00707 ctime_r(&(stat_buf->st_ctime), buf);
00708 add_text_to_textview(textview, "Last extern modification : %s", buf);
00709
00710 populate_stats_histos(main_struct, plugin);
00711
00712 extra = (stat_t *) plugin->extra;
00713
00714 add_text_to_textview(textview, "\n1D histogram statistics :\n");
00715 add_text_to_textview(textview, " . minimum : %lld\n", extra->infos_1D->min);
00716 add_text_to_textview(textview, " . maximum : %lld\n", extra->infos_1D->max);
00717 add_text_to_textview(textview, " . mean : %lld\n", extra->infos_1D->mean);
00718 add_text_to_textview(textview, " . number of values : %lld\n", extra->infos_1D->nb_val);
00719 add_text_to_textview(textview, "\n2D histogram statistics :\n");
00720 add_text_to_textview(textview, " . minimum : %lld\n", extra->infos_2D->min);
00721 add_text_to_textview(textview, " . maximum : %lld\n", extra->infos_2D->max);
00722 add_text_to_textview(textview, " . mean : %lld\n", extra->infos_2D->mean);
00723 add_text_to_textview(textview, " . number of values : %lld\n", extra->infos_2D->nb_val);
00724 log_message(main_struct, G_LOG_LEVEL_INFO, "Histos calculated !");
00725 }
00726 }
00727 }
00728
00729
00730
00731
00732
00733 static void init_stats_histos(heraia_plugin_t *plugin)
00734 {
00735 guint i = 0;
00736 guint j = 0;
00737 stat_t *extra = NULL;
00738
00739
00740 extra = (stat_t *) plugin->extra;
00741 for (i=0; i<=255; i++)
00742 {
00743 extra->histo1D[i] = 0 ;
00744 for (j=0; j<=255; j++)
00745 extra->histo2D[i][j] = 0 ;
00746 }
00747 }
00748
00749
00750
00751
00752
00753 static void populate_stats_histos(heraia_window_t *main_struct, heraia_plugin_t *plugin)
00754 {
00755 GtkHex *gh = GTK_HEX(main_struct->current_doc->hex_widget);
00756 guint64 i = 0;
00757 guint64 taille = ghex_file_size(gh);
00758 guchar c1, c2;
00759 stat_t *extra = (stat_t *) plugin->extra;
00760 GtkImage *image = GTK_IMAGE(glade_xml_get_widget(plugin->xml, "histo_image"));
00761 GtkToggleButton *rb_1D = GTK_TOGGLE_BUTTON(glade_xml_get_widget(plugin->xml, "rb_1D"));
00762 GtkToggleButton *rb_2D = GTK_TOGGLE_BUTTON(glade_xml_get_widget(plugin->xml, "rb_2D"));
00763
00764 init_stats_histos(plugin);
00765
00766 while (i < taille)
00767 {
00768 c1 = gtk_hex_get_byte(gh, i);
00769 extra->histo1D[c1]++;
00770 if (i+1 < taille)
00771 {
00772 i++;
00773 c2 = gtk_hex_get_byte(gh, i);
00774 extra->histo1D[c2]++;
00775 extra->histo2D[c1][c2]++;
00776 }
00777 i++;
00778 }
00779
00780 make_pixbufs_from_histos(extra);
00781
00782 if (gtk_toggle_button_get_active(rb_1D) == TRUE)
00783 gtk_image_set_from_pixbuf(image, extra->pixbuf_1D);
00784 else
00785 if (gtk_toggle_button_get_active(rb_2D) == TRUE)
00786 gtk_image_set_from_pixbuf(image, extra->pixbuf_2D);
00787 }
00788
00789
00790
00791
00792
00793 static void calc_infos_histo_1D(stat_t *extra)
00794 {
00795 guint i = 0;
00796 gint64 n = 1;
00797 guint64 max = 0;
00798 guint64 min = G_MAXUINT64;
00799 gint64 mean = extra->histo1D[0];
00800 gint64 diff = 0;
00801
00802 extra->infos_1D->nb_val = 0;
00803
00804 for (i=0; i<=255; i++)
00805 {
00806
00807 if (extra->histo1D[i] > max)
00808 max = extra->histo1D[i];
00809
00810
00811 if (extra->histo1D[i] < min)
00812 min = extra->histo1D[i];
00813
00814
00815 if (extra->histo1D[i] > 0)
00816 extra->infos_1D->nb_val++;
00817
00818
00819 diff = extra->histo1D[i] - mean;
00820 mean = mean + diff/n;
00821 n++;
00822 }
00823
00824 extra->infos_1D->min = min;
00825 extra->infos_1D->max = max;
00826 extra->infos_1D->mean = (guint64) mean;
00827 }
00828
00829
00830
00831
00832
00833 static void calc_infos_histo_2D(stat_t *extra)
00834 {
00835 guint i = 0;
00836 guint j = 0;
00837 gint64 n = 1;
00838 guint64 max = 0;
00839 guint64 min = G_MAXUINT;
00840 gint64 mean = extra->histo2D[0][0];
00841 gint64 diff = 0;
00842
00843 extra->infos_2D->nb_val = 0;
00844
00845 for (i=0; i<=255; i++)
00846 {
00847 for (j=0; j<=255; j++)
00848 {
00849
00850 if (extra->histo2D[i][j] > max)
00851 max = extra->histo2D[i][j];
00852
00853
00854 if (extra->histo2D[i][j] < min)
00855 min = extra->histo2D[i][j];
00856
00857
00858 if (extra->histo2D[i][j] > 0)
00859 extra->infos_2D->nb_val++;
00860
00861
00862 diff = extra->histo2D[i][j] - mean;
00863 mean = mean + diff/n;
00864 n++;
00865 }
00866 }
00867
00868 extra->infos_2D->min = min;
00869 extra->infos_2D->max = max;
00870 extra->infos_2D->mean = (guint64) mean;
00871 }
00872
00873
00874
00875
00876
00877 static void init_stats_pixbufs(stat_t *extra)
00878 {
00879
00880 extra->pixbuf_1D = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 255, 255);
00881 gdk_pixbuf_fill(extra->pixbuf_1D, 0xFFFFFF00);
00882 gdk_pixbuf_add_alpha(extra->pixbuf_1D, TRUE, (guchar) 255, (guchar) 255, (guchar) 255);
00883
00884 extra->pixbuf_2D = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 255, 255);
00885 gdk_pixbuf_fill(extra->pixbuf_2D, 0xFFFFFF00);
00886 gdk_pixbuf_add_alpha(extra->pixbuf_2D, TRUE, (guchar) 255, (guchar) 255, (guchar) 255);
00887
00888 }
00889
00890
00891
00892
00893
00894 static void make_pixbufs_from_histos(stat_t *extra)
00895 {
00896 init_stats_pixbufs(extra);
00897 calc_infos_histo_1D(extra);
00898 calc_infos_histo_2D(extra);
00899
00900 if (extra->infos_1D->max > 0)
00901 do_pixbuf_1D_from_histo1D(extra);
00902 if (extra->infos_2D->max > 0)
00903 do_pixbuf_2D_from_histo2D(extra, extra->infos_2D->max);
00904 }
00905
00906
00907
00908
00909
00910 static void plot_in_pixbuf(GdkPixbuf *pixbuf, gint64 x, gint64 y, guchar red, guchar green, guchar blue, guchar alpha)
00911 {
00912 guchar *pixels = NULL;
00913 guchar *p = NULL;
00914
00915 pixels = gdk_pixbuf_get_pixels(pixbuf);
00916
00917 p = pixels + y * gdk_pixbuf_get_rowstride(pixbuf) + x * gdk_pixbuf_get_n_channels(pixbuf);
00918
00919 p[0] = red;
00920 p[1] = green;
00921 p[2] = blue;
00922 p[3] = alpha;
00923
00924 }
00925
00926
00927
00928
00929
00930 static void line_in_pixbuf(GdkPixbuf *pixbuf, gint64 x, gint64 y)
00931 {
00932 guchar *pixels = NULL;
00933 guchar *p = NULL;
00934
00935 if (pixbuf != NULL)
00936 {
00937
00938 gint rowstride = gdk_pixbuf_get_rowstride(pixbuf);
00939 gint n_channels = gdk_pixbuf_get_n_channels(pixbuf);
00940
00941 pixels = gdk_pixbuf_get_pixels(pixbuf);
00942
00943 while (y<255)
00944 {
00945 p = pixels + y * rowstride + x * n_channels;
00946 p[0] = (guchar) 255-(y/2);
00947 p[1] = (guchar) 16;
00948 p[2] = (guchar) y/2;
00949 p[3] = (guchar) 255;
00950 y++;
00951 }
00952 }
00953 }
00954
00955
00956
00957
00958
00959
00960 static void do_pixbuf_1D_from_histo1D(stat_t *extra)
00961 {
00962 guint i = 0;
00963 gint64 y = 0;
00964 gdouble inter = 0;
00965 gdouble y_norm = 0;
00966
00967 for (i=0; i<=255; i++)
00968 {
00969
00970 y_norm = (gdouble) extra->infos_1D->max - (gdouble) extra->histo1D[i];
00971 inter = (gdouble) (y_norm*255) / (gdouble)(extra->infos_1D->max);
00972 y = (gint64) inter;
00973 line_in_pixbuf(extra->pixbuf_1D, i, y);
00974 }
00975 }
00976
00977
00978
00979
00980
00981
00982
00983
00984 static void do_pixbuf_2D_from_histo2D(stat_t *extra, guint max_2D)
00985 {
00986
00987 guint i = 0;
00988 guint j = 0;
00989 guchar red;
00990 guchar green;
00991 guchar blue;
00992 gdouble height = 0;
00993 gdouble max = 0;
00994 gdouble min = 0;
00995 gdouble mean = 0;
00996 gdouble threshold1 = 0;
00997 gdouble threshold2 = 0;
00998 guchar ceill;
00999 guchar floor;
01000
01001 max = extra->infos_2D->max;
01002 min = extra->infos_2D->min;
01003 mean = extra->infos_2D->mean;
01004
01005 threshold1 = min + (mean - min) / 2;
01006 threshold2 = mean + (max - mean) / 2;
01007
01008 floor = (guchar) 50;
01009 ceill = (guchar) 200;
01010
01011 for (i=0; i<=255; i++)
01012 {
01013 for (j=0; j<=255; j++)
01014 {
01015 height = extra->histo2D[i][j];
01016
01017 if (height > 0)
01018 {
01019
01020 if (height >= min && height <= threshold1)
01021 {
01022 red = floor;
01023 green = floor;
01024 blue = (guchar) (height - min)*(ceill-floor) / threshold1;
01025
01026
01027
01028
01029
01030
01031 plot_in_pixbuf(extra->pixbuf_2D, i, 255-j, red, green, blue, (guchar) 255);
01032 }
01033 else if (height > threshold1 && height <= threshold2)
01034 {
01035 red = (guchar) floor;
01036 green = (guchar) (height - threshold1)*(ceill-floor) / (threshold2 - threshold1);
01037 blue = (guchar) floor;
01038 plot_in_pixbuf(extra->pixbuf_2D, i, 255-j, red, green, blue, (guchar) 255);
01039 }
01040 else if (height > threshold2 && height <= max)
01041 {
01042 red = (guchar) (height - threshold2)*(ceill-floor) / (max - threshold2);
01043 green = floor;
01044 blue = floor;
01045
01046
01047
01048
01049
01050
01051 plot_in_pixbuf(extra->pixbuf_2D, i, 255-j, red, green, blue, (guchar) 255);
01052 }
01053 }
01054 }
01055 }
01056 }
01057
01058