Revision: 1390
          http://geeqie.svn.sourceforge.net/geeqie/?rev=1390&view=rev
Author:   nadvornik
Date:     2009-02-15 13:11:21 +0000 (Sun, 15 Feb 2009)

Log Message:
-----------
histogram caching
histogram interface prepared for histogram pane

Modified Paths:
--------------
    trunk/src/filedata.c
    trunk/src/histogram.c
    trunk/src/histogram.h
    trunk/src/image-overlay.c
    trunk/src/image.c
    trunk/src/main.c
    trunk/src/typedefs.h

Modified: trunk/src/filedata.c
===================================================================
--- trunk/src/filedata.c        2009-02-15 09:36:53 UTC (rev 1389)
+++ trunk/src/filedata.c        2009-02-15 13:11:21 UTC (rev 1390)
@@ -515,7 +515,8 @@
        g_free(fd->collate_key_name);
        g_free(fd->collate_key_name_nocase);
        if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf);
-
+       g_free(fd->histmap);
+       
        g_assert(fd->sidecar_files == NULL); /* sidecar files must be freed 
before calling this */
 
        file_data_change_info_free(NULL, fd);

Modified: trunk/src/histogram.c
===================================================================
--- trunk/src/histogram.c       2009-02-15 09:36:53 UTC (rev 1389)
+++ trunk/src/histogram.c       2009-02-15 13:11:21 UTC (rev 1390)
@@ -23,10 +23,22 @@
  *----------------------------------------------------------------------------
  */
 
-#define HISTOGRAM_SIZE 256
+#define HISTMAP_SIZE 256
+typedef enum {
+       HISTMAP_CHANNEL_R = 0,
+       HISTMAP_CHANNEL_G,
+       HISTMAP_CHANNEL_B,
+       HISTMAP_CHANNEL_AVG,
+       HISTMAP_CHANNEL_MAX,
+       HISTMAP_CHANNELS
+} HistMapChannels;
 
+struct _HistMap {
+       gulong histmap[HISTMAP_SIZE * HISTMAP_CHANNELS];
+       gulong area;
+};
+
 struct _Histogram {
-       gulong histmap[HISTOGRAM_SIZE*4];
        gint histogram_chan;
        gint histogram_logmode;
 };
@@ -104,83 +116,83 @@
        return t1;
 }
 
-gulong histogram_read(Histogram *histogram, GdkPixbuf *imgpixbuf)
+static HistMap *histmap_read(GdkPixbuf *imgpixbuf)
 {
        gint w, h, i, j, srs, has_alpha, step;
        guchar *s_pix;
 
-       if (!histogram) return 0;
-
+       HistMap *histmap;
+       
        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);
 
-       memset(histogram->histmap, 0, sizeof(histogram->histmap));
+       histmap = g_new0(HistMap, 1);
 
-       /* code duplication is here to speed up the calculation */
        step = 3 + !!(has_alpha);
-       if (histogram->histogram_chan == HCHAN_MAX)
+       for (i = 0; i < h; i++)
                {
-               for (i = 0; i < h; i++)
+               guchar *sp = s_pix + (i * srs); /* 8bit */
+               for (j = 0; j < w; j++)
                        {
-                       guchar *sp = s_pix + (i * srs); /* 8bit */
-                       for (j = 0; j < w; j++)
-                               {
-                               guchar t = sp[0];
-                               if (sp[1]>t) t = sp[1];
-                               if (sp[2]>t) t = sp[2];
+                       guint avg = (sp[0] + sp[1] + sp[2]) / 3;
+                       guint max = sp[0];
+                       if (sp[1] > max) max = sp[1];
+                       if (sp[2] > max) max = sp[2];
 
-                               histogram->histmap[sp[0] + 0 * 
HISTOGRAM_SIZE]++;
-                               histogram->histmap[sp[1] + 1 * 
HISTOGRAM_SIZE]++;
-                               histogram->histmap[sp[2] + 2 * 
HISTOGRAM_SIZE]++;
-                               histogram->histmap[t + 3 * HISTOGRAM_SIZE]++;
-                               sp += step;
-                               }
+                       histmap->histmap[sp[0] * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_R]++;
+                       histmap->histmap[sp[1] * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_G]++;
+                       histmap->histmap[sp[2] * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_B]++;
+                       histmap->histmap[avg   * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_AVG]++;
+                       histmap->histmap[max   * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_MAX]++;
+                       sp += step;
                        }
                }
