diff -r f6cec49c42ff -r afbc636fb5e1 ChangeLog
--- a/ChangeLog	Wed Sep 27 05:35:31 2006 +0000
+++ b/ChangeLog	Wed Sep 27 06:01:51 2006 +0000
@@ -1,3 +1,8 @@ Mon Jun 13 20:22:58 2005  John Ellis  <j
+Tue Sep 26 18:15:00 2006  Uwe Ohse <uwe@ohse.de>
+
+	* image-overlay.c, image-overlay.h, layout_image.c: implement 
+	  histogramm in overlay.
+
 Mon Jun 13 20:22:58 2005  John Ellis  <johne@verizon.net>
 
 	* image.c (image_zoom_cb): If needed, update window title when
diff -r f6cec49c42ff -r afbc636fb5e1 doc/8_2_fullscreen.html
--- a/doc/8_2_fullscreen.html	Wed Sep 27 05:35:31 2006 +0000
+++ b/doc/8_2_fullscreen.html	Wed Sep 27 06:01:51 2006 +0000
@@ -80,9 +80,11 @@ are available when in full screen, these
 are available when in full screen, these are the commands available:</P>
 <CENTER>
 	<TABLE WIDTH=80% BORDER=1 BORDERCOLOR="#cccccc" CELLPADDING=4 CELLSPACING=0 RULES=ROWS>
-		<COL WIDTH=85*>
-		<COL WIDTH=85*>
-		<COL WIDTH=85*>
+	        <COLGROUP>
+		<COL WIDTH=85*>
+		<COL WIDTH=85*>
+		<COL WIDTH=85*>
+	        </COLGROUP>
 		<TR VALIGN=TOP>
 			<TD WIDTH=33%>
 				<P ALIGN=CENTER><B>Keyboard</B></P>
@@ -319,7 +321,23 @@ also available through the keyboard and 
 				<P>I</P>
 			</TD>
 			<TD WIDTH=50%>
-				<P>Toggle information overlay for full screen.</P>
+				<P>Toggle information overlay for full screen: on with histogramm, on without histogramm, off.</P>
+			</TD>
+		</TR>
+		<TR VALIGN=TOP>
+			<TD WIDTH=50%>
+				<P>K</P>
+			</TD>
+			<TD WIDTH=50%>
+				<P>Switch between the different histogramm modes: RGB, value, maximum value, red channel, green channel, blue channel.</P>
+			</TD>
+		</TR>
+		<TR VALIGN=TOP>
+			<TD WIDTH=50%>
+				<P>L</P>
+			</TD>
+			<TD WIDTH=50%>
+				<P>Toogle between linear and logarithmical histogramm.</P>
 			</TD>
 		</TR>
 		<TR VALIGN=TOP>
diff -r f6cec49c42ff -r afbc636fb5e1 src/image-overlay.c
--- a/src/image-overlay.c	Wed Sep 27 05:35:31 2006 +0000
+++ b/src/image-overlay.c	Wed Sep 27 06:01:51 2006 +0000
@@ -19,6 +19,74 @@
 #include "layout.h"
 #include "pixbuf-renderer.h"
 #include "pixbuf_util.h"
