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