1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * Electric Eyes thumbnail support plugin for GImageView
5 * Copyright (C) 2001 Takuro Ashie
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id: ee.c,v 1.18 2003/07/13 13:20:18 makeinu Exp $
22 */
23
24 #include <string.h>
25 #include <gtk/gtk.h>
26 #include <gmodule.h>
27
28 #include "fileutil.h"
29 #include "gfileutil.h"
30 #include "intl.h"
31 #include "gimv_plugin.h"
32 #include "gimv_thumb_cache.h"
33
34
35 #ifndef BUF_SIZE
36 #define BUF_SIZE 4096
37 #endif
38
39 #ifndef MAX_PATH_LEN
40 #define MAX_PATH_LEN 1024
41 #endif
42
43 /* under image directory */
44 #define EE_THUMNAIL_DIRECTORY ".ee"
45
46
47 typedef struct EEThumbPrefs_Tag
48 {
49 gint width;
50 gint height;
51 gchar *dir;
52 } EEThumbPrefs;
53
54
55 static GimvImage *load_thumb (const gchar *filename,
56 const gchar *cache_type,
57 GimvImageInfo *info);
58 static GimvImage *save_thumb (const gchar *filename,
59 const gchar *cache_type,
60 GimvImage *image,
61 GimvImageInfo *info);
62 static gchar *get_path (const gchar *filename,
63 const gchar *cache_type);
64 static gboolean get_size (gint width,
65 gint height,
66 const gchar *cache_type,
67 gint *width_ret,
68 gint *height_ret);
69
70
71 static EEThumbPrefs ee_thumb_prefs [] =
72 {
73 {180, 180, "large"},
74 {256, 64, "med"},
75 {256, 24, "small"},
76 };
77 static gint ee_thumb_prefs_num
78 = sizeof (ee_thumb_prefs) / sizeof (ee_thumb_prefs[0]);
79
80 static GimvThumbCacheLoader plugin_impl[] =
81 {
82 {GIMV_THUMB_CACHE_LOADER_IF_VERSION,
83 N_("Electric Eyes (Preview)"),
84 load_thumb, save_thumb,
85 get_path, get_size,
86 NULL, NULL, NULL, NULL, NULL},
87
88 {GIMV_THUMB_CACHE_LOADER_IF_VERSION,
89 N_("Electric Eyes (Icon)"),
90 load_thumb, save_thumb,
91 get_path, get_size,
92 NULL, NULL, NULL, NULL, NULL},
93
94 {GIMV_THUMB_CACHE_LOADER_IF_VERSION,
95 N_("Electric Eyes (Mini)"),
96 load_thumb, save_thumb,
97 get_path, get_size,
98 NULL, NULL, NULL, NULL, NULL},
99 };
100 static gint plugin_impl_num = sizeof (plugin_impl) / sizeof (plugin_impl[0]);
101
102 GIMV_PLUGIN_GET_IMPL(plugin_impl, GIMV_PLUGIN_THUMB_CACHE)
103
104 GimvPluginInfo gimv_plugin_info =
105 {
106 if_version: GIMV_PLUGIN_IF_VERSION,
107 name: N_("Electric Eyes thumbnail support"),
108 version: "0.5.0",
109 author: N_("Takuro Ashie"),
110 description: NULL,
111 get_implement: gimv_plugin_get_impl,
112 get_mime_type: NULL,
113 get_prefs_ui: NULL,
114 };
115
116
117 gchar *
g_module_check_init(GModule * module)118 g_module_check_init (GModule *module)
119 {
120 return NULL;
121 }
122
123
124 void
g_module_unload(GModule * module)125 g_module_unload (GModule *module)
126 {
127 return;
128 }
129
130
131 static GimvImage *
load_thumb(const gchar * filename,const gchar * cache_type,GimvImageInfo * info)132 load_thumb (const gchar *filename, const gchar *cache_type,
133 GimvImageInfo *info)
134 {
135 GimvImage *image;
136 gchar *thumb_file;
137
138 g_return_val_if_fail (filename, NULL);
139 g_return_val_if_fail (cache_type, NULL);
140
141 thumb_file = get_path (filename, cache_type);
142
143 g_return_val_if_fail (thumb_file, NULL);
144
145 image = gimv_image_load_file (thumb_file, FALSE);
146
147 g_free (thumb_file);
148
149 return image;
150 }
151
152
153 static GimvImage *
save_thumb(const gchar * filename,const gchar * cache_type,GimvImage * image,GimvImageInfo * info)154 save_thumb (const gchar *filename, const gchar *cache_type,
155 GimvImage *image, GimvImageInfo *info)
156 {
157 GimvImage *imcache;
158 gchar *thumb_file;
159 gint im_width = -1, im_height = -1, width = -1, height = -1;
160 gboolean success;
161
162 /* check args */
163 g_return_val_if_fail (filename, FALSE);
164 g_return_val_if_fail (image, FALSE);
165 g_return_val_if_fail (cache_type, FALSE);
166
167 thumb_file = get_path (filename, cache_type);
168 g_return_val_if_fail (thumb_file, FALSE);
169
170 /* get image width & height */
171 gimv_image_get_size (image, &im_width, &im_height);
172 if (im_width < 1 || im_height < 1) return NULL;
173
174 /* get thumnail width & height */
175 success = get_size (im_width, im_height, cache_type, &width, &height);
176 if (!success || width < 1 || height < 1) return NULL;
177
178 /* create cache directory if not found */
179 success = mkdirs (thumb_file);
180 if (!success) return NULL;
181
182 /* scale image */
183 imcache = gimv_image_scale (image, width, height);
184
185 /* save cache to disk */
186 if (imcache) {
187 g_print (N_("save cache: %s\n"), thumb_file);
188 gimv_image_save_file (imcache, thumb_file, "ppm");
189 }
190
191 g_free (thumb_file);
192
193 return imcache;
194 }
195
196
197 static gchar *
get_path(const gchar * filename,const gchar * cache_type)198 get_path (const gchar *filename, const gchar *cache_type)
199 {
200 gchar *abspath;
201 gchar buf[MAX_PATH_LEN];
202 gchar *size = NULL;
203 gint i;
204
205 g_return_val_if_fail (filename, NULL);
206 g_return_val_if_fail (cache_type, NULL);
207
208 for (i = 0; (i < plugin_impl_num) && (i < ee_thumb_prefs_num); i++) {
209 if (!strcmp (cache_type, plugin_impl[i].label)) {
210 size = ee_thumb_prefs[i].dir;
211 break;
212 }
213 }
214
215 g_return_val_if_fail (size, NULL);
216
217 abspath = relpath2abs (filename);
218 g_return_val_if_fail (abspath, NULL);
219
220 g_snprintf (buf, MAX_PATH_LEN, "%s/%s/%s%s",
221 g_getenv("HOME"), EE_THUMNAIL_DIRECTORY, size, filename);
222
223 g_free (abspath);
224
225 return g_strdup (buf);
226 }
227
228
229 static gboolean
get_size(gint width,gint height,const gchar * cache_type,gint * width_ret,gint * height_ret)230 get_size (gint width, gint height, const gchar *cache_type,
231 gint *width_ret, gint *height_ret)
232 {
233 gint max_width = -1, max_height = -1;
234 gint i;
235 gboolean use_large = FALSE;
236
237 /* check args */
238 g_return_val_if_fail (width_ret && height_ret, FALSE);
239 *width_ret = *height_ret = -1;
240
241 g_return_val_if_fail (cache_type, FALSE);
242
243 if (width < 1 || height < 1)
244 return FALSE;
245
246 /* get max thumbnail size */
247 for (i = 0; (i < plugin_impl_num) && (i < ee_thumb_prefs_num); i++) {
248 if (!strcmp (cache_type, plugin_impl[i].label)) {
249 max_width = ee_thumb_prefs[i].width;
250 max_height = ee_thumb_prefs[i].height;
251 if (i == 0)
252 use_large = TRUE;
253 break;
254 }
255 }
256 g_return_val_if_fail (max_width > 0 && max_height > 0, FALSE);
257
258 /* no need to scale */
259 if (width < max_width && height < max_height) {
260 *width_ret = width;
261 *height_ret = height;
262 return TRUE;
263 }
264
265 /* calculate width & height of thumbnail */
266 if (width < height || !use_large) {
267 *width_ret = (gfloat) width * (gfloat) max_height / (gfloat) height;
268 *height_ret = max_height;
269 if (!use_large && width > max_width) {
270 *width_ret = max_width;
271 *height_ret = (gfloat) height * (gfloat) max_width / (gfloat) width;
272 }
273 } else {
274 *width_ret = max_width;
275 *height_ret = (gfloat) height * (gfloat) max_width / (gfloat) width;
276 }
277
278 return TRUE;
279 }
280