-       else
+       histmap->area = w * h;
+       return histmap;
+}
+
+HistMap *histmap_get(FileData *fd)
+{
+       if (fd->histmap) return fd->histmap;
+       
+       if (fd->pixbuf) 
                {
-               for (i = 0; i < h; i++)
-                       {
-                       guchar *sp = s_pix + (i * srs); /* 8bit */
-                       for (j = 0; j < w; j++)
-                               {
-                               histogram->histmap[sp[0] + 0 * 
HISTOGRAM_SIZE]++;
-                               histogram->histmap[sp[1] + 1 * 
HISTOGRAM_SIZE]++;
-                               histogram->histmap[sp[2] + 2 * 
HISTOGRAM_SIZE]++;
-                               histogram->histmap[3 * HISTOGRAM_SIZE + 
(sp[0]+sp[1]+sp[2])/3]++;
-                               sp += step;
-                               }
-                       }
+               fd->histmap = histmap_read(fd->pixbuf);
+               return fd->histmap;
                }
-
-       return w*h;
+       return NULL;
 }
 
-gint histogram_draw(Histogram *histogram, GdkPixbuf *pixbuf, gint x, gint y, 
gint width, gint height)
+gint histogram_draw(Histogram *histogram, HistMap *histmap, GdkPixbuf *pixbuf, 
gint x, gint y, gint width, gint height)
 {
        /* FIXME: use the coordinates correctly */
        gint i;
        gulong max = 0;
        gdouble logmax;
 
-       if (!histogram) return 0;
+       if (!histogram || !histmap) return 0;
 
        for (i = 0; i < 1024; i++) {
+#if 0
+               /* this is probably broken for MAX or VAL mode */
                gint flag = 0;
 
                switch (histogram->histogram_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;
+                       case HCHAN_RGB: if ((i % HISTMAP_CHANNELS) < 3) flag = 
1; break;
+                       case HCHAN_R:   if ((i % HISTMAP_CHANNELS) == 
HISTMAP_CHANNEL_R) flag = 1; break;
+                       case HCHAN_G:   if ((i % HISTMAP_CHANNELS) == 
HISTMAP_CHANNEL_G) flag = 1; break;
+                       case HCHAN_B:   if ((i % HISTMAP_CHANNELS) == 
HISTMAP_CHANNEL_B) flag = 1; break;
+                       case HCHAN_VAL: if ((i % HISTMAP_CHANNELS) == 
HISTMAP_CHANNEL_AVG) flag = 1; break;
+                       case HCHAN_MAX: if ((i % HISTMAP_CHANNELS) == 
HISTMAP_CHANNEL_MAX) flag = 1; break;
                        }
-               if (flag && histogram->histmap[i] > max) max = 
histogram->histmap[i];
+               if (flag && histmap->histmap[i] > max) max = 
histmap->histmap[i];
+#else
+               if (histmap->histmap[i] > max) max = histmap->histmap[i];
+#endif
        }
 
        logmax = log(max);
@@ -191,16 +203,22 @@
                gint rplus = 0;
                gint gplus = 0;
                gint bplus = 0;
-               gint ii = i * HISTOGRAM_SIZE / width;
-               gint combine  = (HISTOGRAM_SIZE - 1) / width + 1;
+               gint ii = i * HISTMAP_SIZE / width;
+               gint combine  = (HISTMAP_SIZE - 1) / width + 1;
 
                for (j = 0; j < combine; j++)
                        {
-                       v[0] += histogram->histmap[ii + j + 0 * 
HISTOGRAM_SIZE]; // r
-                       v[1] += histogram->histmap[ii + j + 1 * 
HISTOGRAM_SIZE]; // g
-                       v[2] += histogram->histmap[ii + j + 2 * 
HISTOGRAM_SIZE]; // b
-                       v[3] += histogram->histmap[ii + j + 3 * 
HISTOGRAM_SIZE]; // value, max
+                       v[0] += histmap->histmap[(ii + j) * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_R]; // r
+                       v[1] += histmap->histmap[(ii + j) * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_G]; // g
+                       v[2] += histmap->histmap[(ii + j) * HISTMAP_CHANNELS + 
HISTMAP_CHANNEL_B]; // b
+                       v[3] += histmap->histmap[(ii + j) * HISTMAP_CHANNELS + 
+                               ((histogram->histogram_chan == HCHAN_VAL) ? 
HISTMAP_CHANNEL_AVG : HISTMAP_CHANNEL_MAX)]; // value, max
                        }
+                       
+               for (j = 0; j < 4; j++)
+                       {
+                       v[j] /= combine;
+                       }
 
                for (j = 0; j < 4; j++)
                        {
@@ -258,4 +276,14 @@
 
        return TRUE;
 }
+
+void histogram_notify_cb(FileData *fd, NotifyType type, gpointer data)
+{
+       if (type != NOTIFY_TYPE_INTERNAL && fd->histmap)
+               {
+               g_free(fd->histmap);
+               fd->histmap = NULL;
+               }
+}
+
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */

Modified: trunk/src/histogram.h
===================================================================
--- trunk/src/histogram.h       2009-02-15 09:36:53 UTC (rev 1389)
+++ trunk/src/histogram.h       2009-02-15 13:11:21 UTC (rev 1390)
@@ -30,8 +30,10 @@
 gint histogram_set_mode(Histogram *histogram, gint mode);
 gint histogram_get_mode(Histogram *histogram);
 const gchar *histogram_label(Histogram *histogram);
-gulong histogram_read(Histogram *histogram, GdkPixbuf *imgpixbuf);
-gint histogram_draw(Histogram *histogram, GdkPixbuf *pixbuf, gint x, gint y, 
gint width, gint height);
+HistMap *histmap_get(FileData *fd);
+gint histogram_draw(Histogram *histogram, HistMap *histmap, GdkPixbuf *pixbuf, 
gint x, gint y, gint width, gint height);
 
+void histogram_notify_cb(FileData *fd, NotifyType type, gpointer data);
+
 #endif /* HISTOGRAM_H */
 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */

Modified: trunk/src/image-overlay.c
===================================================================
--- trunk/src/image-overlay.c   2009-02-15 09:36:53 UTC (rev 1389)
+++ trunk/src/image-overlay.c   2009-02-15 13:11:21 UTC (rev 1390)
@@ -442,6 +442,7 @@
        gchar *text;
        GdkPixbuf *imgpixbuf = NULL;
        gboolean with_hist;
+       HistMap *histmap;
        ImageWindow *imd = osd->imd;
        FileData *fd = image_get_fd(imd);
 
@@ -553,8 +554,14 @@
                text = g_markup_escape_text(_("Untitled"), -1);
        }
 
