1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * 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: gimv_image_info.c,v 1.6 2004/09/21 08:44:32 makeinu Exp $
22 */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28
29 #include "gimageview.h"
30
31 #include "fileutil.h"
32 #include "fr-archive.h"
33 #include "gfileutil.h"
34 #include "gimv_comment.h"
35 #include "gimv_anim.h"
36 #include "gimv_image.h"
37 #include "gimv_image_info.h"
38 #include "gimv_mime_types.h"
39 #include "gimv_thumb.h"
40 #include "gimv_thumb_cache.h"
41 #include "prefs.h"
42
43
44 static GHashTable *gimv_image_info_table = NULL;
45 static GHashTable *comment_table = NULL;
46 static GHashTable *archive_table = NULL;
47 static GHashTable *link_table = NULL;
48
49
50 /******************************************************************************
51 *
52 * Private Functions.
53 *
54 ******************************************************************************/
55 static GimvImageInfo *
gimv_image_info_new(const gchar * filename)56 gimv_image_info_new (const gchar *filename)
57 {
58 GimvImageInfo *info;
59
60 info = g_new0 (GimvImageInfo, 1);
61 g_return_val_if_fail (info, NULL);
62
63 info->filename = g_strdup (filename);
64 info->format = gimv_image_detect_type_by_ext (filename);
65 info->width = -1;
66 info->height = -1;
67 info->depth = -1;
68 info->flags = 0;
69
70 info->ref_count = 1;
71
72 return info;
73 }
74
75
76 /******************************************************************************
77 *
78 * Public Functions.
79 *
80 ******************************************************************************/
81 GimvImageInfo *
gimv_image_info_get(const gchar * filename)82 gimv_image_info_get (const gchar *filename)
83 {
84 GimvImageInfo *info;
85 struct stat st;
86
87 g_return_val_if_fail (filename, NULL);
88
89 if (!gimv_image_info_table) {
90 gimv_image_info_table = g_hash_table_new (g_str_hash, g_str_equal);
91 }
92
93 info = g_hash_table_lookup (gimv_image_info_table, filename);
94 if (!info) {
95 if (!file_exists (filename)) return NULL;
96 info = gimv_image_info_new (filename);
97 if (!info) return NULL;
98 stat (filename, &info->st);
99 g_hash_table_insert (gimv_image_info_table, info->filename, info);
100 } else {
101 if (stat (filename, &st)) return NULL;
102 if (info->st.st_size != st.st_size
103 || info->st.st_mtime != st.st_mtime
104 || info->st.st_ctime != st.st_ctime)
105 {
106 info->st = st;
107 info->width = -1;
108 info->height = -1;
109 info->flags &= ~GIMV_IMAGE_INFO_SYNCED_FLAG;
110 }
111 gimv_image_info_ref (info);
112 }
113
114 return info;
115 }
116
117
118 GimvImageInfo *
gimv_image_info_get_url(const gchar * url)119 gimv_image_info_get_url (const gchar *url)
120 {
121 GimvImageInfo *info;
122
123 g_return_val_if_fail (url, NULL);
124
125 if (!gimv_image_info_table) {
126 gimv_image_info_table = g_hash_table_new (g_str_hash, g_str_equal);
127 }
128
129 info = g_hash_table_lookup (gimv_image_info_table, url);
130 if (!info) {
131 info = gimv_image_info_new (url);
132 if (!info) return NULL;
133 info->flags |= GIMV_IMAGE_INFO_URL_FLAG;
134 g_hash_table_insert (gimv_image_info_table, info->filename, info);
135 } else {
136 gimv_image_info_ref (info);
137 }
138
139 return info;
140 }
141
142
143 GimvImageInfo *
gimv_image_info_get_with_archive(const gchar * filename,FRArchive * archive,struct stat * st)144 gimv_image_info_get_with_archive (const gchar *filename,
145 FRArchive *archive,
146 struct stat *st)
147 {
148 GimvImageInfo *info;
149 gchar buf[MAX_PATH_LEN];
150
151 g_return_val_if_fail (filename, NULL);
152 g_return_val_if_fail (archive, NULL);
153
154 if (!gimv_image_info_table)
155 gimv_image_info_table = g_hash_table_new (g_str_hash, g_str_equal);
156
157 if (!archive_table)
158 archive_table = g_hash_table_new (g_direct_hash, g_direct_equal);
159
160 g_snprintf (buf, MAX_PATH_LEN, "%s/%s", archive->filename, filename);
161
162 info = g_hash_table_lookup (gimv_image_info_table, buf);
163 if (!info) {
164 info = gimv_image_info_new (filename);
165 g_hash_table_insert (gimv_image_info_table, g_strdup (buf), info);
166 g_hash_table_insert (archive_table, info, archive);
167 } else {
168 /* FIXME!! update if needed */
169 /* gimv_image_info_ref (info); */
170 }
171
172 if (st)
173 info->st = *st;
174
175 info->flags |= GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG;
176
177 return info;
178 }
179
180
181 GimvImageInfo *
gimv_image_info_lookup(const gchar * filename)182 gimv_image_info_lookup (const gchar *filename)
183 {
184 GimvImageInfo *info;
185
186 info = g_hash_table_lookup (gimv_image_info_table, filename);
187
188 if (info)
189 gimv_image_info_ref (info);
190
191 return info;
192 }
193
194
195 void
gimv_image_info_finalize(GimvImageInfo * info)196 gimv_image_info_finalize (GimvImageInfo *info)
197 {
198 guint num;
199 gchar buf[MAX_PATH_LEN];
200
201 g_return_if_fail (info);
202
203 /* remove data from hash table */
204 if (info->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG) {
205 gchar *orig_key;
206 GimvImageInfo *value;
207 gboolean success = FALSE;
208 FRArchive *archive = g_hash_table_lookup (archive_table, info);
209
210 if (archive) {
211 g_snprintf (buf, MAX_PATH_LEN, "%s/%s",
212 archive->filename, info->filename);
213 success = g_hash_table_lookup_extended (gimv_image_info_table, buf,
214 (gpointer) &orig_key,
215 (gpointer) &value);
216 g_hash_table_remove (archive_table, info);
217 }
218 if (success) {
219 g_hash_table_remove (gimv_image_info_table, buf);
220 g_free (orig_key);
221 }
222 } else {
223 g_hash_table_remove (gimv_image_info_table, info->filename);
224 }
225
226 gimv_image_info_set_comment (info, NULL);
227 gimv_image_info_set_link (info, NULL);
228
229 if (info->filename) {
230 g_free (info->filename);
231 info->filename = NULL;
232 }
233 g_free (info);
234
235 /* destroy hash table if needed */
236 num = g_hash_table_size (gimv_image_info_table);
237 if (num < 1) {
238 g_hash_table_destroy (gimv_image_info_table);
239 gimv_image_info_table = NULL;
240 }
241 }
242
243
244 GimvImageInfo *
gimv_image_info_ref(GimvImageInfo * info)245 gimv_image_info_ref (GimvImageInfo *info)
246 {
247 g_return_val_if_fail (info, NULL);
248
249 info->ref_count++;
250
251 if (info->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG) {
252 FRArchive *archive = g_hash_table_lookup (archive_table, info);
253 if (archive)
254 fr_archive_ref (archive);
255 }
256
257 return info;
258 }
259
260
261 void
gimv_image_info_unref(GimvImageInfo * info)262 gimv_image_info_unref (GimvImageInfo *info)
263 {
264 FRArchive *archive = NULL;
265
266 g_return_if_fail (info);
267
268 if (info->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG)
269 archive = g_hash_table_lookup (archive_table, info);
270
271 info->ref_count--;
272
273 if (info->ref_count < 1) {
274 gimv_image_info_finalize (info);
275 }
276
277 if (archive)
278 fr_archive_unref (FR_ARCHIVE (archive));
279 }
280
281
282 /* used by fr-command */
283 void
gimv_image_info_unref_with_archive(GimvImageInfo * info)284 gimv_image_info_unref_with_archive (GimvImageInfo *info)
285 {
286 g_return_if_fail (info);
287
288 info->ref_count--;
289 /* info->archive = NULL; */
290
291 if (info->ref_count < 1)
292 gimv_image_info_finalize (info);
293 }
294
295
296 void
gimv_image_info_set_size(GimvImageInfo * info,gint width,gint height)297 gimv_image_info_set_size (GimvImageInfo *info, gint width, gint height)
298 {
299 g_return_if_fail (info);
300
301 if (info->flags & GIMV_IMAGE_INFO_SYNCED_FLAG) return;
302
303 info->width = width;
304 info->height = height;
305 }
306
307
308 void
gimv_image_info_set_comment(GimvImageInfo * info,GimvComment * comment)309 gimv_image_info_set_comment (GimvImageInfo *info, GimvComment *comment)
310 {
311 GimvComment *prev;
312
313 g_return_if_fail (info);
314
315 if (!comment_table)
316 comment_table = g_hash_table_new (g_direct_hash, g_direct_equal);
317
318 prev = g_hash_table_lookup (comment_table, info);
319 if (prev) {
320 g_hash_table_remove (comment_table, info);
321 /* comment_unref (prev); */
322 }
323
324 if (comment) {
325 /* comment_ref (comment); */
326 g_hash_table_insert (comment_table, info, comment);
327 }
328 }
329
330
331 GimvComment *
gimv_image_info_get_comment(GimvImageInfo * info)332 gimv_image_info_get_comment (GimvImageInfo *info)
333 {
334 g_return_val_if_fail (info, NULL);
335
336 if (!comment_table) return NULL;
337 return g_hash_table_lookup (comment_table, info);
338 }
339
340
341 void
gimv_image_info_set_link(GimvImageInfo * info,const gchar * link)342 gimv_image_info_set_link (GimvImageInfo *info, const gchar *link)
343 {
344 gchar *old_link;
345
346 g_return_if_fail (info);
347
348 if (!link_table)
349 link_table = g_hash_table_new (g_direct_hash, g_direct_equal);
350
351 old_link = g_hash_table_lookup (link_table, info);
352 if (old_link) {
353 g_hash_table_remove (link_table, info);
354 g_free (old_link);
355 }
356
357 if (link && *link)
358 g_hash_table_insert (link_table, info, g_strdup (link));
359 }
360
361
362 FRArchive *
gimv_image_info_get_archive(GimvImageInfo * info)363 gimv_image_info_get_archive (GimvImageInfo *info)
364 {
365 g_return_val_if_fail (info, NULL);
366
367 if (!archive_table) return NULL;
368 return g_hash_table_lookup (archive_table, info);
369 }
370
371
372 void
gimv_image_info_set_flags(GimvImageInfo * info,GimvImageInfoFlags flags)373 gimv_image_info_set_flags (GimvImageInfo *info, GimvImageInfoFlags flags)
374 {
375 g_return_if_fail (info);
376
377 if (!(info->flags & GIMV_IMAGE_INFO_SYNCED_FLAG)
378 || (flags & GIMV_IMAGE_INFO_SYNCED_FLAG))
379 {
380 info->flags |= flags;
381 }
382 }
383
384
385 void
gimv_image_info_unset_flags(GimvImageInfo * info,GimvImageInfoFlags flags)386 gimv_image_info_unset_flags (GimvImageInfo *info, GimvImageInfoFlags flags)
387 {
388 g_return_if_fail (info);
389
390 if (!(info->flags & GIMV_IMAGE_INFO_SYNCED_FLAG)
391 || (flags & GIMV_IMAGE_INFO_SYNCED_FLAG))
392 {
393 info->flags &= ~flags;
394 }
395 }
396
397
398 gboolean
gimv_image_info_is_dir(GimvImageInfo * info)399 gimv_image_info_is_dir (GimvImageInfo *info)
400 {
401 g_return_val_if_fail (info, FALSE);
402
403 if (isdir (gimv_image_info_get_path (info)))
404 return TRUE;
405
406 return FALSE;
407 }
408
409
410 gboolean
gimv_image_info_is_archive(GimvImageInfo * info)411 gimv_image_info_is_archive (GimvImageInfo *info)
412 {
413 g_return_val_if_fail (info, FALSE);
414
415 if (fr_archive_utils_get_file_name_ext (gimv_image_info_get_path (info)))
416 return TRUE;
417
418 return FALSE;
419 }
420
421
422 gboolean
gimv_image_info_is_in_archive(GimvImageInfo * info)423 gimv_image_info_is_in_archive (GimvImageInfo *info)
424 {
425 g_return_val_if_fail (info, FALSE);
426
427 if (info->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG)
428 return TRUE;
429 else
430 return FALSE;
431 }
432
433
434 gboolean
gimv_image_info_is_url(GimvImageInfo * info)435 gimv_image_info_is_url (GimvImageInfo *info)
436 {
437 g_return_val_if_fail (info, FALSE);
438
439 if (info->flags & GIMV_IMAGE_INFO_URL_FLAG)
440 return TRUE;
441 else
442 return FALSE;
443 }
444
445
446 gboolean
gimv_image_info_is_animation(GimvImageInfo * info)447 gimv_image_info_is_animation (GimvImageInfo *info)
448 {
449 g_return_val_if_fail (info, FALSE);
450
451 if (info->flags & GIMV_IMAGE_INFO_ANIMATION_FLAG)
452 return TRUE;
453
454 return FALSE;
455 }
456
457
458 gboolean
gimv_image_info_is_movie(GimvImageInfo * info)459 gimv_image_info_is_movie (GimvImageInfo *info)
460 {
461 const gchar *ext;
462 const gchar *type;
463
464 g_return_val_if_fail (info, FALSE);
465
466 if ((info->flags & GIMV_IMAGE_INFO_MOVIE_FLAG)
467 || (info->flags & GIMV_IMAGE_INFO_MRL_FLAG))
468 {
469 return TRUE;
470 }
471
472 ext = fileutil_get_extention (info->filename);
473 type = gimv_mime_types_get_type_from_ext (ext);
474
475 if (type
476 && (!g_strncasecmp (type, "video", 5))
477 && g_strcasecmp (type, "video/x-mng")) /* FIXME!! */
478 {
479 return TRUE;
480 }
481
482 return FALSE;
483 }
484
485
486 gboolean
gimv_image_info_is_audio(GimvImageInfo * info)487 gimv_image_info_is_audio (GimvImageInfo *info)
488 {
489 const gchar *ext;
490 const gchar *type;
491
492 g_return_val_if_fail (info, FALSE);
493
494 ext = gimv_mime_types_get_extension (info->filename);
495 type = gimv_mime_types_get_type_from_ext (ext);
496
497 if (type && !g_strncasecmp (type, "audio", 5))
498 return TRUE;
499
500 return FALSE;
501 }
502
503
504 gboolean
gimv_image_info_is_same(GimvImageInfo * info1,GimvImageInfo * info2)505 gimv_image_info_is_same (GimvImageInfo *info1, GimvImageInfo *info2)
506 {
507 FRArchive *arc1 = NULL, *arc2 = NULL;
508
509 g_return_val_if_fail (info1, FALSE);
510 g_return_val_if_fail (info2, FALSE);
511 g_return_val_if_fail (info1->filename && *info1->filename, FALSE);
512 g_return_val_if_fail (info2->filename && *info2->filename, FALSE);
513
514 if (strcmp (info1->filename, info2->filename))
515 return FALSE;
516
517 if (!(info1->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG)
518 && !(info2->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG))
519 {
520 return TRUE;
521 }
522
523 if (archive_table) {
524 arc1 = g_hash_table_lookup (archive_table, info1);
525 arc2 = g_hash_table_lookup (archive_table, info2);
526 }
527
528 if (arc1 && arc1->filename && *arc1->filename
529 && arc2 && arc2->filename && *arc2->filename
530 && !strcmp (arc1->filename, arc2->filename))
531 {
532 return TRUE;
533 }
534
535 return FALSE;
536 }
537
538
539 const gchar *
gimv_image_info_get_path(GimvImageInfo * info)540 gimv_image_info_get_path (GimvImageInfo *info)
541 {
542 g_return_val_if_fail (info, NULL);
543
544 return info->filename;
545 }
546
547
548 gchar *
gimv_image_info_get_path_with_archive(GimvImageInfo * info)549 gimv_image_info_get_path_with_archive (GimvImageInfo *info)
550 {
551 FRArchive *arc;
552
553 g_return_val_if_fail (info, NULL);
554
555 if (!(info->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG))
556 return g_strdup (info->filename);
557
558 arc = g_hash_table_lookup (archive_table, info);
559 g_return_val_if_fail (arc, NULL);
560
561 return g_strconcat (arc->filename, "/", info->filename, NULL);
562 }
563
564
565 const gchar *
gimv_image_info_get_archive_path(GimvImageInfo * info)566 gimv_image_info_get_archive_path (GimvImageInfo *info)
567 {
568 FRArchive *arc;
569
570 g_return_val_if_fail (info, NULL);
571 g_return_val_if_fail (info->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG,
572 NULL);
573
574 arc = g_hash_table_lookup (archive_table, info);
575
576 return arc->filename;
577 }
578
579
580 gboolean
gimv_image_info_need_temp_file(GimvImageInfo * info)581 gimv_image_info_need_temp_file (GimvImageInfo *info)
582 {
583 g_return_val_if_fail (info, FALSE);
584
585 if (gimv_image_info_is_in_archive (info))
586 return TRUE;
587 else
588 return FALSE;
589 }
590
591
592 gchar *
gimv_image_info_get_temp_file_path(GimvImageInfo * info)593 gimv_image_info_get_temp_file_path (GimvImageInfo *info)
594 {
595 FRArchive *archive;
596 gchar *temp_dir;
597 gchar *filename, buf[MAX_PATH_LEN];
598
599 g_return_val_if_fail (info, NULL);
600 g_return_val_if_fail (archive_table, FALSE);
601
602 archive = g_hash_table_lookup (archive_table, info);
603 g_return_val_if_fail (archive, NULL);
604
605 filename = info->filename;
606
607 temp_dir = gtk_object_get_data (GTK_OBJECT (archive), "temp-dir");
608
609 g_return_val_if_fail (temp_dir && *temp_dir, NULL);
610
611 g_snprintf (buf, MAX_PATH_LEN, "%s/%s",
612 temp_dir, filename);
613
614 return g_strdup (buf);
615 }
616
617
618 gchar *
gimv_image_info_get_temp_file(GimvImageInfo * info)619 gimv_image_info_get_temp_file (GimvImageInfo *info)
620 {
621 gboolean success;
622 gchar *filename;
623
624 /* load the image */
625 if (!gimv_image_info_need_temp_file (info))
626 return NULL;
627
628 filename = gimv_image_info_get_temp_file_path (info);
629 g_return_val_if_fail (filename, NULL);
630
631 if (file_exists (filename)) {
632 return filename;
633 }
634
635 success = gimv_image_info_extract_archive (info);
636 if (success)
637 return filename;
638
639 g_free (filename);
640 return NULL;
641 }
642
643
644 /*
645 * FIXME!!
646 * If archive was already destroyed, create FRArchive object first.
647 * To detect whether archive was destroyed or not, check info->archive.
648 * When archive is destroyed, fr-archive class will set this value to NULL
649 * by using gimv_image_info_unref_with_archive ().
650 */
651 gboolean
gimv_image_info_extract_archive(GimvImageInfo * info)652 gimv_image_info_extract_archive (GimvImageInfo *info)
653 {
654 FRArchive *archive;
655 GList *filelist = NULL;
656 gchar *temp_dir;
657 gchar *filename, *temp_file, buf[MAX_PATH_LEN];
658
659 g_return_val_if_fail (info, FALSE);
660 g_return_val_if_fail (archive_table, FALSE);
661
662 archive = g_hash_table_lookup (archive_table, info);
663 g_return_val_if_fail (archive, FALSE);
664
665 filename = info->filename;
666
667 temp_dir = gtk_object_get_data (GTK_OBJECT (archive), "temp-dir");
668
669 g_return_val_if_fail (temp_dir && *temp_dir, FALSE);
670
671 g_snprintf (buf, MAX_PATH_LEN, "%s/%s",
672 temp_dir, filename);
673 temp_file = buf;
674
675 if (!file_exists (temp_file) && !archive->process->running) {
676 ensure_dir_exists (temp_dir);
677 filelist = g_list_append (filelist, filename);
678
679 fr_archive_extract (archive, filelist, temp_dir,
680 FALSE, TRUE, FALSE);
681
682 gtk_main (); /* will be quited by callback function
683 of archive (see fileload.c) */
684 }
685
686 if (file_exists (temp_file)) {
687 return TRUE;
688 } else {
689 return FALSE;
690 }
691 }
692
693
694 GimvIO *
gimv_image_info_get_gio(GimvImageInfo * info)695 gimv_image_info_get_gio (GimvImageInfo *info)
696 {
697 gboolean need_temp;
698 const gchar *filename;
699 gchar *temp_file = NULL;
700 GimvIO *gio = NULL;
701
702 g_return_val_if_fail (info, NULL);
703
704 need_temp = gimv_image_info_need_temp_file (info);
705 if (need_temp) {
706 temp_file = gimv_image_info_get_temp_file (info);
707 filename = temp_file;
708 } else {
709 filename = gimv_image_info_get_path (info);
710 }
711
712 if (filename)
713 gio = gimv_io_new (filename, "rb");
714
715 g_free (temp_file);
716
717 return gio;
718 }
719
720
721 const gchar *
gimv_image_info_get_format(GimvImageInfo * info)722 gimv_image_info_get_format (GimvImageInfo *info)
723 {
724 g_return_val_if_fail (info, NULL);
725
726 return info->format;
727 }
728
729
730 void
gimv_image_info_get_image_size(GimvImageInfo * info,gint * width_ret,gint * height_ret)731 gimv_image_info_get_image_size (GimvImageInfo *info,
732 gint *width_ret, gint *height_ret)
733 {
734 g_return_if_fail (width_ret && height_ret);
735 *width_ret = -1;
736 *height_ret = -1;
737
738 g_return_if_fail (info);
739
740 *width_ret = info->width;
741 *height_ret = info->height;
742 }
743
744
745 /* FIXME */
746 gboolean
gimv_image_info_rename_image(GimvImageInfo * info,const gchar * filename)747 gimv_image_info_rename_image (GimvImageInfo *info, const gchar *filename)
748 {
749 struct stat st;
750 gboolean success;
751 gchar *cache_type;
752 gchar *src_cache_path, *dest_cache_path;
753 gchar *src_comment, *dest_comment;
754
755 g_return_val_if_fail (info, FALSE);
756 g_return_val_if_fail (info->filename, FALSE);
757 g_return_val_if_fail (!(info->flags & GIMV_IMAGE_INFO_ARCHIVE_MEMBER_FLAG),
758 FALSE);
759 g_return_val_if_fail (filename, FALSE);
760
761 /* rename the file */
762 success = !rename(info->filename, filename);
763 if (!success) return FALSE;
764
765 /* rename cache */
766 src_cache_path = gimv_thumb_find_thumbcache (gimv_image_info_get_path (info),
767 &cache_type);
768 if (src_cache_path) {
769 dest_cache_path
770 = gimv_thumb_cache_get_path (filename, cache_type);
771 if (rename (src_cache_path, dest_cache_path) < 0)
772 g_print (_("Faild to rename cache file :%s\n"), filename);
773 g_free (src_cache_path);
774 g_free (dest_cache_path);
775 }
776
777 /* rename comment */
778 src_comment = gimv_comment_find_file (gimv_image_info_get_path (info));
779 if (src_comment) {
780 dest_comment = gimv_comment_get_path (filename);
781 if (rename (src_comment, dest_comment) < 0)
782 g_print (_("Faild to rename comment file :%s\n"), dest_comment);
783 g_free (src_comment);
784 g_free (dest_comment);
785 }
786
787 if (stat (filename, &st)) return FALSE;
788 info->st = st;
789 g_free (info->filename);
790 info->filename = (gchar *) g_strdup (filename);
791
792 return success;
793 }
794