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
+
+ * image-overlay.c, image-overlay.h, layout_image.c: implement
+ histogramm in overlay.
+
Mon Jun 13 20:22:58 2005 John Ellis
* 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:
-
-
-
+
+
+
+
+
Keyboard
@@ -319,7 +321,23 @@ also available through the keyboard and
I
|
- Toggle information overlay for full screen.
+ Toggle information overlay for full screen: on with histogramm, on without histogramm, off.
+ |
+
+
+
+ K
+ |
+
+ Switch between the different histogramm modes: RGB, value, maximum value, red channel, green channel, blue channel.
+ |
+
+
+
+ L
+ |
+
+ Toogle between linear and logarithmical histogramm.
|
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) %s\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) %s\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;
}