-       with_hist = (imgpixbuf && (osd->show & OSD_SHOW_HISTOGRAM) && 
osd->histogram && (!imd->il || image_loader_get_is_done(imd->il)));
+       with_hist = ((osd->show & OSD_SHOW_HISTOGRAM) && osd->histogram);
+       if (with_hist)
+               {
+               histmap = histmap_get(imd->image_fd);
+               if (!histmap) with_hist = FALSE;
+               }
        
+       
        {
                gint active_marks = 0;
                gint mark;
@@ -611,7 +618,6 @@
 
        if (with_hist)
                {
-               histogram_read(osd->histogram, imgpixbuf);
                if (width < HISTOGRAM_WIDTH + 10) width = HISTOGRAM_WIDTH + 10;
                height += HISTOGRAM_HEIGHT + 5;
                }
@@ -649,7 +655,7 @@
                                xoffset += add+d;
                                }
                                                
-                       histogram_draw(osd->histogram, pixbuf, x, y, w, 
HISTOGRAM_HEIGHT);
+                       histogram_draw(osd->histogram, histmap, pixbuf, x, y, 
w, HISTOGRAM_HEIGHT);
                        }
                pixbuf_draw_layout(pixbuf, layout, imd->pr, 5, 5, 0, 0, 0, 255);
        }

