/basic_libs/blaa/tools/gtk_run/src/main.cpp
C++ | 447 lines | 259 code | 63 blank | 125 comment | 27 complexity | a8a1e94b61036e76a559dab0d07c6888 MD5 | raw file
- #include <fcntl.h> // O_RDONLY ...
- #include <stdio.h>
- #include <gtk/gtk.h>
- #include <string.h>
- #include <stdint.h> //uint32_t
- #include <jpeglib.h>
- #include "blc.h"
- //#include "record.hh"
- // Pour les view metre / text boxes */
- const float value_max = 1;
- const float value_min = 0;
- GtkWidget *window;
- static uchar *RGB3_from_YUYV = NULL;
- pthread_t init_table_thread;
- struct blc_channel_info *channels_infos=NULL;
- GtkWidget **channels_display;
- void getting_range(GtkRange *range, float *value)
- {
- *value = gtk_range_get_value(range);
- }
- void getting_spin_value(GtkSpinButton *button, float *value)
- {
- *value = gtk_spin_button_get_value(button);
- }
- void getting_check_value(GtkToggleButton *button, float *value)
- {
- if (gtk_toggle_button_get_active(button)) *value = 1.0;
- else *value = 0.0;
- }
- gboolean update_range(GtkRange *range, GdkFrameClock *frame_clock, float *value)
- {
- (void) frame_clock;
- gtk_range_set_value(range, *value);
- return G_SOURCE_CONTINUE;
- }
- gboolean update_spin_value(GtkSpinButton *button, GdkFrameClock *frame_clock, float *value)
- {
- (void) frame_clock;
- gtk_spin_button_set_value(button, *value);
- return G_SOURCE_CONTINUE;
- }
- gboolean update_check_value(GtkToggleButton *button, GdkFrameClock *frame_clock, float *value)
- {
- (void) frame_clock;
- gtk_toggle_button_set_active(button, (*value > 0.5));
- return G_SOURCE_CONTINUE;
- }
- /** Gtk cannot display a black and white image, therefore we convert it before updating it*/
- gboolean update_GREY_image(GtkImage *image, GdkFrameClock *frame_clock, blc_channel *channel)
- {
- GdkPixbuf *pixbuf;
- int i, offset;
- uchar *pixels;
- (void) frame_clock;
- pixbuf = gtk_image_get_pixbuf(image);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
- offset = (channel->size - 1) * 3;
- // Conversion GREY -> RGB3
- FOR_INV(i, channel->size)
- {
- memset(&pixels[offset], channel->data[i], 3);
- offset -= 3;
- }
- gtk_image_set_from_pixbuf(image, pixbuf);
- return G_SOURCE_CONTINUE;
- }
- gboolean update_RGB3_image(GtkImage *image, GdkFrameClock *frame_clock, GdkPixbuf *pixbuf)
- {
- (void) frame_clock;
- gtk_image_set_from_pixbuf(image, pixbuf);
- return G_SOURCE_CONTINUE;
- }
- void jpeg_error(j_common_ptr cinfo, int msg_level)
- {
- (void) msg_level;
- cinfo->err->num_warnings++;
- }
- gboolean update_JPEG_image(GtkImage *image, GdkFrameClock *frame_clock, blc_channel *channel)
- {
- JSAMPROW row_pt[1];
- GdkPixbuf *pixbuf;
- int row_stride;
- uchar *pixels;
- struct jpeg_decompress_struct cinfo;
- struct jpeg_error_mgr jerr;
- (void) frame_clock;
- pixbuf = gtk_image_get_pixbuf(image);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
- cinfo.err = jpeg_std_error(&jerr);
- cinfo.err->emit_message = jpeg_error;
- jpeg_create_decompress(&cinfo);
- jpeg_mem_src(&cinfo, (uchar*) channel->data, channel->size);
- jpeg_read_header(&cinfo, TRUE);
- jpeg_start_decompress(&cinfo);
- row_stride = cinfo.output_width * cinfo.output_components;
- row_pt[0] = pixels;
- while (cinfo.output_scanline < cinfo.output_height)
- {
- jpeg_read_scanlines(&cinfo, row_pt, 1);
- row_pt[0] += row_stride;
- }
- if (cinfo.err->num_warnings != 0)
- {
- PRINT_WARNING("Drop image : %s", cinfo.err->jpeg_message_table[cinfo.err->last_jpeg_message]);
- cinfo.err->num_warnings = 0;
- }
- gtk_image_set_from_pixbuf(image, pixbuf);
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- return G_SOURCE_CONTINUE;
- }
- // 4:2:2
- gboolean update_YUYV_image(GtkImage *image, GdkFrameClock *frame_clock, blc_channel *channel)
- {
- GdkPixbuf *pixbuf;
- int i, j;
- uchar *data = (uchar*) channel->data;
- uchar *pixels, *tmp_pixels;
- int Y, Cb = 128, Cr = 128;
- (void) frame_clock;
- pixbuf = gtk_image_get_pixbuf(image);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
- tmp_pixels = pixels;
- i = 0;
- while (i != (int) channel->size)
- {
- Y = data[i++];
- Cb = data[i++];
- j = Y + (Cb << 8) + (Cr << 16);
- memcpy(tmp_pixels, RGB3_from_YUYV + j * 3, 3);
- Y = data[i++];
- Cr = data[i++];
- j = Y + (Cb << 8) + (Cr << 16);
- memcpy(tmp_pixels + 3, RGB3_from_YUYV + j * 3, 3);
- tmp_pixels+=6;
- }
- gtk_image_set_from_pixbuf(image, pixbuf);
- return G_SOURCE_CONTINUE;
- }
- void* create_RGB3_from_YUYV(void *widget)
- {
- int Y, Cb, Cr;
- int i, j;
- float G_tmp;
- static uchar R[256], B;
- struct timeval time = {0,0};
- if (RGB3_from_YUYV == NULL)
- {
- RGB3_from_YUYV= MANY_ALLOCATIONS(256*256*256*3, uchar);
- diff_us_time(&time);
- i;
- FOR_INV(Y, 256)
- {
- FOR_INV(j,256) R[j]= CLIP_UCHAR(Y+1.13983*(j-128)); //It does not depend on Cb
- FOR_INV(Cb, 256)
- {
- B = CLIP_UCHAR(Y+2.03211*(Cb-128)); // It does not depend on Cr
- G_tmp = - 0.58060*(Cb-128);
- FOR_INV(Cr, 256)
- {
- i = 3 * (Y + (Cb << 8) + (Cr << 16));
- // Version Wikipedia
- RGB3_from_YUYV[i] = R[Cr];
- RGB3_from_YUYV[i + 1] = CLIP_UCHAR(Y-0.39465*(Cr-128) + G_tmp);
- RGB3_from_YUYV[i + 2] = B;
- }
- }
- }
- printf("time %lfms\n", diff_us_time(&time)/1000.);
- }
- return NULL;
- }
- /*
- void type_experience::create_display()
- {
- GtkWidget *grid;
- GtkWidget *scrolled_window;
- display = gtk_frame_new(name);
- scrolled_window = gtk_scrolled_window_new(NULL, NULL);
- grid = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add(GTK_CONTAINER(display), scrolled_window);
- gtk_container_add(GTK_CONTAINER(scrolled_window), grid);
- gtk_widget_set_vexpand(scrolled_window, TRUE);
- gtk_widget_set_hexpand(scrolled_window, TRUE);
- }
- /// Create a widget displaying the controls accordingly to the type of control
- void float_variable::create_display()
- {
- char label_text[NAME_MAX + 1];
- float *values = (float*) data;
- GtkWidget *widget = NULL, *grid;
- int i;
- display = gtk_frame_new(name);
- grid = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_container_add(GTK_CONTAINER(display), grid);
- if (display_type != UNDEFINED_DISPLAY)
- {
- FOR(i, values_nb)
- {
- switch (display_type)
- {
- case TEXT_DISPLAY:
- widget = gtk_spin_button_new_with_range(value_min, value_max, 0.001);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_spin_value, &values[i], NULL);
- g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(getting_spin_value), &values[i]);
- break;
- case VIEW_METER_DISPLAY:
- widget = gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL, value_min, value_max, 0.001);
- gtk_range_set_inverted(GTK_RANGE(widget), TRUE);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_range, &values[i], NULL);
- g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(getting_range), &values[i]);
- gtk_widget_set_size_request(widget, 40, 128);
- break;
- case CHECKBOX_DISPLAY:
- widget = gtk_check_button_new();
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_check_value, &values[i], NULL);
- g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(getting_check_value), &values[i]);
- break;
- break;
- }
- gtk_widget_set_vexpand(widget, TRUE);
- gtk_widget_set_hexpand(widget, TRUE);
- gtk_container_add(GTK_CONTAINER(grid), widget);
- }
- }
- else
- {
- snprintf(label_text, NAME_MAX, "Unknown display for %d float values.", values_nb);
- widget = gtk_label_new(label_text);
- gtk_container_add(GTK_CONTAINER(grid), widget);
- }
- }
- */
- /*
- /// Create a widget displaying an image accordingly to the type of the image
- void image_variable::create_display()
- {
- GdkPixbuf *pixbuf;
- GtkWidget *widget = NULL;
- char *image_buffer;
- char label_text[NAME_MAX + 1];
- sprintf(label_text, "%s %.4s", name, (char*) &pixel_format);
- display = gtk_frame_new(label_text);
- if (pixel_format == TO_UINT32("GREY") )
- {
- image_buffer = MANY_ALLOCATIONS(size * 3, char); //In order to be sure that the rowstride will be 'gui.width * 3'
- pixbuf = gdk_pixbuf_new_from_data((uchar*) image_buffer, GDK_COLORSPACE_RGB, 0, 8, width, height, width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_GREY_image, this, NULL);
- }
- else if (pixel_format == TO_UINT32("RGB3") )
- {
- pixbuf = gdk_pixbuf_new_from_data((uchar*) data, GDK_COLORSPACE_RGB, 0, 8, width, height, width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_RGB3_image, pixbuf, NULL);
- }
- else if (pixel_format == TO_UINT32("JPEG") )
- {
- image_buffer = MANY_ALLOCATIONS(size * 3, char); //In order to be sure that the rowstride will be 'gui.width * 3'
- pixbuf = gdk_pixbuf_new_from_data((uchar*) image_buffer, GDK_COLORSPACE_RGB, 0, 8, width, height, width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_JPEG_image, this, NULL);
- }
- else if ((pixel_format == TO_UINT32("YUYV") )|| (pixel_format == TO_UINT32("YUV2"))){
- image_buffer = MANY_ALLOCATIONS(size * 3, char); //In order to be sure that the rowstride will be 'gui.width * 3'
- pixbuf = gdk_pixbuf_new_from_data((uchar*)image_buffer, GDK_COLORSPACE_RGB, 0, 8, width, height, width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
- pthread_create(&init_table_thread, NULL, create_RGB3_from_YUYV, widget);
- gtk_widget_add_tick_callback(GTK_WIDGET(widget), (GtkTickCallback) update_YUYV_image, this, NULL);
- }
- else widget = gtk_label_new("Unknown format image");
- gtk_widget_set_size_request(GTK_WIDGET(display), 32, 32);
- gtk_container_add(GTK_CONTAINER(display), widget);
- }
- */
- GtkWidget *create_image_display(blc_channel *channel)
- {
- GdkPixbuf *pixbuf;
- GtkWidget *widget = NULL;
- uchar *image_buffer;
- char label_text[NAME_MAX + 1];
- GtkWidget *display;
- blc_image_info image(channel->parameter);
-
- sprintf(label_text, "%s %.4s", channel->name, UINT32_TO_STRING(image.format));
- display = gtk_frame_new(label_text);
-
- if (image.format == STRING_TO_UINT32("Y800") )
- {
- image_buffer = MANY_ALLOCATIONS(image.size * 3, uchar); //In order to be sure that the rowstride will be 'gui.width * 3'
- pixbuf = gdk_pixbuf_new_from_data( image_buffer, GDK_COLORSPACE_RGB, 0, 8, image.width, image.height, image.width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_GREY_image, channel, NULL);
- }
- else if (image.format == STRING_TO_UINT32("RGB3") )
- {
- pixbuf = gdk_pixbuf_new_from_data((uchar*)channel->data, GDK_COLORSPACE_RGB, 0, 8, image.width, image.height, image.width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_RGB3_image, pixbuf, NULL);
- }
- else if (image.format == STRING_TO_UINT32("JPEG") )
- {
- image_buffer = MANY_ALLOCATIONS(image.size * 3, uchar); //In order to be sure that the rowstride will be 'gui.width * 3'
- pixbuf = gdk_pixbuf_new_from_data( image_buffer, GDK_COLORSPACE_RGB, 0, 8, image.width, image.height, image.width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
- gtk_widget_add_tick_callback(widget, (GtkTickCallback) update_JPEG_image, channel, NULL);
- }
- else if ((image.format == STRING_TO_UINT32("YUYV"))|| (image.format == STRING_TO_UINT32("yuv2"))){
- image_buffer = MANY_ALLOCATIONS(image.size * 3, uchar); //In order to be sure that the rowstride will be 'gui.width * 3'
- pixbuf = gdk_pixbuf_new_from_data(image_buffer, GDK_COLORSPACE_RGB, 0, 8, image.width, image.height, image.width * 3, NULL, NULL);
- widget = gtk_image_new_from_pixbuf(pixbuf);
-
- pthread_create(&init_table_thread, NULL, create_RGB3_from_YUYV, widget);
- gtk_widget_add_tick_callback(GTK_WIDGET(widget), (GtkTickCallback) update_YUYV_image, channel, NULL);
-
- }
- else widget = gtk_label_new("Unknown format image");
-
- gtk_widget_set_size_request(GTK_WIDGET(display), 32, 32);
- gtk_container_add(GTK_CONTAINER(display), widget);
- return display;
- }
- /** Look for the blc_channels and then create the graphical interface */
- static void activate(GtkApplication *app, char *start_filter)
- {
- struct blc_channel_info *info;
- blc_channel **channels;
- GtkWidget *layout, *grid;
- GtkBin *scrolled_window;
- int i, channels_nb;
- char title[NAME_MAX + 1];
- window = gtk_application_window_new(app);
- snprintf(title, NAME_MAX, "blc_channels %s", start_filter);
- gtk_window_set_title(GTK_WINDOW(window), title);
- gtk_widget_set_size_request(GTK_WIDGET(window), 400, 320);
- layout = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
- grid = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
- gtk_container_add(GTK_CONTAINER(window), layout);
- // gtk_container_add(GTK_CONTAINER(layout), create_record_interface());
- gtk_container_add(GTK_CONTAINER(layout), grid);
-
- channels_nb = blc_channel_get_all_infos(&channels_infos, start_filter);
-
- channels = MANY_ALLOCATIONS(channels_nb, blc_channel*);
- FOR (i, channels_nb)
- {
- info =&channels_infos[i];
- channels[i]=new blc_channel(info->name, info->referenced_size, info->sem_abp, info->type, info->parameter);
- }
-
-
- channels_display = MANY_ALLOCATIONS(channels_nb, GtkWidget*);
- FOR(i, channels_nb)
- {
- if (channels[i]->type == STRING_TO_UINT32("IMGE")) channels_display[i] = create_image_display(channels[i]);
- else channels_display[i] = gtk_label_new("Unknonwn channel type");
- gtk_container_add(GTK_CONTAINER(grid), GTK_WIDGET(channels_display[i]));
- }
- pthread_join(init_table_thread, NULL);
- gtk_widget_show_all(window);
- }
- /** Classical GTK application.
- * The first optional argument is the name of the experience. Otherwise all the existing shared memory are used.
- * */
- int main(int argc, char **argv)
- {
- GtkApplication *app;
- int status;
- char const *start_filter_name = "";
- gtk_disable_setlocale();
- gtk_init(&argc, &argv);
- if (argc == 2)
- {
- start_filter_name = argv[1];
- argc = 1; // To avoid g_application to try to interpret it.
- }
- app = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE);
- g_signal_connect(app, "activate", G_CALLBACK(activate), (void* )start_filter_name);
- status = g_application_run(G_APPLICATION(app), argc, argv);
- g_object_unref(app);
- return (status);
- }