Add two new options to control image read buffer at runtime.
authorLaurent Monin <geeqie@norz.org>
Fri, 18 Apr 2008 22:15:01 +0000 (22:15 +0000)
committerLaurent Monin <geeqie@norz.org>
Fri, 18 Apr 2008 22:15:01 +0000 (22:15 +0000)
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.

src/globals.c
src/image-load.c
src/main.h
src/preferences.c
src/rcfile.c
src/typedefs.h

index dc5bcbf..5fc9731 100644 (file)
@@ -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;
@@ -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;
index d18a953..1571cce 100644 (file)
 #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)
@@ -177,7 +171,6 @@ 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;
 
@@ -185,10 +178,10 @@ static gint image_loader_idle_cb(gpointer data)
 
        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)
                        {
@@ -196,7 +189,7 @@ static gint image_loader_idle_cb(gpointer data)
                        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;
@@ -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)
@@ -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;
@@ -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;
@@ -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;
 }
 
@@ -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);
 }
 
@@ -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)
index 0ab3e0e..d457815 100644 (file)
 #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
index c988632..0eabf70 100644 (file)
@@ -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;
@@ -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
index ff1d5b0..7f62bd1 100644 (file)
@@ -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");
 
@@ -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);
index 7103749..55830a7 100644 (file)
@@ -158,8 +158,6 @@ struct _ImageLoader
        gint bytes_read;
        gint bytes_total;
 
-       guint buffer_size;
-
        gint requested_width;
        gint requested_height;
        gint shrunk;
@@ -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);
@@ -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 */