Skip to content

Commit

Permalink
Add two new options to control image read buffer at runtime.
Browse files Browse the repository at this point in the history
They are available in Preferences > Advanced > Image loading and caching.
Default read buffer size was set to 4096 instead of 512.
These options are saved to rc file.
  • Loading branch information
Laurent Monin committed Apr 18, 2008
1 parent 37af10a commit aa3a6e8
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 26 deletions.
5 changes: 5 additions & 0 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ ConfOptions *init_options(ConfOptions *options)
options->file_ops.safe_delete_path = NULL;
options->file_ops.safe_delete_folder_maxsize = 128;
options->layout.tools_restore_state = FALSE;

options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
options->image.zoom_2pass = TRUE;
options->image.scroll_reset_method = SCROLL_RESET_TOPLEFT;
Expand All @@ -59,6 +60,10 @@ ConfOptions *init_options(ConfOptions *options)
options->image.max_window_size = 100;
options->image.limit_autofit_size = FALSE;
options->image.max_autofit_size = 100;

options->image.read_buffer_size = IMAGE_LOADER_READ_BUFFER_SIZE_DEFAULT;
options->image.idle_read_loop_count = IMAGE_LOADER_IDLE_READ_LOOP_COUNT_DEFAULT;

options->thumbnails.max_width = DEFAULT_THUMB_WIDTH;
options->thumbnails.max_height = DEFAULT_THUMB_HEIGHT;
options->thumbnails.enable_caching = TRUE;
Expand Down
40 changes: 18 additions & 22 deletions src/image-load.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@
#include <fcntl.h>


/* bytes to read from file per read() */
#define IMAGE_LOADER_BUFFER_SIZE 512

/* the number of bytes to read per idle call (define x IMAGE_LOADER_BUFFER_SIZE) */
#define IMAGE_LOADER_BUFFER_DEFAULT_COUNT 1

