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 ******************************************/
26 #include "thumbnails.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
);
45 cwd
= g_get_current_dir();
47 while (filename
[0] == '.' && filename
[1] == '/') {
49 while (filename
[0] == '/')
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
);
72 static GdkPixbuf
*create_mini(GdkPixbuf
* pixbuf
)
75 gfloat zoom_w
, zoom_h
, zoom
;
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
);
86 /* A thumbnail should not be bigger than the original. */
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
)
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())
115 mini
= g_hash_table_lookup(thumbs_hash_table
, item
->thumb_key
);
119 pixbuf
= gdk_pixbuf_new_from_file(item
->path
, NULL
);
123 if (canceled_using_tree()) {
124 g_object_unref(pixbuf
);
128 mini
= create_mini(pixbuf
);
130 g_object_unref(pixbuf
);
132 g_hash_table_insert(thumbs_hash_table
, item
->thumb_key
, mini
);
134 if (canceled_using_tree())
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
;
149 /* Simulate the do_threaded() effect. */
155 void collection_add_thumbnail(gchar
* key
, GdkPixbuf
* thumb
)
159 g_hash_table_insert(thumbs_hash_table
, key
, thumb
);