comparison src/thumb.c @ 838:9bd49e725ad3

use FileData in thumb_loader
author nadvornik
date Sun, 15 Jun 2008 20:09:15 +0000
parents 179a7224dde1
children 14520c3a91f8
comparison
equal deleted inserted replaced
837:f8c22438376c 838:9bd49e725ad3
23 23
24 #include <utime.h> 24 #include <utime.h>
25 25
26 26
27 static void thumb_loader_error_cb(ImageLoader *il, gpointer data); 27 static void thumb_loader_error_cb(ImageLoader *il, gpointer data);
28 static void thumb_loader_setup(ThumbLoader *tl, gchar *path); 28 static void thumb_loader_setup(ThumbLoader *tl, const gchar *path);
29 29
30 static gint normalize_thumb(gint *width, gint *height, gint max_w, gint max_h); 30 static gint normalize_thumb(gint *width, gint *height, gint max_w, gint max_h);
31 static GdkPixbuf *get_xv_thumbnail(gchar *thumb_filename, gint max_w, gint max_h); 31 static GdkPixbuf *get_xv_thumbnail(gchar *thumb_filename, gint max_w, gint max_h);
32 32
33 33
41 { 41 {
42 gchar *cache_dir; 42 gchar *cache_dir;
43 gint success = FALSE; 43 gint success = FALSE;
44 mode_t mode = 0755; 44 mode_t mode = 0755;
45 45
46 if (!tl || !tl->pixbuf) return FALSE; 46 if (!tl || !tl->fd || !tl->fd->pixbuf) return FALSE;
47 47
48 cache_dir = cache_get_location(CACHE_TYPE_THUMB, tl->path, FALSE, &mode); 48 cache_dir = cache_get_location(CACHE_TYPE_THUMB, tl->fd->path, FALSE, &mode);
49 49
50 if (cache_ensure_dir_exists(cache_dir, mode)) 50 if (cache_ensure_dir_exists(cache_dir, mode))
51 { 51 {
52 gchar *cache_path; 52 gchar *cache_path;
53 gchar *pathl; 53 gchar *pathl;
54 gchar *name = g_strconcat(filename_from_path(tl->path), GQ_CACHE_EXT_THUMB, NULL); 54 gchar *name = g_strconcat(filename_from_path(tl->fd->path), GQ_CACHE_EXT_THUMB, NULL);
55 55
56 cache_path = g_build_filename(cache_dir, name, NULL); 56 cache_path = g_build_filename(cache_dir, name, NULL);
57 g_free(name); 57 g_free(name);
58 58
59 DEBUG_1("Saving thumb: %s", cache_path); 59 DEBUG_1("Saving thumb: %s", cache_path);
60 60
61 pathl = path_from_utf8(cache_path); 61 pathl = path_from_utf8(cache_path);
62 success = pixbuf_to_file_as_png(tl->pixbuf, pathl); 62 success = pixbuf_to_file_as_png(tl->fd->pixbuf, pathl);
63 if (success) 63 if (success)
64 { 64 {
65 struct utimbuf ut; 65 struct utimbuf ut;
66 /* set thumb time to that of source file */ 66 /* set thumb time to that of source file */
67 67
68 ut.actime = ut.modtime = filetime(tl->path); 68 ut.actime = ut.modtime = filetime(tl->fd->path);
69 if (ut.modtime > 0) 69 if (ut.modtime > 0)
70 { 70 {
71 utime(pathl, &ut); 71 utime(pathl, &ut);
72 } 72 }
73 } 73 }
91 gint success = FALSE; 91 gint success = FALSE;
92 mode_t mode = 0755; 92 mode_t mode = 0755;
93 93
94 if (!tl) return FALSE; 94 if (!tl) return FALSE;
95 95
96 cache_dir = cache_get_location(CACHE_TYPE_THUMB, tl->path, FALSE, &mode); 96 cache_dir = cache_get_location(CACHE_TYPE_THUMB, tl->fd->path, FALSE, &mode);
97 97
98 if (cache_ensure_dir_exists(cache_dir, mode)) 98 if (cache_ensure_dir_exists(cache_dir, mode))
99 { 99 {
100 gchar *cache_path; 100 gchar *cache_path;
101 gchar *pathl; 101 gchar *pathl;
102 FILE *f; 102 FILE *f;
103 gchar *name = g_strconcat(filename_from_path(tl->path), GQ_CACHE_EXT_THUMB, NULL); 103 gchar *name = g_strconcat(filename_from_path(tl->fd->path), GQ_CACHE_EXT_THUMB, NULL);
104 104
105 cache_path = g_build_filename(cache_dir, name, NULL); 105 cache_path = g_build_filename(cache_dir, name, NULL);
106 g_free(name); 106 g_free(name);
107 107
108 DEBUG_1("marking thumb failure: %s", cache_path); 108 DEBUG_1("marking thumb failure: %s", cache_path);
113 { 113 {
114 struct utimbuf ut; 114 struct utimbuf ut;
115 115
116 fclose(f); 116 fclose(f);
117 117
118 ut.actime = ut.modtime = filetime(tl->path); 118 ut.actime = ut.modtime = filetime(tl->fd->path);
119 if (ut.modtime > 0) 119 if (ut.modtime > 0)
120 { 120 {
121 utime(pathl, &ut); 121 utime(pathl, &ut);
122 } 122 }
123 123
146 ThumbLoader *tl = data; 146 ThumbLoader *tl = data;
147 GdkPixbuf *pixbuf; 147 GdkPixbuf *pixbuf;
148 gint pw, ph; 148 gint pw, ph;
149 gint save; 149 gint save;
150 150
151 DEBUG_1("thumb done: %s", tl->path); 151 DEBUG_1("thumb done: %s", tl->fd->path);
152 152
153 pixbuf = image_loader_get_pixbuf(tl->il); 153 pixbuf = image_loader_get_pixbuf(tl->il);
154 if (!pixbuf) 154 if (!pixbuf)
155 { 155 {
156 DEBUG_1("...but no pixbuf: %s", tl->path); 156 DEBUG_1("...but no pixbuf: %s", tl->fd->path);
157 thumb_loader_error_cb(tl->il, tl); 157 thumb_loader_error_cb(tl->il, tl);
158 return; 158 return;
159 } 159 }
160 160
161 pw = gdk_pixbuf_get_width(pixbuf); 161 pw = gdk_pixbuf_get_width(pixbuf);
162 ph = gdk_pixbuf_get_height(pixbuf); 162 ph = gdk_pixbuf_get_height(pixbuf);
163 163
164 if (tl->cache_hit && pw != tl->max_w && ph != tl->max_h) 164 if (tl->cache_hit && pw != tl->max_w && ph != tl->max_h)
165 { 165 {
166 /* requested thumbnail size may have changed, load original */ 166 /* requested thumbnail size may have changed, load original */
167 DEBUG_1("thumbnail size mismatch, regenerating: %s", tl->path); 167 DEBUG_1("thumbnail size mismatch, regenerating: %s", tl->fd->path);
168 tl->cache_hit = FALSE; 168 tl->cache_hit = FALSE;
169 169
170 thumb_loader_setup(tl, tl->path); 170 thumb_loader_setup(tl, tl->fd->path);
171 171
172 if (!image_loader_start(tl->il, thumb_loader_done_cb, tl)) 172 if (!image_loader_start(tl->il, thumb_loader_done_cb, tl))
173 { 173 {
174 image_loader_free(tl->il); 174 image_loader_free(tl->il);
175 tl->il = NULL; 175 tl->il = NULL;
176 176
177 DEBUG_1("regeneration failure: %s", tl->path); 177 DEBUG_1("regeneration failure: %s", tl->fd->path);
178 thumb_loader_error_cb(tl->il, tl); 178 thumb_loader_error_cb(tl->il, tl);
179 } 179 }
180 return; 180 return;
181 } 181 }
182 182
196 { 196 {
197 h = tl->max_h; 197 h = tl->max_h;
198 w = (double)h / ph * pw; 198 w = (double)h / ph * pw;
199 if (w < 1) w = 1; 199 if (w < 1) w = 1;
200 } 200 }
201 201
202 tl->pixbuf = gdk_pixbuf_scale_simple(pixbuf, w, h, (GdkInterpType)options->thumbnails.quality); 202 if (tl->fd)
203 {
204 if (tl->fd->pixbuf) g_object_unref(tl->fd->pixbuf);
205 tl->fd->pixbuf = gdk_pixbuf_scale_simple(pixbuf, w, h, (GdkInterpType)options->thumbnails.quality);
206 }
203 save = TRUE; 207 save = TRUE;
204 } 208 }
205 else 209 else
206 { 210 {
207 tl->pixbuf = pixbuf; 211 if (tl->fd)
208 gdk_pixbuf_ref(tl->pixbuf); 212 {
213 if (tl->fd->pixbuf) g_object_unref(tl->fd->pixbuf);
214 tl->fd->pixbuf = pixbuf;
215 gdk_pixbuf_ref(tl->fd->pixbuf);
216 }
209 save = il->shrunk; 217 save = il->shrunk;
210 } 218 }
211 219
212 /* save it ? */ 220 /* save it ? */
213 if (tl->cache_enable && save) 221 if (tl->cache_enable && save)
227 { 235 {
228 thumb_loader_done_cb(il, data); 236 thumb_loader_done_cb(il, data);
229 return; 237 return;
230 } 238 }
231 239
232 DEBUG_1("thumb error: %s", tl->path); 240 DEBUG_1("thumb error: %s", tl->fd->path);
233 241
234 image_loader_free(tl->il); 242 image_loader_free(tl->il);
235 tl->il = NULL; 243 tl->il = NULL;
236 244
237 if (tl->func_error) tl->func_error(tl, tl->data); 245 if (tl->func_error) tl->func_error(tl, tl->data);
251 static void thumb_loader_delay_done(ThumbLoader *tl) 259 static void thumb_loader_delay_done(ThumbLoader *tl)
252 { 260 {
253 if (tl->idle_done_id == -1) tl->idle_done_id = g_idle_add(thumb_loader_done_delay_cb, tl); 261 if (tl->idle_done_id == -1) tl->idle_done_id = g_idle_add(thumb_loader_done_delay_cb, tl);
254 } 262 }
255 263
256 static void thumb_loader_setup(ThumbLoader *tl, gchar *path) 264 static void thumb_loader_setup(ThumbLoader *tl, const gchar *path)
257 { 265 {
266 FileData *fd = file_data_new_simple(path);
258 image_loader_free(tl->il); 267 image_loader_free(tl->il);
259 tl->il = image_loader_new(file_data_new_simple(path)); 268 tl->il = image_loader_new(fd);
269 file_data_unref(fd);
260 270
261 if (options->thumbnails.fast) 271 if (options->thumbnails.fast)
262 { 272 {
263 /* this will speed up jpegs by up to 3x in some cases */ 273 /* this will speed up jpegs by up to 3x in some cases */
264 image_loader_set_requested_size(tl->il, tl->max_w, tl->max_h); 274 image_loader_set_requested_size(tl->il, tl->max_w, tl->max_h);
309 tl->cache_retry = retry_failed; 319 tl->cache_retry = retry_failed;
310 #endif 320 #endif
311 } 321 }
312 322
313 323
314 gint thumb_loader_start(ThumbLoader *tl, const gchar *path) 324 gint thumb_loader_start(ThumbLoader *tl, FileData *fd)
315 { 325 {
316 gchar *cache_path = NULL; 326 gchar *cache_path = NULL;
317 327
318 if (!tl) return FALSE; 328 if (!tl) return FALSE;
319 329
320 if (tl->standard_loader) 330 if (tl->standard_loader)
321 { 331 {
322 return thumb_loader_std_start((ThumbLoaderStd *)tl, path); 332 return thumb_loader_std_start((ThumbLoaderStd *)tl, fd);
323 } 333 }
324 334
325 if (!tl->path && !path) return FALSE; 335 if (!tl->fd && !fd) return FALSE;
326 336
327 if (!tl->path) tl->path = g_strdup(path); 337 if (!tl->fd) tl->fd = file_data_ref(fd);
328 338
329 if (tl->cache_enable) 339 if (tl->cache_enable)
330 { 340 {
331 cache_path = cache_find_location(CACHE_TYPE_THUMB, tl->path); 341 cache_path = cache_find_location(CACHE_TYPE_THUMB, tl->fd->path);
332 342
333 if (cache_path) 343 if (cache_path)
334 { 344 {
335 if (cache_time_valid(cache_path, tl->path)) 345 if (cache_time_valid(cache_path, tl->fd->path))
336 { 346 {
337 DEBUG_1("Found in cache:%s", tl->path); 347 DEBUG_1("Found in cache:%s", tl->fd->path);
338 348
339 if (filesize(cache_path) == 0) 349 if (filesize(cache_path) == 0)
340 { 350 {
341 DEBUG_1("Broken image mark found:%s", cache_path); 351 DEBUG_1("Broken image mark found:%s", cache_path);
342 g_free(cache_path); 352 g_free(cache_path);
353 } 363 }
354 } 364 }
355 365
356 if (!cache_path && options->thumbnails.use_xvpics) 366 if (!cache_path && options->thumbnails.use_xvpics)
357 { 367 {
358 tl->pixbuf = get_xv_thumbnail(tl->path, tl->max_w, tl->max_h); 368 if (tl->fd->pixbuf) g_object_unref(tl->fd->pixbuf);
359 if (tl->pixbuf) 369 tl->fd->pixbuf = get_xv_thumbnail(tl->fd->path, tl->max_w, tl->max_h);
370 if (tl->fd->pixbuf)
360 { 371 {
361 thumb_loader_delay_done(tl); 372 thumb_loader_delay_done(tl);
362 return TRUE; 373 return TRUE;
363 } 374 }
364 } 375 }
369 g_free(cache_path); 380 g_free(cache_path);
370 tl->cache_hit = TRUE; 381 tl->cache_hit = TRUE;
371 } 382 }
372 else 383 else
373 { 384 {
374 thumb_loader_setup(tl, tl->path); 385 thumb_loader_setup(tl, tl->fd->path);
375 } 386 }
376 387
377 if (!image_loader_start(tl->il, thumb_loader_done_cb, tl)) 388 if (!image_loader_start(tl->il, thumb_loader_done_cb, tl))
378 { 389 {
379 /* try from original if cache attempt */ 390 /* try from original if cache attempt */
380 if (tl->cache_hit) 391 if (tl->cache_hit)
381 { 392 {
382 tl->cache_hit = FALSE; 393 tl->cache_hit = FALSE;
383 log_printf("%s", _("Thumbnail image in cache failed to load, trying to recreate.\n")); 394 log_printf("%s", _("Thumbnail image in cache failed to load, trying to recreate.\n"));
384 395
385 thumb_loader_setup(tl, tl->path); 396 thumb_loader_setup(tl, tl->fd->path);
386 if (image_loader_start(tl->il, thumb_loader_done_cb, tl)) return TRUE; 397 if (image_loader_start(tl->il, thumb_loader_done_cb, tl)) return TRUE;
387 } 398 }
388 /* mark failed thumbnail in cache with 0 byte file */ 399 /* mark failed thumbnail in cache with 0 byte file */
389 if (tl->cache_enable) 400 if (tl->cache_enable)
390 { 401 {
417 if (tl && tl->standard_loader) 428 if (tl && tl->standard_loader)
418 { 429 {
419 return thumb_loader_std_get_pixbuf((ThumbLoaderStd *)tl, with_fallback); 430 return thumb_loader_std_get_pixbuf((ThumbLoaderStd *)tl, with_fallback);
420 } 431 }
421 432
422 if (tl && tl->pixbuf) 433 if (tl && tl->fd && tl->fd->pixbuf)
423 { 434 {
424 pixbuf = tl->pixbuf; 435 pixbuf = tl->fd->pixbuf;
425 g_object_ref(pixbuf); 436 g_object_ref(pixbuf);
426 } 437 }
427 else if (with_fallback) 438 else if (with_fallback)
428 { 439 {
429 gint w, h; 440 gint w, h;
469 return (ThumbLoader *)thumb_loader_std_new(width, height); 480 return (ThumbLoader *)thumb_loader_std_new(width, height);
470 } 481 }
471 482
472 tl = g_new0(ThumbLoader, 1); 483 tl = g_new0(ThumbLoader, 1);
473 tl->standard_loader = FALSE; 484 tl->standard_loader = FALSE;
474 tl->path = NULL; 485 tl->fd = NULL;
475 tl->cache_enable = options->thumbnails.enable_caching; 486 tl->cache_enable = options->thumbnails.enable_caching;
476 tl->cache_hit = FALSE; 487 tl->cache_hit = FALSE;
477 tl->percent_done = 0.0; 488 tl->percent_done = 0.0;
478 tl->max_w = width; 489 tl->max_w = width;
479 tl->max_h = height; 490 tl->max_h = height;
493 { 504 {
494 thumb_loader_std_free((ThumbLoaderStd *)tl); 505 thumb_loader_std_free((ThumbLoaderStd *)tl);
495 return; 506 return;
496 } 507 }
497 508
498 if (tl->pixbuf) gdk_pixbuf_unref(tl->pixbuf);
499 image_loader_free(tl->il); 509 image_loader_free(tl->il);
500 g_free(tl->path); 510 file_data_unref(tl->fd);
501 511
502 if (tl->idle_done_id != -1) g_source_remove(tl->idle_done_id); 512 if (tl->idle_done_id != -1) g_source_remove(tl->idle_done_id);
503 513
504 g_free(tl); 514 g_free(tl);
505 } 515 }