Commit 11324484 authored by Arnaud Blanchard's avatar Arnaud Blanchard
Browse files

Modern version of blc

parent 539bc0b8
......@@ -6,7 +6,6 @@ project(c_gtk_image)
#This is to be able to debug and recompile automatically the libs (shared_blc). It is slower, you can remove this line and use : ${BLAR_BUILD_DIR}/lib/libblc.dylib instead of shared_blc
find_package(blc REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
find_package(JPEG REQUIRED)
......
#include "blc.h"
#include "network_display.h"
#include <string>
#include "Display.hpp"
using namespace std;
Tcp4ClientDisplay::Tcp4ClientDisplay(string const &address, string const &port):blc_array_tcp4_client(address, port){
}
gboolean refresh_screen_callback(GtkWidget *widget, GdkFrameClock *frame_clock, Tcp4ClientDisplay* client){
char text[64];
int x, y, i, j;
double x_scale, y_scale;
if (blc_command_loop_start()){
client->recv_data();
client->display->update();
return G_SOURCE_CONTINUE;
}
else exit(EXIT_SUCCESS);
}
#ifndef NETWORK_DISPLAY_H
#define NETWORK_DISPLAY_H
#include <gtk/gtk.h>
#include <blc_array_network.h>
#include "Display.hpp"
class Tcp4ClientDisplay:public blc_array_tcp4_client{
public:
Tcp4ClientDisplay(std::string const &address, std::string const &port);
std::unique_ptr<Display> display;
};
#endif
......@@ -27,7 +27,6 @@ public:
/** set pointer position (i, j) in the window. return false if the pointer is not in the window. */
bool get_pointer_position(int &i, int &j);
/** Display the new image with the content array.*/
virtual void update()=0;
......
#ifndef COMMON_H
#define COMMON_H
#include <gtk/gtk.h>
#include <blc.h>
#include <image_display.h>
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 *window, *paned;
extern GdkDevice *pointer_device;
extern blc_array mouse_array;
extern char const *fullscreen_option;
void histogram_cb(GtkToolButton *toolbutton, gpointer pointer_statusbar );
GtkWidget *create_image_display(blc_array *array);
#endif
#include "common.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;
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 (array->format){
case 'Y800':
switch (array->type){
case 'UIN8':
FOR(i, array->size) histogram[array->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)array->size);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
break;
case 'FL32':
FOR(i, array->total_length) histogram[(int)CLIP_UCHAR(((array->floats[i]-min_val)/(max_val-min_val)*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_val-min_val-0.5)/256+min_val, histogram[x]*100/(float)array->total_length);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
break;
default: EXIT_ON_ARRAY_ERROR( array, "Type not managed for format 'Y800'. Only 'UIN8' is");
}
break;
case 'RGB3':
FOR_INV(i, array->size/3){
histogram[array->uchars[i*3]]++;
histogram1[array->uchars[i*3+1]]++;
histogram2[array->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)array->size);
else if (y<170) SPRINTF(text, "G[%d]=%.2f%%", x, histogram1[x]*100*4/(float)array->size);
else SPRINTF(text, "B[%d]=%.2f%%", x, histogram2[x]*100*4/(float)array->size);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
break;
case 'YUYV':
for(i=array->size-2;i!=-1;i-=2) histogram[array->uchars[i]]++;
for(i=array->size-1;i!=-2;i-=4) histogram1[array->uchars[i]]++;
for(i=array->size-3;i!=-4;i-=4) histogram2[array->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)array->size);
else if (y<192) SPRINTF(text, "U[%d]=%.2f%%", x, histogram1[x]*100*4/(float)array->size);
else SPRINTF(text, "V[%d]=%.2f%%", x, histogram2[x]*100*4/(float)array->size);
gtk_statusbar_push(GTK_STATUSBAR(pointer_statusbar), 0, text);
}
break;
case 'yuv2':
for(i=array->size-1;i!=-1;i-=2) histogram[array->uchars[i]]++;
for(i=array->size-2;i!=-2;i-=4) histogram1[array->uchars[i]]++;
for(i=array->size-4;i!=-4;i-=4) histogram2[array->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)array->size);
else if (y<192) SPRINTF(text, "U[%d]=%.2f%%", x, histogram1[x]*100*4/(float)array->size);
else SPRINTF(text, "V[%d]=%.2f%%", x, histogram2[x]*100*4/(float)array->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;
}
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_val);
label=gtk_label_new(text);
gtk_box_pack_start(GTK_BOX(legend_box), label, FALSE, FALSE, 0);
SPRINTF(text, "%f", max_val);
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);
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;
}
}
This diff is collapsed.
#ifndef IMAGE_DISPLAY_H
#define IMAGE_DISPLAY_H
#include <gtk/gtk.h>
#include <blc_array.h>
GtkWidget *create_image_display(blc_array *array);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment