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.
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;
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;
#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)
static gint image_loader_idle_cb(gpointer data)
{
ImageLoader *il = data;
- guchar buf[IMAGE_LOADER_BUFFER_SIZE];
gint b;
gint c;
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)
{
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;
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)
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;
/* 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;
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;
}
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);
}
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)
#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
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;
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
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");
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);
gint bytes_read;
gint bytes_total;
- guint buffer_size;
-
gint requested_width;
gint requested_height;
gint shrunk;
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);
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 */