Skip to content

Commit

Permalink
compute histogram in idle time
Browse files Browse the repository at this point in the history
  • Loading branch information
nadvornik committed Mar 15, 2009
1 parent c30d278 commit 04e5dfc
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 19 deletions.
8 changes: 6 additions & 2 deletions src/bar_histogram.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ static gboolean bar_pane_histogram_update_cb(gpointer data)

histmap = histmap_get(phd->fd);

if (!histmap) return FALSE;
if (!histmap)
{
histmap_start_idle(phd->fd);
return FALSE;
}

phd->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, phd->histogram_width, phd->histogram_height);
gdk_pixbuf_fill(phd->pixbuf, 0xffffffff);
Expand Down Expand Up @@ -126,7 +130,7 @@ static void bar_pane_histogram_write_config(GtkWidget *pane, GString *outstr, gi
static void bar_pane_histogram_notify_cb(FileData *fd, NotifyType type, gpointer data)
{
PaneHistogramData *phd = data;
if (fd == phd->fd) bar_pane_histogram_update(phd);
if ((type & (NOTIFY_REREAD | NOTIFY_CHANGE | NOTIFY_HISTMAP | NOTIFY_PIXBUF)) && fd == phd->fd) bar_pane_histogram_update(phd);
}

static gboolean bar_pane_histogram_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data)
Expand Down
3 changes: 2 additions & 1 deletion src/filedata.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "ui_fileops.h"
#include "metadata.h"
#include "trash.h"
#include "histogram.h"


static GHashTable *file_data_pool = NULL;
Expand Down Expand Up @@ -509,7 +510,7 @@ static void file_data_free(FileData *fd)
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);
histmap_free(fd->histmap);

g_assert(fd->sidecar_files == NULL); /* sidecar files must be freed before calling this */

Expand Down
80 changes: 66 additions & 14 deletions src/histogram.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "histogram.h"

#include "pixbuf_util.h"
#include "filedata.h"

#include <math.h>

Expand All @@ -30,6 +31,10 @@ struct _HistMap {
gulong g[HISTMAP_SIZE];
gulong b[HISTMAP_SIZE];
gulong max[HISTMAP_SIZE];

gint idle_id;
GdkPixbuf *pixbuf;
gint y;
};


Expand Down Expand Up @@ -123,22 +128,46 @@ const gchar *histogram_label(Histogram *histogram)
return t1;
}

static HistMap *histmap_read(GdkPixbuf *imgpixbuf)
static HistMap *histmap_new(void)
{
HistMap *histmap = g_new0(HistMap, 1);
histmap->idle_id = -1;
return histmap;
}

void histmap_free(HistMap *histmap)
{
if (!histmap) return;
if (histmap->idle_id != -1) g_source_remove(histmap->idle_id);
if (histmap->pixbuf) g_object_unref(histmap->pixbuf);
g_free(histmap);
}

static gboolean histmap_read(HistMap *histmap, gboolean whole)
{
gint w, h, i, j, srs, has_alpha, step;
gint w, h, i, j, srs, has_alpha, step, end_line;
guchar *s_pix;
HistMap *histmap;
GdkPixbuf *imgpixbuf = histmap->pixbuf;

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);

histmap = g_new0(HistMap, 1);

if (whole)
{
end_line = h;
}
else
{
gint lines = 1 + 16384 / w;
end_line = histmap->y + lines;
if (end_line > h) end_line = h;
}

step = 3 + !!(has_alpha);
for (i = 0; i < h; i++)
for (i = histmap->y; i < end_line; i++)
{
guchar *sp = s_pix + (i * srs); /* 8bit */
for (j = 0; j < w; j++)
Expand All @@ -155,22 +184,45 @@ static HistMap *histmap_read(GdkPixbuf *imgpixbuf)
sp += step;
}
}

return histmap;
histmap->y = end_line;
return end_line >= h;
}

const HistMap *histmap_get(FileData *fd)
{
if (fd->histmap) return fd->histmap;
if (fd->histmap && fd->histmap->idle_id == -1) return fd->histmap; /* histmap exists and is finished */

if (fd->pixbuf)
return NULL;
}

static gboolean histmap_idle_cb(gpointer data)
{
FileData *fd = data;
if (histmap_read(fd->histmap, FALSE))
{
fd->histmap = histmap_read(fd->pixbuf);
return fd->histmap;
/* finished */
g_object_unref(fd->histmap->pixbuf); /*pixbuf is no longer needed */
fd->histmap->pixbuf = NULL;
fd->histmap->idle_id = -1;
file_data_send_notification(fd, NOTIFY_HISTMAP);
return FALSE;
}
return NULL;
return TRUE;
}

