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 "callbacks.h"
32 extern options_struct
*options
;
34 static GHashTable
*thumbs_hash_table
= NULL
;
36 gchar
*get_absolute_filename(const gchar
* filename
)
38 static gchar
*cwd
= NULL
;
40 if (filename
[0] == '/')
41 return g_strdup(filename
);
44 cwd
= g_get_current_dir();
46 while (filename
[0] == '.' && filename
[1] == '/') {
48 while (filename
[0] == '/')
52 return g_build_filename(cwd
, filename
, NULL
);
56 * We include the thumbnails wanted dimensions in the hash key, this way we can
57 * keep track of many thumbnails with different sizes for a given filename.
59 static gchar
*get_key(const gchar
* filename
)
61 gchar
*key
, *fullpath
;
63 fullpath
= get_absolute_filename(filename
);
65 key
= g_strdup_printf("%s_%d_%d", fullpath
,
66 options
->thumb_width
, options
->thumb_height
);
71 static GdkPixbuf
*create_mini(GdkPixbuf
* pixbuf
)
74 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. */
91 mini_w
= (gint
) (w
/ zoom
);
92 mini_h
= (gint
) (h
/ zoom
);
94 mini_w
= MAX(mini_w
, 1);
95 mini_h
= MAX(mini_h
, 1);
97 res
= gdk_pixbuf_scale_simple(pixbuf
, mini_w
, mini_h
, GDK_INTERP_BILINEAR
);
102 static void init_hash(void)
104 if (thumbs_hash_table
== NULL
)
106 thumbs_hash_table
= g_hash_table_new(g_str_hash
, g_str_equal
);
109 /* Runs in a separate thread. */
110 static GdkPixbuf
*get_mini(const gchar
* filename
)
112 GdkPixbuf
*pixbuf
, *mini
;
114 if (canceled_using_tree())
117 pixbuf
= gdk_pixbuf_new_from_file(filename
, NULL
);
121 if (canceled_using_tree()) {
122 g_object_unref(pixbuf
);
126 mini
= create_mini(pixbuf
);
127 g_object_unref(pixbuf
);
132 /* Called when we have loaded an image, to add its thumbnail. */
133 void add_thumbnail(const gchar
* filename
, GdkPixbuf
* pixbuf
)
140 key
= get_key(filename
);
141 if (g_hash_table_lookup(thumbs_hash_table
, key
) != NULL
) {
146 mini
= do_threaded((GThreadFunc
) create_mini
, pixbuf
);
152 g_hash_table_insert(thumbs_hash_table
, key
, mini
);
154 g_object_ref(pixbuf
);
157 gboolean
fill_thumbnail(tree_item
* item
)
159 if (item
->thumb
!= NULL
) {
160 /* Simulate the do_threaded() effect. */
165 if (item
->thumb_key
== NULL
)
166 item
->thumb_key
= get_key(item
->path
);
170 item
->thumb
= g_hash_table_lookup(thumbs_hash_table
, item
->thumb_key
);
171 if (item
->thumb
!= NULL
)
174 item
->thumb
= do_threaded((GThreadFunc
) get_mini
, item
->path
);
175 if (item
->thumb
== NULL
)
178 g_hash_table_insert(thumbs_hash_table
, g_strdup(item
->thumb_key
),
183 void collection_add_thumbnail(gchar
* key
, GdkPixbuf
* thumb
)
187 g_hash_table_insert(thumbs_hash_table
, key
, thumb
);
190 GdkPixbuf
*get_thumbnail(const gchar
* filename
, gchar
** thumb_key
)
195 item
.path
= (gchar
*) filename
;
196 item
.thumb_key
= NULL
;
199 fill_thumbnail(&item
);
202 *thumb_key
= item
.thumb_key
;