diff --git a/check.sh b/check.sh deleted file mode 100755 index 7072e99cadb9b4902a4fcac30a994658ef58e2d2..0000000000000000000000000000000000000000 --- a/check.sh +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright ETIS — ENSEA, Université de Cergy-Pontoise, CNRS (2011 - 2016) -# Author: Arnaud Blanchard (November 2016) -# This software is governed by the CeCILL v2.1 license under French law and abiding by the rules of distribution of free software. -# You can use, modify and/ or redistribute the software under the terms of the CeCILL v2.1 license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info". -# As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, -# users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors have only limited liability. -# In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge. -# Users are therefore encouraged to load and test the software's suitability as regards their requirements in conditions enabling the security of their systems and/or data to be ensured  and, more generally, to use and operate it in the same conditions as regards security. -# The fact that you are presently reading this means that you have had knowledge of the CeCILL v2.1 license and that you accept its terms. - - -cd `dirname $0` -echo -echo "Checking `basename $PWD`" -echo "====================" -echo -echo "No check for now" -echo diff --git a/o_gtk_image/CMakeLists.txt b/o_gtk_image/CMakeLists.txt index 0234672735c1d058e48a86432e7d1302ed5a30dc..f57f750c62fcbdecb37f159e38ba0a5ffe54f3ad 100644 --- a/o_gtk_image/CMakeLists.txt +++ b/o_gtk_image/CMakeLists.txt @@ -18,7 +18,7 @@ add_definitions(-Wall ${BL_DEFINITIONS} -Wno-deprecated-declarations) #device_ma include_directories(${GTK3_INCLUDE_DIRS} ${BL_INCLUDE_DIRS} ${JPEG_INCLUDE_DIR}) link_directories(${GTK3_LIBRARY_DIRS}) add_definitions(${GTK3_CFLAGS_OTHER}) -add_executable(o_gtk_image src/o_gtk_image.cpp src/image_display.cpp) +add_executable(o_gtk_image src/o_gtk_image.cpp src/image_display.cpp src/histogram.cpp) target_link_libraries(o_gtk_image ${GTK3_LIBRARIES} ${BL_LIBRARIES} ${JPEG_LIBRARIES} ) diff --git a/o_gtk_image/src/common.h b/o_gtk_image/src/common.h new file mode 100644 index 0000000000000000000000000000000000000000..ae24106442bf8b25be0ec2d32b672b7af038cf98 --- /dev/null +++ b/o_gtk_image/src/common.h @@ -0,0 +1,34 @@ +#ifndef COMMON_H +#define COMMON_H + +#include <gtk/gtk.h> +#include <blc_channel.h> + + +extern float min, max; + +extern blc_channel *channel; +extern GtkWidget *legend; + +extern u_int32_t false_colors[256]; +extern uint32_t gray_colors[256]; +extern uint32_t u_colors[256]; +extern uint32_t v_colors[256]; +extern uint32_t r_colors[256]; +extern uint32_t g_colors[256]; +extern uint32_t b_colors[256]; +extern uint32_t *color_map; + +extern GtkWidget *paned; +extern GdkDevice *pointer_device; +extern blc_channel mouse_channel; + +extern char const *fullscreen_option; + + + +void histogram_cb(GtkToolButton *toolbutton, gpointer pointer_statusbar ); +GtkWidget *create_image_display(blc_channel *channel); + +#endif + diff --git a/o_gtk_image/src/histogram.cpp b/o_gtk_image/src/histogram.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b1e496fea41c13ff4223f5d05d5efa7b56dc954a --- /dev/null +++ b/o_gtk_image/src/histogram.cpp @@ -0,0 +1,222 @@ +#include "common.h" + +#include "blgtk.h" + +#include <fcntl.h> // O_RDONLY ... +#include <stdio.h> +#include <gtk/gtk.h> +#include <string.h> +#include <stdint.h> //uint32_t +#include <jpeglib.h> +#include <sys/mman.h> +#include <errno.h> //errno +#include "blc_image.h" +#include "blc_realtime.h" +#include "blc_program.h" //blc_status + +//cairo_surface_t *legend_surface; +guint histogram_tick_id; +uint32_t *histogram_data=NULL; +GtkWidget *histogram_image, *histogram, *histogram_scrolled_window; +cairo_surface_t *histogram_surface; + +static void draw_histogram(uint32_t *drawing, int height, int histogram[256], uint32_t color_map[256], int max){ + int i, j, val; + FOR_INV(i, 256) + { + val = height-histogram[i]*(height-1)/max; + for(j=height; j!=val; j--) drawing[j*256+i]=color_map[i]; + drawing[val*256+i]=255<<24; + FOR_INV(j, val) drawing[j*256+i]=0; + } +} + +static gboolean update_histogram_cb(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar){ + int i, j, x, y; + double sx, sy; + int histogram[256]={0}, histogram1[256]={0}, histogram2[256]={0}, hist_max=0, max1=0, max2=0; + char text[64]; + struct timeval timer; + + CLEAR(timer); + gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL); + cairo_surface_get_device_scale(histogram_surface, &sx, &sy); + + x*=sx; + y*=sy; + + switch (channel->format){ + case 'Y800': + switch (channel->type){ + case 'UIN8': + FOR(i, channel->size) histogram[channel->uchars[i]]++; + FOR(i, 256) hist_max=MAX(histogram[i], hist_max); + + FOR(i, 256) + { + FOR_INV(j, histogram[i]*255/hist_max) histogram_data[(255-j)*256+i]=color_map[i]; + histogram_data[(255-histogram[i]*255/hist_max)*256+i]=255<<24; + FOR_INV(j, 255-histogram[i]*255/hist_max) histogram_data[j*256+i]=0; + } + if (y>=0 && y<256 && x >=0 && x<256) + { + SPRINTF(text, "Y[%d]=%f.2%%", x, histogram[x]*100/(float)channel->size); + gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); + } + break; + case 'FL32': + FOR(i, channel->total_length) histogram[(int)CLIP_UCHAR(((channel->floats[i]-min)/(max-min)*256+0.5))]++; + FOR(i, 256) hist_max=MAX(histogram[i], hist_max); + FOR(i, 256) + { + FOR_INV(j, histogram[i]*255/hist_max) histogram_data[(255-j)*256+i]=color_map[i]; + histogram_data[(255-histogram[i]*255/hist_max)*256+i]=255<<24; + FOR_INV(j, 255-histogram[i]*255/hist_max) histogram_data[j*256+i]=0; + } + if (y>=0 && y<256 && x >=0 && x<256) + { + SPRINTF(text, "Y[%f]=%f.2%%", x*(max-min-0.5)/256+min, histogram[x]*100/(float)channel->total_length); + gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); + } + break; + default: EXIT_ON_ARRAY_ERROR( channel, "Type not managed for format 'Y800'. Only 'UIN8' is"); + } + break; + case 'RGB3': + FOR_INV(i, channel->size/3){ + histogram[channel->uchars[i*3]]++; + histogram1[channel->uchars[i*3+1]]++; + histogram2[channel->uchars[i*3+2]]++; + } + + FOR_INV(i, 256) + { + hist_max=MAX(histogram[i], hist_max); + max1=MAX(histogram1[i], max1); + max2=MAX(histogram2[i], max2); + } + draw_histogram(histogram_data, 85, histogram, r_colors, hist_max); + draw_histogram(histogram_data+256*85, 85, histogram1, g_colors, max1); + draw_histogram(histogram_data+256*170, 85, histogram2, b_colors, max2); + + if (y>=0 && y<256 && x >=0 && x<256) + { + if (y<85) SPRINTF(text, "R[%d]=%f.2%%", x, histogram[x]*100*2/(float)channel->size); + else if (y<170) SPRINTF(text, "G[%d]=%.2f%%", x, histogram1[x]*100*4/(float)channel->size); + else SPRINTF(text, "B[%d]=%.2f%%", x, histogram2[x]*100*4/(float)channel->size); + gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); + } + + break; + case 'YUYV': + for(i=channel->size-2;i!=-1;i-=2) histogram[channel->uchars[i]]++; + for(i=channel->size-1;i!=-2;i-=4) histogram1[channel->uchars[i]]++; + for(i=channel->size-3;i!=-4;i-=4) histogram2[channel->uchars[i]]++; + + FOR_INV(i, 256) + { + hist_max=MAX(histogram[i], hist_max); + max1=MAX(histogram1[i], max1); + max2=MAX(histogram2[i], max2); + } + + draw_histogram(histogram_data, 127, histogram, gray_colors, hist_max); + draw_histogram(histogram_data+256*128, 63, histogram1, u_colors, max1); + draw_histogram(histogram_data+256*192, 63, histogram2, v_colors, max2); + + if (y>=0 && y<256 && x >=0 && x<256) + { + if (y<128) SPRINTF(text, "Y[%d]=%f.2%%", x, histogram[x]*100*2/(float)channel->size); + else if (y<192) SPRINTF(text, "U[%d]=%.2f%%", x, histogram1[x]*100*4/(float)channel->size); + else SPRINTF(text, "V[%d]=%.2f%%", x, histogram2[x]*100*4/(float)channel->size); + gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); + } + break; + case 'yuv2': + for(i=channel->size-1;i!=-1;i-=2) histogram[channel->uchars[i]]++; + for(i=channel->size-2;i!=-2;i-=4) histogram1[channel->uchars[i]]++; + for(i=channel->size-4;i!=-4;i-=4) histogram2[channel->uchars[i]]++; + + FOR_INV(i, 256) + { + hist_max=MAX(histogram[i], hist_max); + max1=MAX(histogram1[i], max1); + max2=MAX(histogram2[i], max2); + } + + draw_histogram(histogram_data, 127, histogram, gray_colors, hist_max); + draw_histogram(histogram_data+256*128, 63, histogram1, u_colors, max1); + draw_histogram(histogram_data+256*192, 63, histogram2, v_colors, max2); + + if (y>=0 && y<256 && x >=0 && x<256) + { + if (y<128) SPRINTF(text, "Y[%d]=%f.2%%", x, histogram[x]*100*2/(float)channel->size); + else if (y<192) SPRINTF(text, "U[%d]=%.2f%%", x, histogram1[x]*100*4/(float)channel->size); + else SPRINTF(text, "V[%d]=%.2f%%", x, histogram2[x]*100*4/(float)channel->size); + gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); + + } + break; + + default: + gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, "No histogram for this format. Only Y800,RGB3 or yuv2."); + + } + gtk_image_set_from_surface(image, histogram_surface); + return G_SOURCE_CONTINUE; +} + + +static void histogram_resize_cb(GtkWidget *widget, GdkRectangle *allocation, gpointer user_data) +{ + (void) widget; + (void) user_data; + cairo_surface_set_device_scale(histogram_surface, (double)256/(double)allocation->width, (double)256/(double)allocation->height); +} + +void histogram_cb(GtkToolButton *toolbutton, gpointer pointer_statusbar ) +{ + char text[NAME_MAX]; + GtkWidget *legend_box, *label; + + if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(toolbutton))) + { + histogram_data=MANY_ALLOCATIONS(256*256, uint32_t); + histogram_surface=cairo_image_surface_create_for_data ((uchar*)histogram_data, CAIRO_FORMAT_ARGB32, 256, 256, 256*4); + histogram_image=gtk_image_new_from_surface(histogram_surface); + histogram_scrolled_window=gtk_scrolled_window_new(NULL, NULL); + histogram=gtk_box_new(GTK_ORIENTATION_VERTICAL, 1); + legend_box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1); + gtk_container_add(GTK_CONTAINER(histogram_scrolled_window), histogram_image); + gtk_container_add(GTK_CONTAINER(histogram), histogram_scrolled_window); + gtk_container_add(GTK_CONTAINER(histogram), legend_box); + + SPRINTF(text, "%f", min); + label=gtk_label_new(text); + gtk_box_pack_start(GTK_BOX(legend_box), label, FALSE, FALSE, 0); + SPRINTF(text, "%f", max); + label=gtk_label_new(text); + gtk_box_pack_end(GTK_BOX(legend_box), label, FALSE, FALSE, 0); + + if (legend) + { + gtk_container_remove(GTK_CONTAINER(paned), legend); + // gtk_widget_destroy(legend); + legend=NULL; + } + gtk_paned_add2(GTK_PANED(paned), histogram); + gtk_widget_set_vexpand(histogram_image, TRUE); + gtk_paned_set_position(GTK_PANED(paned), gtk_widget_get_allocated_height(paned)-256); + gtk_widget_show_all(paned); + g_signal_connect(G_OBJECT(histogram_scrolled_window), "size-allocate", G_CALLBACK(histogram_resize_cb), NULL); + histogram_tick_id = gtk_widget_add_tick_callback(GTK_WIDGET(histogram_image), (GtkTickCallback) update_histogram_cb, pointer_statusbar, NULL); + } + else + { + gtk_widget_remove_tick_callback(GTK_WIDGET(histogram_image), histogram_tick_id); + gtk_container_remove(GTK_CONTAINER(paned), histogram); + FREE(histogram_data); + // gtk_widget_destroy(histogram); + histogram=NULL; + } +} diff --git a/o_gtk_image/src/image_display.cpp b/o_gtk_image/src/image_display.cpp index 677338f742a59d1e519bfd63bd033a7094392e7b..f06427bb2f5850ae10fea394a9e5b46af62be39c 100644 --- a/o_gtk_image/src/image_display.cpp +++ b/o_gtk_image/src/image_display.cpp @@ -1,7 +1,5 @@ -#include "image_display.hpp" - +#include "common.h" #include "blgtk.h" -#include "o_gtk_image.hpp" #include <fcntl.h> // O_RDONLY ... #include <stdio.h> @@ -22,10 +20,7 @@ uint32_t v_colors[256]; uint32_t r_colors[256]; uint32_t g_colors[256]; uint32_t b_colors[256]; - uint32_t *color_map; -uchar min=0; -uchar max=255; int iterations=0; int colors_initilized = 0; @@ -33,28 +28,26 @@ int colors_initilized = 0; int mouse_image_x, mouse_image_y; cairo_surface_t *legend_surface, *image_surface; -guint histogram_tick_id; gulong pointer_value_handler; -uint32_t *histogram_data=NULL; -GtkWidget *histogram_image, *histogram, *histogram_scrolled_window; -cairo_surface_t *histogram_surface; GtkWidget *paned; static uint32_t *RGBA_from_YUYV = NULL; static GtkWidget *vbox, *scrolled_window, *event_box, *toolbar, *general_statusbar; static GtkToggleToolButton *zoom_button, *false_colors_button, *histogram_button; -static GtkWidget *image, *legend=NULL; +GtkWidget *image; + static uchar *image_buffer; -pthread_t init_table_thread; +static pthread_t init_table_thread; double zoom_in_factor=2, zoom_out_factor=0.5; +GtkWidget *legend=NULL; + static int width=0, height=0; -static blc_channel *channel; +blc_channel *channel=NULL; static int g_source_continue=G_SOURCE_CONTINUE; -static int g_source_remove_pt=G_SOURCE_REMOVE; #define SWAP_RGBA_TO_CAIRO_ARGB32(x) ((((x) & 0x000000FF) << 16) | (((x) & 0x00FF0000) >> 16) | ((x) & 0xFF00FF00) ) @@ -70,7 +63,6 @@ static void toggle_fullscreen(GtkWidget *widget, GdkEventWindowState *event, gpo } } - void* create_RGBA_from_YUYV(void *widget) { int Y, Cb, Cr; @@ -79,11 +71,9 @@ void* create_RGBA_from_YUYV(void *widget) static uchar R[256], B; (void)widget; - if (RGBA_from_YUYV == NULL) - { + if (RGBA_from_YUYV == NULL){ RGBA_from_YUYV= MANY_ALLOCATIONS(256*256*256, uint32_t); - FOR_INV(Y, 256) - { + 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) { @@ -149,16 +139,20 @@ static void init_color_maps(){ /** Gtk cannot display a black and white image, therefore we convert it before updating it*/ gboolean update_Y800_image(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar) { - int i, x, y, j, ret=-1; + float gain; + int i, x, y, j; double sx, sy; uint32_t *values; char text[64]; - if (blc_command_loop_start()){; - + gain=1/(max-min); + + if (blc_command_loop_start()){ values = (uint32_t*)image_buffer; - if (channel->type=='UIN8') FOR_INV(i, channel->size) values[i]=color_map[channel->uchars[i]]; - else if (channel->type=='FL32') FOR_INV(i, channel->size/sizeof(float)) values[i]=color_map[CLIP_UCHAR(channel->floats[i]*256-0.5f)]; + if (channel->type=='UIN8') + FOR(i, channel->size) values[i]=color_map[channel->uchars[i]]; + else if (channel->type=='FL32') + FOR(i, channel->total_length) values[i]=color_map[CLIP_UCHAR((channel->floats[i]-min)*256*gain-0.5f)]; else EXIT_ON_ARRAY_ERROR(channel, "Type not managed"); gtk_image_set_from_surface(image, image_surface); @@ -166,18 +160,15 @@ gboolean update_Y800_image(GtkImage *image, GdkFrameClock *, gpointer pointer_st cairo_surface_get_device_scale(image_surface, &sx, &sy); i=x*sx; j=y*sy; - if (i<width && j<height && i>=0 && j>=0) - { + if (i<width && j<height && i>=0 && j>=0){ if (channel->type=='UIN8') SPRINTF(text, "%4d,%4d: Y:%3d", i,j, channel->uchars[i+j*width]); else if (channel->type=='FL32') SPRINTF(text, "%4d,%4d: Y:%.3f", i,j, channel->floats[i+j*width]); - gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); } iterations++; blc_command_loop_end(); - return G_SOURCE_CONTINUE; - } else exit(EXIT_SUCCESS); + return G_SOURCE_CONTINUE; } gboolean update_RGB3_image(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar) @@ -187,45 +178,43 @@ gboolean update_RGB3_image(GtkImage *image, GdkFrameClock *, gpointer pointer_st int x, y, i=0, j=0; int R, G, B; - if (blc_command_loop_start()==0) exit(0); - - - gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL); - cairo_surface_get_device_scale(image_surface, &sx, &sy); - - while(i!=channel->size) - { - image_buffer[j++]=channel->uchars[i+2]; - image_buffer[j++]=channel->uchars[i+1]; - image_buffer[j++]=channel->uchars[i]; - j++; - i+=3; - } - - i=x*sx; - j=y*sy; - - if (i<width && j<height && i>=0 && j>=0) - { - if (mouse_channel.fd!=-1) - { - mouse_channel.uints32[0]=i; - mouse_channel.uints32[1]=j; - gdk_device_get_state(pointer_device, gtk_widget_get_window(GTK_WIDGET(image)), NULL, (GdkModifierType*)(&mouse_channel.uints32[2])); + if (blc_command_loop_start()){ + gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL); + cairo_surface_get_device_scale(image_surface, &sx, &sy); + + while(i!=channel->size){ + image_buffer[j++]=channel->uchars[i+2]; + image_buffer[j++]=channel->uchars[i+1]; + image_buffer[j++]=channel->uchars[i]; + j++; + i+=3; } - R=channel->uchars[i*4+j*width*3]; - G=channel->uchars[i*4+j*width*3+1]; - B=channel->uchars[i*4+j*width*3+2]; - SPRINTF(text, "%4d,%4d : R:%3d,G:%3d,B:%3d", i, j, R, G, B); + i=x*sx; + j=y*sy; - gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); + if (i<width && j<height && i>=0 && j>=0){ + if (mouse_channel.fd!=-1) + { + mouse_channel.uints32[0]=i; + mouse_channel.uints32[1]=j; + gdk_device_get_state(pointer_device, gtk_widget_get_window(GTK_WIDGET(image)), NULL, (GdkModifierType*)(&mouse_channel.uints32[2])); + } + + R=channel->uchars[i*4+j*width*3]; + G=channel->uchars[i*4+j*width*3+1]; + B=channel->uchars[i*4+j*width*3+2]; + SPRINTF(text, "%4d,%4d : R:%3d,G:%3d,B:%3d", i, j, R, G, B); + + gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); + } + gtk_image_set_from_surface(image, image_surface); + iterations++; + blc_command_loop_end(); } - gtk_image_set_from_surface(image, image_surface); - iterations++; - blc_command_loop_end(); - + else exit (EXIT_SUCCESS); return G_SOURCE_CONTINUE; + } gboolean update_RGBA_image(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar) @@ -245,10 +234,8 @@ gboolean update_RGBA_image(GtkImage *image, GdkFrameClock *, gpointer pointer_st i=x*sx; j=y*sy; - if (i<width && j<height && i>=0 && j>=0) - { - if (mouse_channel.fd!=-1) - { + if (i<width && j<height && i>=0 && j>=0){ + if (mouse_channel.fd!=-1){ mouse_channel.uints32[0]=i; mouse_channel.uints32[1]=j; gdk_device_get_state(pointer_device, gtk_widget_get_window(GTK_WIDGET(image)), NULL, (GdkModifierType*)(&mouse_channel.uints32[2])); @@ -425,141 +412,7 @@ gboolean update_yuv2_image(GtkImage *image, GdkFrameClock *, gpointer pointer_st return G_SOURCE_CONTINUE; } -static void draw_histogram(uint32_t *drawing, int height, int histogram[256], uint32_t color_map[256], int max) -{ - int i, j, val; - FOR_INV(i, 256) - { - val = height-histogram[i]*(height-1)/max; - for(j=height; j!=val; j--) drawing[j*256+i]=color_map[i]; - drawing[val*256+i]=255<<24; - FOR_INV(j, val) drawing[j*256+i]=0; - } -} -gboolean update_histogram_cb(GtkImage *image, GdkFrameClock *, gpointer pointer_statusbar){ - int i, j, x, y; - - double sx, sy; - int histogram[256]={0}, histogram1[256]={0}, histogram2[256]={0}, max=0, max1=0, max2=0; - char text[64]; - struct timeval timer; - - CLEAR(timer); - gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(image)), pointer_device, &x, &y, NULL); - cairo_surface_get_device_scale(histogram_surface, &sx, &sy); - - x*=sx; - y*=sy; - - - - switch (channel->format){ - case 'Y800': - FOR_INV(i, channel->size) histogram[channel->uchars[i]]++; - FOR_INV(i, 256) max=MAX(histogram[i], max); - - FOR_INV(i, 256) - { - FOR_INV(j, histogram[i]*255/max) histogram_data[(255-j)*256+i]=color_map[i]; - histogram_data[(255-histogram[i]*255/max)*256+i]=255<<24; - FOR_INV(j, 255-histogram[i]*255/max) histogram_data[j*256+i]=0; - } - if (y>=0 && y<256 && x >=0 && x<256) - { - SPRINTF(text, "Y[%d]=%f.2%%", x, histogram[x]*100/(float)channel->size); - gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); - } - break; - case 'RGB3': - FOR_INV(i, channel->size/3){ - histogram[channel->uchars[i*3]]++; - histogram1[channel->uchars[i*3+1]]++; - histogram2[channel->uchars[i*3+2]]++; - } - - FOR_INV(i, 256) - { - max=MAX(histogram[i], max); - max1=MAX(histogram1[i], max1); - max2=MAX(histogram2[i], max2); - } - draw_histogram(histogram_data, 85, histogram, r_colors, max); - draw_histogram(histogram_data+256*85, 85, histogram1, g_colors, max1); - draw_histogram(histogram_data+256*170, 85, histogram2, b_colors, max2); - - if (y>=0 && y<256 && x >=0 && x<256) - { - if (y<85) SPRINTF(text, "R[%d]=%f.2%%", x, histogram[x]*100*2/(float)channel->size); - else if (y<170) SPRINTF(text, "G[%d]=%.2f%%", x, histogram1[x]*100*4/(float)channel->size); - else SPRINTF(text, "B[%d]=%.2f%%", x, histogram2[x]*100*4/(float)channel->size); - gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); - } - - break; - case 'YUYV': - for(i=channel->size-2;i!=-1;i-=2) histogram[channel->uchars[i]]++; - for(i=channel->size-1;i!=-2;i-=4) histogram1[channel->uchars[i]]++; - for(i=channel->size-3;i!=-4;i-=4) histogram2[channel->uchars[i]]++; - - FOR_INV(i, 256) - { - max=MAX(histogram[i], max); - max1=MAX(histogram1[i], max1); - max2=MAX(histogram2[i], max2); - } - - draw_histogram(histogram_data, 127, histogram, gray_colors, max); - draw_histogram(histogram_data+256*128, 63, histogram1, u_colors, max1); - draw_histogram(histogram_data+256*192, 63, histogram2, v_colors, max2); - - if (y>=0 && y<256 && x >=0 && x<256) - { - if (y<128) SPRINTF(text, "Y[%d]=%f.2%%", x, histogram[x]*100*2/(float)channel->size); - else if (y<192) SPRINTF(text, "U[%d]=%.2f%%", x, histogram1[x]*100*4/(float)channel->size); - else SPRINTF(text, "V[%d]=%.2f%%", x, histogram2[x]*100*4/(float)channel->size); - gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); - - } - - - break; - case 'yuv2': - for(i=channel->size-1;i!=-1;i-=2) histogram[channel->uchars[i]]++; - for(i=channel->size-2;i!=-2;i-=4) histogram1[channel->uchars[i]]++; - for(i=channel->size-4;i!=-4;i-=4) histogram2[channel->uchars[i]]++; - - FOR_INV(i, 256) - { - max=MAX(histogram[i], max); - max1=MAX(histogram1[i], max1); - max2=MAX(histogram2[i], max2); - } - - draw_histogram(histogram_data, 127, histogram, gray_colors, max); - draw_histogram(histogram_data+256*128, 63, histogram1, u_colors, max1); - draw_histogram(histogram_data+256*192, 63, histogram2, v_colors, max2); - - if (y>=0 && y<256 && x >=0 && x<256) - { - if (y<128) SPRINTF(text, "Y[%d]=%f.2%%", x, histogram[x]*100*2/(float)channel->size); - else if (y<192) SPRINTF(text, "U[%d]=%.2f%%", x, histogram1[x]*100*4/(float)channel->size); - else SPRINTF(text, "V[%d]=%.2f%%", x, histogram2[x]*100*4/(float)channel->size); - gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text); - - } - break; - - default: - gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, "No histogram for this format. Only Y800,RGB3 or yuv2."); - - } - gtk_image_set_from_surface(image, histogram_surface); - - // fprintf(stderr, "Hist delai %ldµs\n", us_time_diff(&timer)); - - return G_SOURCE_CONTINUE; -} static void gtk_image_resize_cb(GtkWidget *image, GdkRectangle *allocation, gpointer user_data) { @@ -570,12 +423,7 @@ static void gtk_image_resize_cb(GtkWidget *image, GdkRectangle *allocation, gpo if (legend) cairo_surface_set_device_scale(legend_surface, 256/(double)allocation->width, 1/(double)allocation->height); } -static void histogram_resize_cb(GtkWidget *widget, GdkRectangle *allocation, gpointer user_data) -{ - (void) widget; - (void) user_data; - cairo_surface_set_device_scale(histogram_surface, (double)256/(double)allocation->width, (double)256/(double)allocation->height); -} + static void zoom_original_cb(GtkToolButton *, gpointer) { @@ -599,52 +447,6 @@ static void zoom_cb(GtkToolButton *toolbutton, double *factor) cairo_surface_set_device_scale(image_surface, sx*(*factor), sy*(*factor)); } -static void histogram_cb(GtkToolButton *toolbutton, gpointer pointer_statusbar ) -{ - char text[NAME_MAX]; - GtkWidget *legend_box, *label; - - if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(toolbutton))) - { - histogram_data=MANY_ALLOCATIONS(256*256, uint32_t); - histogram_surface=cairo_image_surface_create_for_data ((uchar*)histogram_data, CAIRO_FORMAT_ARGB32, 256, 256, 256*4); - histogram_image=gtk_image_new_from_surface(histogram_surface); - histogram_scrolled_window=gtk_scrolled_window_new(NULL, NULL); - histogram=gtk_box_new(GTK_ORIENTATION_VERTICAL, 1); - legend_box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1); - gtk_container_add(GTK_CONTAINER(histogram_scrolled_window), histogram_image); - gtk_container_add(GTK_CONTAINER(histogram), histogram_scrolled_window); - gtk_container_add(GTK_CONTAINER(histogram), legend_box); - - SPRINTF(text, "%d", min); - label=gtk_label_new(text); - gtk_box_pack_start(GTK_BOX(legend_box), label, FALSE, FALSE, 0); - SPRINTF(text, "%d", max); - label=gtk_label_new(text); - gtk_box_pack_end(GTK_BOX(legend_box), label, FALSE, FALSE, 0); - - if (legend) - { - gtk_container_remove(GTK_CONTAINER(paned), legend); - // gtk_widget_destroy(legend); - legend=NULL; - } - gtk_paned_add2(GTK_PANED(paned), histogram); - gtk_widget_set_vexpand(histogram_image, TRUE); - gtk_paned_set_position(GTK_PANED(paned), gtk_widget_get_allocated_height(paned)-256); - gtk_widget_show_all(paned); - g_signal_connect(G_OBJECT(histogram_scrolled_window), "size-allocate", G_CALLBACK(histogram_resize_cb), NULL); - histogram_tick_id = gtk_widget_add_tick_callback(GTK_WIDGET(histogram_image), (GtkTickCallback) update_histogram_cb, pointer_statusbar, NULL); - } - else - { - gtk_widget_remove_tick_callback(GTK_WIDGET(histogram_image), histogram_tick_id); - gtk_container_remove(GTK_CONTAINER(paned), histogram); - FREE(histogram_data); - // gtk_widget_destroy(histogram); - histogram=NULL; - } -} static void false_color_cb(GtkToolButton *toolbutton, struct update_cb *){ GtkWidget *label, *legend_box, *legend_image; @@ -679,47 +481,6 @@ static void false_color_cb(GtkToolButton *toolbutton, struct update_cb *){ } } - - -void *refresh_RGB3_cb(void *) -{ - int ch=' '; - - while(ch!='q') - { - ch=fgetc(stdin); - switch (ch){ - - case '\n': case '.': gtk_widget_add_tick_callback(GTK_WIDGET(image), (GtkTickCallback) update_RGB3_image, &g_source_remove_pt, NULL); - - break; - case 'q': g_application_quit(G_APPLICATION(app)); break; - default:fprintf(stderr, "Unknown command '%c' code '%d'.\n", ch, ch); - } - } - return NULL; -} - -void *refresh_yuv2_cb(void *user_data) -{ - int ch=' '; - (void)user_data; - - while(ch!='q') - { - ch=fgetc(stdin); - switch (ch){ - - case '\n': case '.': gtk_widget_add_tick_callback(GTK_WIDGET(image), (GtkTickCallback) update_yuv2_image, &g_source_remove_pt, NULL); - - break; - case 'q': g_application_quit(G_APPLICATION(app)); break; - default:fprintf(stderr, "Unknown command '%c' code '%d'.\n", ch, ch); - } - } - return NULL; -} - int frame_rate(gpointer data) { char text[64]; @@ -745,7 +506,7 @@ GtkWidget *create_image_display(blc_channel *tmp_channel) blc_loop_try_add_posting_semaphore(channel->sem_ack_data); blc_loop_try_add_waiting_semaphore(channel->sem_new_data); - + blc_command_loop_init(0); switch (channel->format) { diff --git a/o_gtk_image/src/image_display.hpp b/o_gtk_image/src/image_display.hpp deleted file mode 100644 index e336842b85cbdbe421835184404285032036a502..0000000000000000000000000000000000000000 --- a/o_gtk_image/src/image_display.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef BYTE_DISPLAY_H -#define BYTE_DISPLAY_H - -#include <gtk/gtk.h> -#include <blc_channel.h> - - -GtkWidget *create_image_display(blc_channel *channel); - -#endif \ No newline at end of file diff --git a/o_gtk_image/src/o_gtk_image.cpp b/o_gtk_image/src/o_gtk_image.cpp index fe2fb72a0456ad00e44866a8d3351519109bf849..246c36a2e76a28e35d8c69d784a3d6d645e64cd1 100644 --- a/o_gtk_image/src/o_gtk_image.cpp +++ b/o_gtk_image/src/o_gtk_image.cpp @@ -1,4 +1,4 @@ -#include "o_gtk_image.hpp" +#include "common.h" #include <fcntl.h> // O_RDONLY ... #include <stdio.h> @@ -10,8 +10,7 @@ #include <errno.h> //errno #include "blc_core.h" #include "blc_program.h" - -#include "image_display.hpp" +float min, max; const char *channel_name, *fullscreen_option, *keyboard_mode; GtkWidget *window; @@ -43,7 +42,7 @@ void ask_quit() } void on_key_press(GtkWidget *widget, GdkEventKey *event){ - + char key; if (event->type == GDK_KEY_PRESS){ @@ -53,10 +52,8 @@ void on_key_press(GtkWidget *widget, GdkEventKey *event){ } } - void activate_cb(GApplication *app) { - char tmp_title[NAME_MAX*2+1]; GtkWidget *display=NULL; GtkWidget *grid; @@ -65,19 +62,18 @@ void activate_cb(GApplication *app) pointer_device = gdk_device_manager_get_client_pointer (device_manager); window=gtk_application_window_new(GTK_APPLICATION(app)); - SPRINTF(tmp_title, "%s", blc_program_name); - gtk_window_set_title(GTK_WINDOW(window), tmp_title); + gtk_window_set_title(GTK_WINDOW(window), input.name); grid=gtk_grid_new(); - // for(i=0; input_names[i]; i++){ This is for displaying multiple images - // input=new blc_channel(/*input_names[i]*/ input_name, BLC_CHANNEL_READ); - display=create_image_display(&input); - if (display==NULL) EXIT_ON_CHANNEL_ERROR(&input, "Format not managed."); - gtk_widget_set_hexpand(display, 1); - gtk_widget_set_vexpand(display, 1); - gtk_container_add(GTK_CONTAINER(grid), display); - // } + // for(i=0; input_names[i]; i++){ This is for displaying multiple images + // input=new blc_channel(/*input_names[i]*/ input_name, BLC_CHANNEL_READ); + display=create_image_display(&input); + if (display==NULL) EXIT_ON_CHANNEL_ERROR(&input, "Format not managed."); + gtk_widget_set_hexpand(display, 1); + gtk_widget_set_vexpand(display, 1); + gtk_container_add(GTK_CONTAINER(grid), display); + // } gtk_container_add(GTK_CONTAINER(window), grid); gtk_widget_show_all(window); if (keyboard_mode) g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK (on_key_press), NULL); @@ -90,24 +86,37 @@ void activate_cb(GApplication *app) int main(int argc, char *argv[]) { int status=0; - char const *g_debug, *mouse_name; + char const *g_debug, *mouse_name, *min_str, *max_str; blc_channel channel_info; blc_program_set_description("Display the content of the blc_channel depending on its type on format"); blc_program_add_option(&keyboard_mode, 'k', "keyboard", NULL, "Send keyboard input to stdout", NULL); - blc_program_add_option(&mouse_name, 'm', "mouse", "blc_channel-out", "return the mouse coordinates and status in the channel", NULL); + blc_program_add_option(&min_str, 'm', "min", "FL32", "minimal value", NULL); + blc_program_add_option(&max_str, 'M', "max", "FL32", "maximal value", NULL); + // blc_program_add_option(&mouse_name, 'm', "mouse", "blc_channel-out", "return the mouse coordinates and status in the channel", NULL); blc_program_add_option(&fullscreen_option, 'F', "fullscreen", NULL, "Set the window in fullscreen", NULL); blc_program_add_option(&g_debug, ' ', "g-fatal-warnings", NULL, "Debug gtk.", NULL); - // This function is not yer operaiotnal blc_program_add_multiple_parameters(&input_names, "blc_channel", 1, "channel name you want to display"); + // This function is not yer operaiotnal blc_program_add_multiple_parameters(&input_names, "blc_channel", 1, "channel name you want to display"); blc_program_add_parameter(&input_name, "blc_channel-in", 1, "channel name you want to display", NULL); blc_program_init(&argc, &argv, ask_quit); input.open(input_name, mode); - /* - while (sem_trywait(input.sem_ack_data)==0); - while (sem_trywait(input.sem_new_data)==0); -*/ + + min=0; + if (input.type=='UIN8') max=256; + if (input.type=='INT8'){ + min=-128; + max=128; + } + + + if (input.type=='FL32' && input.format=='Y800'){ + if (min_str) SSCANF(1, min_str, "%f", &min); + else min=0; + if (max_str) SSCANF(1, max_str, "%f", &max); + else max=1; + }else if (min_str || max_str) EXIT_ON_ARRAY_ERROR(&input, "Min (-m) and max (-M) have only effect for type FL32 format Y800"); gtk_disable_setlocale(); gtk_init(&argc, &argv); @@ -116,6 +125,6 @@ int main(int argc, char *argv[]) status = g_application_run(G_APPLICATION(app), 0, NULL); g_object_unref(app); - return (status); + return EXIT_SUCCESS; } diff --git a/o_gtk_image/src/o_gtk_image.hpp b/o_gtk_image/src/o_gtk_image.hpp deleted file mode 100644 index bd41e8247f040b3cd58e7e64bcde5e67ebeee3ee..0000000000000000000000000000000000000000 --- a/o_gtk_image/src/o_gtk_image.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MAIN_HPP -#define MAIN_HPP - -#include <gtk/gtk.h> -#include <blc_channel.h> - -extern GtkWidget *window; -extern GdkDisplay *main_display; -extern GdkDevice *pointer_device; -extern GtkApplication *app; -extern blc_channel mouse_channel; - -extern int interactive_mode; -extern uint32_t format; -extern char const *fullscreen_option; - -void quit(); -#endif \ No newline at end of file