static const gchar *image_loader_path(ImageLoader *il)
{
if (il->fd)
Expand Down Expand Up @@ -177,26 +171,25 @@ static void image_loader_error(ImageLoader *il)
static gint image_loader_idle_cb(gpointer data)
{
ImageLoader *il = data;
guchar buf[IMAGE_LOADER_BUFFER_SIZE];
gint b;
gint c;

if (!il) return FALSE;

if (il->idle_id == -1) return FALSE;

c = il->buffer_size ? il->buffer_size : 1;
c = il->idle_read_loop_count ? il->idle_read_loop_count : 1;
while (c > 0)
{
b = read(il->load_fd, &buf, sizeof(buf));
b = read(il->load_fd, il->read_buffer, il->read_buffer_size);

if (b == 0)
{
image_loader_done(il);
return FALSE;
}

if (b < 0 || (b > 0 && !gdk_pixbuf_loader_write(il->loader, buf, b, NULL)))
if (b < 0 || (b > 0 && !gdk_pixbuf_loader_write(il->loader, il->read_buffer, b, NULL)))
{
image_loader_error(il);
return FALSE;
Expand All @@ -217,20 +210,19 @@ static gint image_loader_idle_cb(gpointer data)

static gint image_loader_begin(ImageLoader *il)
{
guchar buf[IMAGE_LOADER_BUFFER_SIZE];
int b;
unsigned int offset = 0;

if (!il->loader || il->pixbuf) return FALSE;

b = read(il->load_fd, &buf, sizeof(buf));
b = read(il->load_fd, il->read_buffer, il->read_buffer_size);

if (b > 0 &&
format_raw_img_exif_offsets_fd(il->load_fd, image_loader_path(il), buf, b, &offset, NULL))
format_raw_img_exif_offsets_fd(il->load_fd, image_loader_path(il), il->read_buffer, b, &offset, NULL))
{
if (debug) printf("Raw file %s contains embedded image\n", image_loader_path(il));

b = read(il->load_fd, &buf, sizeof(buf));
b = read(il->load_fd, il->read_buffer, il->read_buffer_size);
}

if (b < 1)
Expand All @@ -239,7 +231,7 @@ static gint image_loader_begin(ImageLoader *il)
return FALSE;
}

if (!gdk_pixbuf_loader_write(il->loader, buf, b, NULL))
if (!gdk_pixbuf_loader_write(il->loader, il->read_buffer, b, NULL))
{
image_loader_stop(il);
return FALSE;
Expand All @@ -250,8 +242,8 @@ static gint image_loader_begin(ImageLoader *il)
/* read until size is known */
while (il->loader && !gdk_pixbuf_loader_get_pixbuf(il->loader) && b > 0)
{
b = read(il->load_fd, &buf, sizeof(buf));
if (b < 0 || (b > 0 && !gdk_pixbuf_loader_write(il->loader, buf, b, NULL)))
b = read(il->load_fd, il->read_buffer, il->read_buffer_size);
if (b < 0 || (b > 0 && !gdk_pixbuf_loader_write(il->loader, il->read_buffer, b, NULL)))
{
image_loader_stop(il);
return FALSE;
Expand Down Expand Up @@ -332,12 +324,14 @@ static ImageLoader *image_loader_new_real(FileData *fd, const gchar *path)

il->idle_done_id = -1;

il->buffer_size = IMAGE_LOADER_BUFFER_DEFAULT_COUNT;
il->idle_read_loop_count = options->image.idle_read_loop_count;
il->read_buffer_size = options->image.read_buffer_size;
il->read_buffer = g_new(guchar, il->read_buffer_size);

il->requested_width = 0;
il->requested_height = 0;
il->shrunk = FALSE;

if (debug) printf("new image loader %p, bufsize=%u idle_loop=%u\n", il, il->read_buffer_size, il->idle_read_loop_count);
return il;
}

Expand All @@ -360,6 +354,8 @@ void image_loader_free(ImageLoader *il)
if (il->pixbuf) gdk_pixbuf_unref(il->pixbuf);
if (il->fd) file_data_unref(il->fd);
if (il->path) g_free(il->path);
if (il->read_buffer) g_free(il->read_buffer);
if (debug) printf("freeing image loader %p bytes_read=%d\n", il, il->bytes_read);
g_free(il);
}

Expand Down Expand Up @@ -430,11 +426,11 @@ void image_loader_set_requested_size(ImageLoader *il, gint width, gint height)
il->requested_height = height;
}

void image_loader_set_buffer_size(ImageLoader *il, guint size)
void image_loader_set_buffer_size(ImageLoader *il, guint count)
{
if (!il) return;

il->buffer_size = size ? size : 1;
il->idle_read_loop_count = count ? count : 1;
}

void image_loader_set_priority(ImageLoader *il, gint priority)
Expand Down
8 changes: 8 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@
#define DEFAULT_THUMB_WIDTH 96
#define DEFAULT_THUMB_HEIGHT 72

#define IMAGE_LOADER_READ_BUFFER_SIZE_DEFAULT 4096
#define IMAGE_LOADER_READ_BUFFER_SIZE_MIN 512
#define IMAGE_LOADER_READ_BUFFER_SIZE_MAX 16*1024*1024

#define IMAGE_LOADER_IDLE_READ_LOOP_COUNT_DEFAULT 1
#define IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN 1
#define IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX 16

#if 1 /* set to 0 to disable debugging code and related options */
# ifndef DEBUG
# define DEBUG 1
Expand Down
14 changes: 14 additions & 0 deletions src/preferences.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ static void config_window_apply(void)
options->collections.rectangular_selection = c_options->collections.rectangular_selection;

options->image.tile_cache_max = c_options->image.tile_cache_max;

options->image.read_buffer_size = c_options->image.read_buffer_size;
options->image.idle_read_loop_count = c_options->image.idle_read_loop_count;

options->thumbnails.quality = c_options->thumbnails.quality;
options->image.zoom_quality = c_options->image.zoom_quality;
Expand Down Expand Up @@ -1412,8 +1415,19 @@ static void config_tab_advanced(GtkWidget *notebook)
pref_spin_new_int(group, _("Custom similarity threshold:"), NULL,
0, 100, 1, options->duplicates_similarity_threshold, &c_options->duplicates_similarity_threshold);

group = pref_group_new(vbox, FALSE, _("Image loading and caching"), GTK_ORIENTATION_VERTICAL);

pref_spin_new_int(group, _("Offscreen cache size (Mb per image):"), NULL,
0, 128, 1, options->image.tile_cache_max, &c_options->image.tile_cache_max);

pref_spin_new_int(group, _("Image read buffer size (bytes):"), NULL,
IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX, 512,
options->image.read_buffer_size, &c_options->image.read_buffer_size);

pref_spin_new_int(group, _("Image idle loop read count:"), NULL,
IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX, 1,
options->image.idle_read_loop_count, &c_options->image.idle_read_loop_count);


group = pref_group_new(vbox, FALSE, _("Color profiles"), GTK_ORIENTATION_VERTICAL);
#ifndef HAVE_LCMS
Expand Down
7 changes: 5 additions & 2 deletions src/rcfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ void save_options(void)
WRITE_BOOL(image.exif_rotate_enable);
WRITE_BOOL(image.use_custom_border_color);
WRITE_COLOR(image.border_color);

WRITE_INT(image.read_buffer_size);
WRITE_INT(image.idle_read_loop_count);

WRITE_SUBTITLE("Thumbnails Options");

Expand Down Expand Up @@ -666,7 +667,9 @@ void load_options(void)
READ_BOOL(image.exif_rotate_enable);
READ_BOOL(image.use_custom_border_color);
READ_COLOR(image.border_color);

READ_INT_CLAMP(image.read_buffer_size, IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX);
READ_INT_CLAMP(image.idle_read_loop_count, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX);


/* thumbnails options */
READ_INT_CLAMP(thumbnails.max_width, 16, 512);
Expand Down
9 changes: 7 additions & 2 deletions src/typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ struct _ImageLoader
gint bytes_read;
gint bytes_total;

guint buffer_size;

gint requested_width;
gint requested_height;
gint shrunk;
Expand All @@ -182,6 +180,10 @@ struct _ImageLoader
gpointer data_percent;

gint idle_done_id;

guchar *read_buffer;
gint read_buffer_size;
gint idle_read_loop_count;
};

typedef void (* ThumbLoaderFunc)(ThumbLoader *tl, gpointer data);
Expand Down Expand Up @@ -779,6 +781,9 @@ struct _ConfOptions

gint use_custom_border_color;
GdkColor border_color;

gint read_buffer_size; /* bytes to read from file per read() */
gint idle_read_loop_count; /* the number of bytes to read per idle call (define x image.read_buffer_size) */
} image;

/* thumbnails */
Expand Down

0 comments on commit aa3a6e8

Please sign in to comment.