37
|
1 /*
|
|
2 * GQview
|
|
3 * (C) 2005 John Ellis
|
|
4 *
|
|
5 * Author: John Ellis
|
|
6 *
|
|
7 * This software is released under the GNU General Public License (GNU GPL).
|
|
8 * Please read the included file COPYING for more information.
|
|
9 * This software comes with no warranty of any kind, use at your own risk!
|
|
10 */
|
|
11
|
|
12 #include "gqview.h"
|
|
13 #include "cache-loader.h"
|
|
14
|
|
15 #include "exif.h"
|
|
16 #include "md5-util.h"
|
|
17 #include "ui_fileops.h"
|
|
18
|
|
19
|
|
20 static gboolean cache_loader_process(CacheLoader *cl);
|
|
21
|
|
22
|
|
23 static void cache_loader_done_cb(ImageLoader *il, gpointer data)
|
|
24 {
|
|
25 CacheLoader *cl = data;
|
|
26
|
|
27 cache_loader_process(cl);
|
|
28 }
|
|
29
|
|
30 static void cache_loader_error_cb(ImageLoader *il, gpointer data)
|
|
31 {
|
|
32 CacheLoader *cl = data;
|
|
33
|
|
34 cl->error = TRUE;
|
|
35 cache_loader_done_cb(il, data);
|
|
36 }
|
|
37
|
|
38 static gboolean cache_loader_process(CacheLoader *cl)
|
|
39 {
|
|
40 if (cl->todo_mask & CACHE_LOADER_SIMILARITY &&
|
|
41 !cl->cd->similarity)
|
|
42 {
|
|
43 GdkPixbuf *pixbuf;
|
|
44
|
|
45 if (!cl->il && !cl->error)
|
|
46 {
|
|
47 cl->il = image_loader_new(cl->path);
|
|
48 image_loader_set_error_func(cl->il, cache_loader_error_cb, cl);
|
|
49 if (image_loader_start(cl->il, cache_loader_done_cb, cl))
|
|
50 {
|
|
51 return FALSE;
|
|
52 }
|
|
53
|
|
54 cl->error = TRUE;
|
|
55 }
|
|
56
|
|
57 pixbuf = image_loader_get_pixbuf(cl->il);
|
|
58 if (pixbuf)
|
|
59 {
|
|
60 if (!cl->error)
|
|
61 {
|
|
62 ImageSimilarityData *sim;
|
|
63
|
|
64 sim = image_sim_new_from_pixbuf(pixbuf);
|
|
65 cache_sim_data_set_similarity(cl->cd, sim);
|
|
66 image_sim_free(sim);
|
|
67
|
|
68 cl->done_mask |= CACHE_LOADER_SIMILARITY;
|
|
69 }
|
|
70
|
|
71 /* we have the dimensions via pixbuf */
|
|
72 if (!cl->cd->dimensions)
|
|
73 {
|
|
74 cache_sim_data_set_dimensions(cl->cd, gdk_pixbuf_get_width(pixbuf),
|
|
75 gdk_pixbuf_get_height(pixbuf));
|
|
76 if (cl->todo_mask & CACHE_LOADER_DIMENSIONS)
|
|
77 {
|
|
78 cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS;
|
|
79 cl->done_mask |= CACHE_LOADER_DIMENSIONS;
|
|
80 }
|
|
81 }
|
|
82 }
|
|
83
|
|
84 image_loader_free(cl->il);
|
|
85 cl->il = NULL;
|
|
86
|
|
87 cl->todo_mask &= ~CACHE_LOADER_SIMILARITY;
|
|
88 }
|
|
89 else if (cl->todo_mask & CACHE_LOADER_DIMENSIONS &&
|
|
90 !cl->cd->dimensions)
|
|
91 {
|
|
92 if (!cl->error &&
|
|
93 image_load_dimensions(cl->path, &cl->cd->width, &cl->cd->height))
|
|
94 {
|
|
95 cl->cd->dimensions = TRUE;
|
|
96 cl->done_mask |= CACHE_LOADER_DIMENSIONS;
|
|
97 }
|
|
98 else
|
|
99 {
|
|
100 cl->error = TRUE;
|
|
101 }
|
|
102
|
|
103 cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS;
|
|
104 }
|
|
105 else if (cl->todo_mask & CACHE_LOADER_MD5SUM &&
|
|
106 !cl->cd->have_md5sum)
|
|
107 {
|
|
108 if (md5_get_digest_from_file_utf8(cl->path, cl->cd->md5sum))
|
|
109 {
|
|
110 cl->cd->have_md5sum = TRUE;
|
|
111 cl->done_mask |= CACHE_LOADER_MD5SUM;
|
|
112 }
|
|
113 else
|
|
114 {
|
|
115 cl->error = TRUE;
|
|
116 }
|
|
117
|
|
118 cl->todo_mask &= ~CACHE_LOADER_MD5SUM;
|
|
119 }
|
|
120 else if (cl->todo_mask & CACHE_LOADER_DATE &&
|
|
121 !cl->cd->have_date)
|
|
122 {
|
|
123 time_t date = -1;
|
|
124 ExifData *exif;
|
|
125
|
|
126 exif = exif_read(cl->path);
|
|
127 if (exif)
|
|
128 {
|
|
129 gchar *text;
|
|
130
|
|
131 text = exif_get_data_as_text(exif, "fDateTime");
|
|
132 if (text)
|
|
133 {
|
|
134 struct tm t = { 0 };
|
|
135
|
|
136 if (sscanf(text, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday,
|
|
137 &t.tm_hour, &t.tm_min, &t.tm_sec) == 6)
|
|
138 {
|
|
139 t.tm_year -= 1900;
|
|
140 t.tm_mon -= 1;
|
|
141 date = mktime(&t);
|
|
142 }
|
|
143 g_free(text);
|
|
144 }
|
|
145 exif_free(exif);
|
|
146 }
|
|
147
|
|
148 cl->cd->date = date;
|
|
149 cl->cd->have_date = TRUE;
|
|
150
|
|
151 cl->done_mask |= CACHE_LOADER_DATE;
|
|
152 cl->todo_mask &= ~CACHE_LOADER_DATE;
|
|
153 }
|
|
154 else
|
|
155 {
|
|
156 /* done, save then call done function */
|
|
157 if (enable_thumb_caching &&
|
|
158 cl->done_mask != CACHE_LOADER_NONE)
|
|
159 {
|
|
160 gchar *base;
|
|
161 mode_t mode = 0755;
|
|
162
|
|
163 base = cache_get_location(CACHE_TYPE_SIM, cl->path, FALSE, &mode);
|
|
164 if (cache_ensure_dir_exists(base, mode))
|
|
165 {
|
|
166 g_free(cl->cd->path);
|
|
167 cl->cd->path = cache_get_location(CACHE_TYPE_SIM, cl->path, TRUE, NULL);
|
|
168 if (cache_sim_data_save(cl->cd))
|
|
169 {
|
|
170 filetime_set(cl->cd->path, filetime(cl->path));
|
|
171 }
|
|
172 }
|
|
173 g_free(base);
|
|
174 }
|
|
175
|
|
176 cl->idle_id = -1;
|
|
177
|
|
178 if (cl->done_func)
|
|
179 {
|
|
180 cl->done_func(cl, cl->error, cl->done_data);
|
|
181 }
|
|
182
|
|
183 return FALSE;
|
|
184 }
|
|
185
|
|
186 return TRUE;
|
|
187 }
|
|
188
|
|
189 static gboolean cache_loader_idle_cb(gpointer data)
|
|
190 {
|
|
191 CacheLoader *cl = data;
|
|
192
|
|
193 return cache_loader_process(cl);
|
|
194 }
|
|
195
|
|
196 CacheLoader *cache_loader_new(const gchar *path, CacheDataType load_mask,
|
|
197 CacheLoaderDoneFunc done_func, gpointer done_data)
|
|
198 {
|
|
199 CacheLoader *cl;
|
|
200 gchar *found;
|
|
201
|
|
202 if (!path || !isfile(path)) return NULL;
|
|
203
|
|
204 cl = g_new0(CacheLoader, 1);
|
|
205 cl->path = g_strdup(path);
|
|
206
|
|
207 cl->done_func = done_func;
|
|
208 cl->done_data = done_data;
|
|
209
|
|
210 found = cache_find_location(CACHE_TYPE_SIM, path);
|
|
211 if (found && filetime(found) == filetime(path))
|
|
212 {
|
|
213 cl->cd = cache_sim_data_load(found);
|
|
214 }
|
|
215 g_free(found);
|
|
216
|
|
217 if (!cl->cd) cl->cd = cache_sim_data_new();
|
|
218
|
|
219 cl->todo_mask = load_mask;
|
|
220 cl->done_mask = CACHE_LOADER_NONE;
|
|
221
|
|
222 cl->il = NULL;
|
|
223 cl->idle_id = g_idle_add(cache_loader_idle_cb, cl);
|
|
224
|
|
225 cl->error = FALSE;
|
|
226
|
|
227 return cl;
|
|
228 }
|
|
229
|
|
230 void cache_loader_free(CacheLoader *cl)
|
|
231 {
|
|
232 if (!cl) return;
|
|
233
|
|
234 if (cl->idle_id != -1)
|
|
235 {
|
|
236 g_source_remove(cl->idle_id);
|
|
237 cl->idle_id = -1;
|
|
238 }
|
|
239
|
|
240 image_loader_free(cl->il);
|
|
241 cache_sim_data_free(cl->cd);
|
|
242
|
|
243 g_free(cl->path);
|
|
244 g_free(cl);
|
|
245 }
|
|
246
|