gboolean histmap_start_idle(FileData *fd)
{
if (fd->histmap || !fd->pixbuf) return FALSE;

fd->histmap = histmap_new();
fd->histmap->pixbuf = fd->pixbuf;
g_object_ref(fd->histmap->pixbuf);

fd->histmap->idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, histmap_idle_cb, fd, NULL);
return TRUE;
}


static void histogram_vgrid(Histogram *histogram, GdkPixbuf *pixbuf, gint x, gint y, gint width, gint height)
{
guint i;
Expand Down Expand Up @@ -322,7 +374,7 @@ void histogram_notify_cb(FileData *fd, NotifyType type, gpointer data)
{
if ((type & (NOTIFY_CHANGE || NOTIFY_REREAD)) && fd->histmap)
{
g_free(fd->histmap);
histmap_free(fd->histmap);
fd->histmap = NULL;
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/histogram.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ gint histogram_get_mode(Histogram *histogram);
gint histogram_toggle_channel(Histogram *histogram);
gint histogram_toggle_mode(Histogram *histogram);
const gchar *histogram_label(Histogram *histogram);

void histmap_free(HistMap *histmap);

const HistMap *histmap_get(FileData *fd);
gboolean histmap_start_idle(FileData *fd);

gboolean histogram_draw(Histogram *histogram, const HistMap *histmap, GdkPixbuf *pixbuf, gint x, gint y, gint width, gint height);

void histogram_notify_cb(FileData *fd, NotifyType type, gpointer data);
Expand Down
26 changes: 24 additions & 2 deletions src/image-overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ typedef struct _OverlayStateData OverlayStateData;
struct _OverlayStateData {
ImageWindow *imd;
ImageState changed_states;
NotifyType notify;

Histogram *histogram;

Expand Down Expand Up @@ -557,7 +558,11 @@ static GdkPixbuf *image_osd_info_render(OverlayStateData *osd)
if (with_hist)
{
histmap = histmap_get(imd->image_fd);
if (!histmap) with_hist = FALSE;
if (!histmap)
{
histmap_start_idle(imd->image_fd);
with_hist = FALSE;
}
}


Expand Down Expand Up @@ -829,7 +834,8 @@ static gboolean image_osd_update_cb(gpointer data)
/* redraw when the image was changed,
with histogram we have to redraw also when loading is finished */
if (osd->changed_states & IMAGE_STATE_IMAGE ||
(osd->changed_states & IMAGE_STATE_LOADING && osd->show & OSD_SHOW_HISTOGRAM))
(osd->changed_states & IMAGE_STATE_LOADING && osd->show & OSD_SHOW_HISTOGRAM) ||
osd->notify & NOTIFY_HISTMAP)
{
GdkPixbuf *pixbuf;

Expand Down Expand Up @@ -884,6 +890,7 @@ static gboolean image_osd_update_cb(gpointer data)

if (osd->imd->il && image_loader_get_is_done(osd->imd->il))
osd->changed_states = IMAGE_STATE_NONE;
osd->notify = 0;
osd->idle_id = -1;
return FALSE;
}
Expand Down Expand Up @@ -958,13 +965,27 @@ static void image_osd_state_cb(ImageWindow *imd, ImageState state, gpointer data
image_osd_update_schedule(osd, FALSE);
}

static void image_osd_notify_cb(FileData *fd, NotifyType type, gpointer data)
{
OverlayStateData *osd = data;

if ((type & (NOTIFY_HISTMAP)) && osd->imd && fd == osd->imd->image_fd)
{
osd->notify |= type;
image_osd_update_schedule(osd, FALSE);
}
}


static void image_osd_free(OverlayStateData *osd)
{
if (!osd) return;

if (osd->idle_id != -1) g_source_remove(osd->idle_id);
if (osd->timer_id != -1) g_source_remove(osd->timer_id);

file_data_unregister_notify_func(image_osd_notify_cb, osd);

if (osd->imd)
{
image_set_osd_data(osd->imd, NULL);
Expand Down Expand Up @@ -1017,6 +1038,7 @@ static void image_osd_enable(ImageWindow *imd, OsdShowFlags show)
image_set_osd_data(imd, osd);

image_set_state_func(osd->imd, image_osd_state_cb, osd);
file_data_register_notify_func(image_osd_notify_cb, osd, NOTIFY_PRIORITY_LOW);
}

if (show & OSD_SHOW_STATUS)
Expand Down

0 comments on commit 04e5dfc

Please sign in to comment.