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