Modified: trunk/src/image.c
===================================================================
--- trunk/src/image.c   2009-02-15 09:36:53 UTC (rev 1389)
+++ trunk/src/image.c   2009-02-15 13:11:21 UTC (rev 1390)
@@ -538,14 +538,14 @@
 
        DEBUG_1("%s image done", get_exec_time());
 
-       g_object_set(G_OBJECT(imd->pr), "loading", FALSE, NULL);
-       image_state_unset(imd, IMAGE_STATE_LOADING);
-
        if (options->image.enable_read_ahead && imd->image_fd && 
!imd->image_fd->pixbuf && image_loader_get_pixbuf(imd->il))
                {
                imd->image_fd->pixbuf = 
g_object_ref(image_loader_get_pixbuf(imd->il));
                image_cache_set(imd, imd->image_fd);
                }
+       /* call the callback triggered by image_state after fd->pixbuf is set */
+       g_object_set(G_OBJECT(imd->pr), "loading", FALSE, NULL);
+       image_state_unset(imd, IMAGE_STATE_LOADING);
 
        if (!image_loader_get_pixbuf(imd->il))
                {

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c    2009-02-15 09:36:53 UTC (rev 1389)
+++ trunk/src/main.c    2009-02-15 13:11:21 UTC (rev 1390)
@@ -33,6 +33,7 @@
 #include "metadata.h"
 #include "editors.h"
 #include "exif.h"
+#include "histogram.h"
 
 #include <gdk/gdkkeysyms.h> /* for keyboard values */
 
@@ -743,6 +744,7 @@
        /* register global notify functions */
        file_data_register_notify_func(cache_notify_cb, NULL, 
NOTIFY_PRIORITY_HIGH);
        file_data_register_notify_func(thumb_notify_cb, NULL, 
NOTIFY_PRIORITY_HIGH);
+       file_data_register_notify_func(histogram_notify_cb, NULL, 
NOTIFY_PRIORITY_HIGH);
        file_data_register_notify_func(collect_manager_notify_cb, NULL, 
NOTIFY_PRIORITY_LOW);
 
        parse_command_line_for_debug_option(argc, argv);

Modified: trunk/src/typedefs.h
===================================================================
--- trunk/src/typedefs.h        2009-02-15 09:36:53 UTC (rev 1389)
+++ trunk/src/typedefs.h        2009-02-15 13:11:21 UTC (rev 1390)
@@ -200,6 +200,7 @@
 
 typedef struct _PixmapFolders PixmapFolders;
 typedef struct _Histogram Histogram;
+typedef struct _HistMap HistMap;
 
 typedef struct _SecureSaveInfo SecureSaveInfo;
 
@@ -451,6 +452,8 @@
 
        GdkPixbuf *pixbuf; /* full-size image, only complete images, NULL 
during loading
                              all FileData with non-NULL pixbuf are referenced 
by image_cache */
+                             
+       HistMap *histmap;
 
        gint ref;
        gint version; /* increased when any field in this structure is changed 
*/


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn

Reply via email to