Remove misleading comment in ~/.glivrc.
[gliv.git] / src / thumbnails.c
blob71d0513555b478f676692b369dbd4f829e78fa29
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <guichaz@yahoo.fr>
21 /******************************************
22 * Make thumbnails and keep track of them *
23 ******************************************/
25 #include "gliv.h"
26 #include "thumbnails.h"
27 #include "options.h"
28 #include "tree.h"
29 #include "thread.h"
30 #include "images_menus.h"
31 #include "callbacks.h"
33 extern options_struct *options;
35 static GHashTable *thumbs_hash_table = NULL;
37 gchar *get_absolute_filename(const gchar * filename)
39 static gchar *cwd = NULL;
41 if (filename[0] == '/')
42 return g_strdup(filename);
44 if (cwd == NULL)
45 cwd = g_get_current_dir();
47 while (filename[0] == '.' && filename[1] == '/') {
48 filename += 2;
49 while (filename[0] == '/')
50 filename++;
53 return g_build_filename(cwd, filename, NULL);
57 * We include the thumbnails wanted dimensions in the hash key, this way we can
58 * keep track of many thumbnails with different sizes for a given filename.
60 static gchar *get_key(const gchar * filename)
62 gchar *key, *fullpath;
64 fullpath = get_absolute_filename(filename);
66 key = g_strdup_printf("%s_%d_%d", fullpath,
67 options->thumb_width, options->thumb_height);
68 g_free(fullpath);
69 return key;
72 static GdkPixbuf *create_mini(GdkPixbuf * pixbuf)
74 gint w, h;
75 gfloat zoom_w, zoom_h, zoom;
76 gint mini_w, mini_h;
78 w = gdk_pixbuf_get_width(pixbuf);
79 h = gdk_pixbuf_get_height(pixbuf);
81 zoom_w = (gfloat) w / options->thumb_width;
82 zoom_h = (gfloat) h / options->thumb_height;
83 zoom = MAX(zoom_w, zoom_h);
85 if (zoom <= 1.0)
86 /* A thumbnail should not be bigger than the original. */
87 return pixbuf;
89 mini_w = (gint) (w / zoom);
90 mini_h = (gint) (h / zoom);
92 mini_w = MAX(mini_w, 1);
93 mini_h = MAX(mini_h, 1);
95 return gdk_pixbuf_scale_simple(pixbuf, mini_w, mini_h, GDK_INTERP_BILINEAR);
98 static void init_hash(void)
100 if (thumbs_hash_table == NULL)
101 /* First time. */
102 thumbs_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
105 /* Runs in a separate thread. */
106 static GdkPixbuf *get_mini(tree_item * item)
108 GdkPixbuf *pixbuf, *mini;
110 if (canceled_using_tree())
111 return NULL;
113 init_hash();
115 mini = g_hash_table_lookup(thumbs_hash_table, item->thumb_key);
116 if (mini != NULL)
117 return mini;
119 pixbuf = gdk_pixbuf_new_from_file(item->path, NULL);
120 if (pixbuf == NULL)
121 return NULL;
123 if (canceled_using_tree()) {
124 g_object_unref(pixbuf);
125 return NULL;
128 mini = create_mini(pixbuf);
129 if (mini != pixbuf)
130 g_object_unref(pixbuf);
132 g_hash_table_insert(thumbs_hash_table, item->thumb_key, mini);
134 if (canceled_using_tree())
135 mini = NULL;
137 return mini;
140 gboolean fill_thumbnail(tree_item * item)
142 if (item->thumb == NULL) {
143 if (item->thumb_key == NULL)
144 item->thumb_key = get_key(item->path);
146 item->thumb = do_threaded((GThreadFunc) get_mini, item);
147 return item->thumb != NULL;
148 } else
149 /* Simulate the do_threaded() effect. */
150 process_events();
152 return TRUE;
155 void collection_add_thumbnail(gchar * key, GdkPixbuf * thumb)
157 init_hash();
159 g_hash_table_insert(thumbs_hash_table, key, thumb);