/*************************************************************************************** * * histogram.cc is part of SimpleSkyCam. * *****************************************************************************************/ #include "simpleskycam.h" #include "histogram.h" #include "gui.h" #include "configuration.h" #include "video.h" GtkWidget *histogram_da = NULL; GdkPixbuf *histogram_pixbuf = NULL; int *hist_minmax = NULL; // 2* hist_width min, max, min , max..... int hist_width = 0; extern GtkBuilder *_builder_; // work around for threads #define S_X(_x_) (((_x_) * clientw / pixbufw)) #define S_Y(_y_) (((_y_) * clienth / pixbufh)) void cb_histogramda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) { int clientw, clienth, pixbufw, pixbufh; GdkRGBA color; if (histogram_da == NULL) // should only be called once histogram_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "histogram-da")); // // create or resize pixbuf if needed clienth = gtk_widget_get_allocated_height(histogram_da); clientw = gtk_widget_get_allocated_width(histogram_da); if (histogram_pixbuf == NULL) { histogram_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, clientw, clienth); memset (gdk_pixbuf_get_pixels(histogram_pixbuf), 0, 3 * gdk_pixbuf_get_height(histogram_pixbuf) * gdk_pixbuf_get_width(histogram_pixbuf)); } pixbufh = gdk_pixbuf_get_height(histogram_pixbuf); pixbufw = gdk_pixbuf_get_width(histogram_pixbuf); if (pixbufw != clientw || pixbufh != clienth) { g_object_unref(histogram_pixbuf); histogram_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, clientw, clienth); memset (gdk_pixbuf_get_pixels(histogram_pixbuf), 0, 3 * gdk_pixbuf_get_height(histogram_pixbuf) * gdk_pixbuf_get_width(histogram_pixbuf)); } // // put the drawing area on the screen gdk_cairo_set_source_pixbuf(cr, histogram_pixbuf, 0, 0); cairo_paint(cr); cairo_fill (cr); // // draw cross color.blue = 1.0; color.red = 0.0; color.green = 1.0; color.alpha = 1.0; gdk_cairo_set_source_rgba(cr, &color); cairo_move_to(cr, 0, 0); cairo_line_to(cr, pixbufw, pixbufh); cairo_move_to(cr, pixbufw, 0); cairo_line_to(cr, 0, pixbufh); cairo_stroke(cr); // // draw basic histogram if (hist_minmax != NULL) { // // draw cross color.blue = 0.75; color.red = 0.75; color.green = 0.75; color.alpha = 0.8; gdk_cairo_set_source_rgba(cr, &color); int x, i; // position in histogram int px, py1, py2; // screen pos x and line from to for (i = 0, x = 0; x < hist_width; x++) { px = (pixbufw * x) / hist_width; py1 = (pixbufh * hist_minmax[i++]) / 255; py2 = (pixbufh * hist_minmax[i++]) / 255; cairo_move_to(cr, px, py1); cairo_line_to(cr, px, py2); cairo_stroke(cr); } } // draw some text for (int i = 0; i < 5; i++) { int dx, dy; switch (i) { case 0: cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); dx = -1; dy = 0; break; case 1: dx = +1; dy = 0; break; case 2: dx = 0; dy = -1; break; case 3: dx = 0; dy = +1; break; case 4: cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); dx = 0; dy = 0; break; } cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 12); cairo_move_to (cr, 10+dx, 15+dy); cairo_show_text(cr, "Test"); cairo_stroke(cr); } }; /* * test function */ void histogram_update(VideoFrame *vf) { int i, x, y, min, max, v; if (vf == NULL) return; if (vf->w <= 0 ) return; if (hist_minmax == NULL ) { hist_minmax = (int*) malloc (2 * sizeof(int) * vf->w); hist_width = vf->w; } if (hist_width != vf->w) { free (hist_minmax); hist_minmax = (int*) malloc (2 * sizeof(int) * vf->w); hist_width = vf->w; } for (i = 0, x = 0; x < vf->w; x++) { for (y = 0; y < vf->h; y++) { v = (vf->data[3*y*vf->w+x + 0] + vf->data[3*y*vf->w+x + 1] + vf->data[3*y*vf->w+x + 2]) / 3; if (y == 0) { min = v; max = v; } if (v < min) min = v; if (v > max) max = v; } hist_minmax[i++] = min; hist_minmax[i++] = max; } if (histogram_da) gdk_window_invalidate_rect(gtk_widget_get_window(histogram_da), NULL, true); };