diff --git a/histogram.cc b/histogram.cc index 3eda5c0..d55e202 100644 --- a/histogram.cc +++ b/histogram.cc @@ -12,122 +12,99 @@ GtkWidget *histogram_da = NULL; -GdkPixbuf *histogram_pixbuf = NULL; -int *hist_minmax = NULL; // 2* hist_width min, max, min , max..... -int hist_width = 0; +int histogram[3][256]; // 6* hist_width min, max, min , max..... +int histogram_max; // max vlaue 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; + int clientw, clienth, px, py2; GdkRGBA color; + char txt[255]; 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; + if (histogram_max == 0) return; + + for (int chan = 0; chan < 3; chan++) { + switch (chan) { + case 0: + color.blue = 0.0; + color.red = 1.0; + color.green = 0.0; + color.alpha = 0.5; + break; + case 1: + color.blue = 0.0; + color.red = 0.0; + color.green = 1.0; + color.alpha = 0.5; + break; + case 2: + color.blue = 1.0; + color.red = 0.0; + color.green = 0.0; + color.alpha = 0.5; + break; + } 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 (int i = 0; i < 256; i++) { + px = 16 + ((clientw-32) * i) / 256; + py2 = (clienth-16) - ((clienth-32) * histogram[chan][i]) / histogram_max; - for (i = 0, x = 0; x < hist_width; x++) { + if (i == 0) cairo_move_to(cr, px, py2); + else cairo_line_to(cr, px, py2); - 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); + } - cairo_stroke(cr); + // draw some text + snprintf (txt, 255, "%d", histogram_max); + + 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; } - } - - // 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); - } + 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, txt); + cairo_stroke(cr); + } }; @@ -135,39 +112,26 @@ void cb_histogramda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da * test function */ void histogram_update(VideoFrame *vf) { - int i, x, y, min, max, v; + int chan, i, x, y; 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 (chan = 0; chan < 3; chan++) for (i = 0; i < 256; i++) + histogram[chan][i] = 0; 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; + for (chan = 0; chan < 3; chan++) { + histogram[chan][vf->data[3*(y*vf->w+x) + chan]]++; } - - 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); + + for (histogram_max = 0, chan = 0; chan < 3; chan++) for (i = 0; i < 256; i++) + if (histogram_max < histogram[chan][i]) histogram_max = histogram[chan][i]; };