+
+/*
+ *----------------------------------------------------------------------------
+ * image histogramm
+ *----------------------------------------------------------------------------
+ */
+
+/* cheap and dirty static variables, don't want to modify ImageWindow etc */
+static gint histogramm_on;
+
+#define HCHAN_R 0
+#define HCHAN_G 1
+#define HCHAN_B 2
+#define HCHAN_RGB 3
+#define HCHAN_VAL 4
+#define HCHAN_MAX 5
+#define HCHAN_COUNT (HCHAN_MAX+1)
+static gint histogramm_chan=HCHAN_RGB;
+
+/* 0: linear
+   1: log.
+ */
+static gint histogramm_logmode;
+
+void image_overlay_histogramm_onoff_toggle(gint x)
+{
+  histogramm_on=!!(x);
+}
+gint image_overlay_histogramm_onoff_status(void) { return histogramm_on;}
+
+void image_overlay_histogramm_chan_toggle(void)
+{ histogramm_chan=(histogramm_chan+1)%HCHAN_COUNT;}
+void image_overlay_histogramm_log_toggle(void)
+{ histogramm_logmode=!histogramm_logmode; }
+
+static gulong count_for_histmap(GdkPixbuf *imgpixbuf, gint chan, gulong *cnt)
+{
+  gint w, h, i, j, srs, has_alpha;
+  guchar * s_pix;
+
+  w = gdk_pixbuf_get_width(imgpixbuf);
+  h = gdk_pixbuf_get_height(imgpixbuf);
+  srs = gdk_pixbuf_get_rowstride(imgpixbuf);
+  s_pix = gdk_pixbuf_get_pixels(imgpixbuf);
+  has_alpha = gdk_pixbuf_get_has_alpha(imgpixbuf);
+
+  for (i = 0; i < 256*4; i++) cnt[i]=0;
+
+  for (i = 0; i < h; i++) {
+    guchar *sp = s_pix + (i * srs); /* 8bit */
+    for (j = 0; j < w; j++) {
+      cnt[*sp+0]+=sp[0];
+      cnt[*sp+256]+=sp[1];
+      cnt[*sp+512]+=sp[2];
+      if (chan==HCHAN_MAX) {
+	guchar t=sp[0];
+	if (sp[1]>t) t=sp[1];
+	if (sp[2]>t) t=sp[2];
+	cnt[*sp+768]+=t;
+      }
+      else
+	cnt[*sp+768]+=(sp[0]+sp[1]+sp[2])/3;
+      sp+=3;
+      if (has_alpha) sp++;
+    }
+  }
+  return w*h;
+}
 
 
 /*
@@ -54,6 +122,9 @@ static GdkPixbuf *image_overlay_info_ren
 	CollectionData *cd;
 	CollectInfo *info;
 	gchar *ct;
+	GdkPixbuf *imgpixbuf=NULL;
+	gulong histmap[256*4];
+	gulong total=0;
 
 	name = image_get_name(imd);
 	if (name)
@@ -124,6 +195,8 @@ static GdkPixbuf *image_overlay_info_ren
 	else
 		{
 		gint w, h;
+		const char *t1="";
+		const char *t2="";
 
 		if (imd->delay_flip &&
 		    imd->il && imd->il->pixbuf &&
@@ -131,16 +204,30 @@ static GdkPixbuf *image_overlay_info_ren
 			{
 			w = gdk_pixbuf_get_width(imd->il->pixbuf);
 			h = gdk_pixbuf_get_height(imd->il->pixbuf);
+			imgpixbuf = imd->il->pixbuf;
 			}
 		else
 			{
 			pixbuf_renderer_get_image_size(PIXBUF_RENDERER(imd->pr), &w, &h);
-			}
-
-		text = g_strdup_printf("%s(%d/%d) <b>%s</b>\n%d x %d - %s - %s", ct,
+			imgpixbuf = (PIXBUF_RENDERER(imd->pr))->pixbuf;
+			}
+		if (histogramm_on) {
+		  switch (histogramm_chan) {
+		  case HCHAN_R: t1="histogramm on red"; break;
+		  case HCHAN_G: t1="histogramm on green"; break;
+		  case HCHAN_B: t1="histogramm on blue"; break;
+		  case HCHAN_VAL: t1="histogramm on value"; break;
+		  case HCHAN_RGB: t1="histogramm on RGB"; break;
+		  case HCHAN_MAX: t1="histogramm on max value"; break;
+		  }
+		  t2=histogramm_logmode ? "\nlog " : "\nlinear ";
+		}
+
+		text = g_strdup_printf("%s(%d/%d) <b>%s</b>\n%d x %d - %s - %s%s%s", ct,
 				       n, t, name_escaped,
 				       w, h,
-				       text_from_time(imd->mtime), size);
+				       text_from_time(imd->mtime), size,
+				       t2,t1);
 		}
 	g_free(size);
 	g_free(ct);
@@ -154,6 +241,11 @@ static GdkPixbuf *image_overlay_info_ren
 
 	width += 10;
 	height += 10;
+	if (imgpixbuf && histogramm_on) {
+		total=count_for_histmap(imgpixbuf, histogramm_chan,histmap);
+		if (width<266) width=266;
+		height+=256;
+	}
 
 	pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
 	pixbuf_set_rect_fill(pixbuf, 3, 3, width-6, height-6, 240, 240, 240, 210);
@@ -164,6 +256,59 @@ static GdkPixbuf *image_overlay_info_ren
 	pixbuf_pixel_set(pixbuf, width - 1, 0, 0, 0, 0, 0);
 	pixbuf_pixel_set(pixbuf, 0, height - 1, 0, 0, 0, 0);
 	pixbuf_pixel_set(pixbuf, width - 1, height - 1, 0, 0, 0, 0);
+	if (imgpixbuf && histogramm_on) {
+	  gint i;
+	  gulong max=0;
+	  double logmax;
+	  for (i=0;i<1024;i++) {
+	    int flag=0;
+	    switch (histogramm_chan) {
+	    case HCHAN_RGB: if ((i%4)!=3) flag=1; break;
+	    case HCHAN_R: if ((i%4)==0) flag=1; break;
+	    case HCHAN_G: if ((i%4)==1) flag=1; break;
+	    case HCHAN_B: if ((i%4)==2) flag=1; break;
+	    case HCHAN_VAL: if ((i%4)==3) flag=1; break;
+	    case HCHAN_MAX: if ((i%4)==3) flag=1; break;
+	    }
+	    if (flag)
+	      if (histmap[i]>max) max=histmap[i];
+	  }
+	  logmax=log(max);
+	  for (i=0;i<256;i++) {
+	    gint j;
+	    glong v[4];
+	    v[0]=histmap[i+0*256]; // r
+	    v[1]=histmap[i+1*256]; // g
+	    v[2]=histmap[i+2*256]; // b
+	    v[3]=histmap[i+3*256]; // value, max
+	    for (j=0;j<4;j++) {
+	      gint r=0,g=0,b=0,a=0;
+	      gint max2=0;
+	      gint k;
+	      for (k=1;k<4;k++)
+		if (v[k]>v[max2]) max2=k;
+	      switch (max2) {
+	      case HCHAN_R: r=255; break;
+	      case HCHAN_G: g=255; break;
+	      case HCHAN_B: b=255; break;
+	      }
+
+	      if (histogramm_chan==HCHAN_MAX) {r=0;b=0;g=0;}
+	      if (histogramm_chan==HCHAN_VAL) {r=0;b=0;g=0;}
+	      gulong pt;
+	      if (histogramm_logmode)
+		pt=((float)log(v[max2]))/logmax*255;
+	      else
+		pt=((float)v[max2])/max*255;
+	      if (histogramm_chan>=HCHAN_RGB || max2==histogramm_chan)
+		pixbuf_draw_line(pixbuf, 
+		  0+5,height-255,256,256,
+		  i+5,height,i+5,height-pt, 
+		  r,g,b,255);
+	      v[max2]=-1;
+	    }
+	  }
+	}
 
 	pixbuf_draw_layout(pixbuf, layout, imd->pr, 5, 5, 0, 0, 0, 255);
 
diff -r f6cec49c42ff -r afbc636fb5e1 src/image-overlay.h
--- a/src/image-overlay.h	Wed Sep 27 05:35:31 2006 +0000
+++ b/src/image-overlay.h	Wed Sep 27 06:01:51 2006 +0000
@@ -17,8 +17,9 @@ void image_overlay_info_disable(ImageWin
 void image_overlay_info_disable(ImageWindow *imd, gint id);
 
 void image_overlay_update(ImageWindow *imd, gint id);
-
+void image_overlay_histogramm_onoff_toggle(gint);
+gint image_overlay_histogramm_onoff_status(void);
+void image_overlay_histogramm_chan_toggle(void);
+void image_overlay_histogramm_log_toggle(void);
 
 #endif
-
-
diff -r f6cec49c42ff -r afbc636fb5e1 src/layout_image.c
--- a/src/layout_image.c	Wed Sep 27 05:35:31 2006 +0000
+++ b/src/layout_image.c	Wed Sep 27 06:01:51 2006 +0000
@@ -221,7 +221,25 @@ static gint layout_image_full_screen_key
 			stop_signal = TRUE;
 			break;
 		case 'I': case 'i':
-			layout_image_overlay_set(lw, !(lw->full_screen_overlay_on));
+			if (lw->full_screen_overlay_on) {
+			  if (image_overlay_histogramm_onoff_status()) {
+			    image_overlay_histogramm_onoff_toggle(0);
+			    layout_image_overlay_update(lw);
+			  } else
+			    layout_image_overlay_set(lw, 0);
+			} else {
+			  layout_image_overlay_set(lw, 1);
+			  image_overlay_histogramm_onoff_toggle(1);
+			  layout_image_overlay_update(lw);
+			}
+			break;
+		case 'K': case 'k':
+			image_overlay_histogramm_chan_toggle();
+			layout_image_overlay_update(lw);
+			break;
+		case 'L': case 'l':
+			image_overlay_histogramm_log_toggle();
+			layout_image_overlay_update(lw);
 			break;
 		}
 
