libgimpthumb/gimpthumb-utils.[ch] libgimpthumb/gimpthumbnail.[ch] added

2004-10-23  Sven Neumann  <sven@gimp.org>

	* libgimpthumb/gimpthumb-utils.[ch]
	* libgimpthumb/gimpthumbnail.[ch]
	* libgimpthumb/gimpthumb.def: added missing API, mainly for deleting
	thumbnails.

	* app/core/gimpimagefile.[ch]: when saving a thumbnail, delete a
	failure thumbnail if one exists. Unless the thumbnail was created
	explicitely, remove all other thumbnails for this image.

	* app/actions/documents-commands.c: changed accordingly.

	* app/file/file-open.c: only save a thumbnail if there isn't a
	valid thumbnail already.

	* app/widgets/gimpthumbbox.c: before attempting to create a new
	thumbnail, check if there's an uptodate failure thumbnail.
This commit is contained in:
Sven Neumann 2004-10-23 15:30:39 +00:00 committed by Sven Neumann
parent dab05392af
commit ea273aadb9
14 changed files with 389 additions and 61 deletions

View File

@ -1,3 +1,22 @@
2004-10-23 Sven Neumann <sven@gimp.org>
* libgimpthumb/gimpthumb-utils.[ch]
* libgimpthumb/gimpthumbnail.[ch]
* libgimpthumb/gimpthumb.def: added missing API, mainly for deleting
thumbnails.
* app/core/gimpimagefile.[ch]: when saving a thumbnail, delete a
failure thumbnail if one exists. Unless the thumbnail was created
explicitely, remove all other thumbnails for this image.
* app/actions/documents-commands.c: changed accordingly.
* app/file/file-open.c: only save a thumbnail if there isn't a
valid thumbnail already.
* app/widgets/gimpthumbbox.c: before attempting to create a new
thumbnail, check if there's an uptodate failure thumbnail.
2004-10-23 Michael Natterer <mitch@gimp.org> 2004-10-23 Michael Natterer <mitch@gimp.org>
* app/dialogs/Makefile.am * app/dialogs/Makefile.am

View File

@ -180,16 +180,10 @@ documents_recreate_preview_cmd_callback (GtkAction *action,
if (imagefile && gimp_container_have (container, GIMP_OBJECT (imagefile))) if (imagefile && gimp_container_have (container, GIMP_OBJECT (imagefile)))
{ {
const gchar *uri = gimp_object_get_name (GIMP_OBJECT (imagefile)); gimp_imagefile_create_thumbnail (imagefile,
gint size = imagefile->gimp->config->thumbnail_size; context, NULL,
imagefile->gimp->config->thumbnail_size,
if (!size) FALSE);
return;
if (uri)
gimp_thumbs_delete_for_uri (uri);
gimp_imagefile_create_thumbnail (imagefile, context, NULL, size);
} }
} }

View File

@ -72,6 +72,7 @@ static GdkPixbuf * gimp_imagefile_load_thumb (GimpImagefile *imagefile,
static gboolean gimp_imagefile_save_thumb (GimpImagefile *imagefile, static gboolean gimp_imagefile_save_thumb (GimpImagefile *imagefile,
GimpImage *gimage, GimpImage *gimage,
gint size, gint size,
gboolean replace,
GError **error); GError **error);
static gchar * gimp_imagefile_get_description (GimpViewable *viewable, static gchar * gimp_imagefile_get_description (GimpViewable *viewable,
@ -230,7 +231,8 @@ void
gimp_imagefile_create_thumbnail (GimpImagefile *imagefile, gimp_imagefile_create_thumbnail (GimpImagefile *imagefile,
GimpContext *context, GimpContext *context,
GimpProgress *progress, GimpProgress *progress,
gint size) gint size,
gboolean replace)
{ {
GimpThumbnail *thumbnail; GimpThumbnail *thumbnail;
@ -276,7 +278,7 @@ gimp_imagefile_create_thumbnail (GimpImagefile *imagefile,
NULL); NULL);
success = gimp_imagefile_save_thumb (imagefile, success = gimp_imagefile_save_thumb (imagefile,
gimage, size, &error); gimage, size, replace, &error);
g_object_unref (gimage); g_object_unref (gimage);
} }
@ -285,11 +287,12 @@ gimp_imagefile_create_thumbnail (GimpImagefile *imagefile,
success = gimp_thumbnail_save_failure (thumbnail, success = gimp_thumbnail_save_failure (thumbnail,
"The GIMP " GIMP_VERSION, "The GIMP " GIMP_VERSION,
&error); &error);
gimp_imagefile_update (imagefile);
} }
g_object_unref (imagefile); g_object_unref (imagefile);
if (!success) if (! success)
{ {
g_message (error->message); g_message (error->message);
g_error_free (error); g_error_free (error);
@ -300,13 +303,14 @@ gimp_imagefile_create_thumbnail (GimpImagefile *imagefile,
/* The weak version doesn't ref the imagefile but deals gracefully /* The weak version doesn't ref the imagefile but deals gracefully
* with an imagefile that is destroyed while the thumbnail is * with an imagefile that is destroyed while the thumbnail is
* created. Thia allows to use this function w/o the need to block * created. Thia allows to use this function w/o the need to block
* the user interface (making it insensitive). * the user interface.
*/ */
void void
gimp_imagefile_create_thumbnail_weak (GimpImagefile *imagefile, gimp_imagefile_create_thumbnail_weak (GimpImagefile *imagefile,
GimpContext *context, GimpContext *context,
GimpProgress *progress, GimpProgress *progress,
gint size) gint size,
gboolean replace)
{ {
GimpImagefile *local; GimpImagefile *local;
const gchar *uri; const gchar *uri;
@ -327,7 +331,7 @@ gimp_imagefile_create_thumbnail_weak (GimpImagefile *imagefile,
g_object_add_weak_pointer (G_OBJECT (imagefile), (gpointer) &imagefile); g_object_add_weak_pointer (G_OBJECT (imagefile), (gpointer) &imagefile);
gimp_imagefile_create_thumbnail (local, context, progress, size); gimp_imagefile_create_thumbnail (local, context, progress, size, replace);
if (imagefile) if (imagefile)
{ {
@ -346,28 +350,54 @@ gimp_imagefile_create_thumbnail_weak (GimpImagefile *imagefile,
g_object_unref (local); g_object_unref (local);
} }
gboolean
gimp_imagefile_check_thumbnail (GimpImagefile *imagefile)
{
gint size;
g_return_val_if_fail (GIMP_IS_IMAGEFILE (imagefile), FALSE);
size = imagefile->gimp->config->thumbnail_size;
if (size > 0)
{
GimpThumbState state;
state = gimp_thumbnail_check_thumb (imagefile->thumbnail, size);
return (state == GIMP_THUMB_STATE_OK);
}
return TRUE;
}
gboolean gboolean
gimp_imagefile_save_thumbnail (GimpImagefile *imagefile, gimp_imagefile_save_thumbnail (GimpImagefile *imagefile,
GimpImage *gimage) GimpImage *gimage)
{ {
gboolean success; gint size;
GError *error = NULL; gboolean success = TRUE;
GError *error = NULL;
g_return_val_if_fail (GIMP_IS_IMAGEFILE (imagefile), FALSE); g_return_val_if_fail (GIMP_IS_IMAGEFILE (imagefile), FALSE);
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
/* peek the thumbnail to make sure that mtime and filesize are set */ size = imagefile->gimp->config->thumbnail_size;
gimp_thumbnail_peek_image (imagefile->thumbnail);
success = gimp_imagefile_save_thumb (imagefile, if (size > 0)
gimage,
gimage->gimp->config->thumbnail_size,
&error);
if (! success)
{ {
g_message (error->message); /* peek the thumbnail to make sure that mtime and filesize are set */
g_error_free (error); gimp_thumbnail_peek_image (imagefile->thumbnail);
success = gimp_imagefile_save_thumb (imagefile,
gimage, size, FALSE,
&error);
if (! success)
{
g_message (error->message);
g_error_free (error);
}
} }
return success; return success;
@ -684,6 +714,7 @@ static gboolean
gimp_imagefile_save_thumb (GimpImagefile *imagefile, gimp_imagefile_save_thumb (GimpImagefile *imagefile,
GimpImage *gimage, GimpImage *gimage,
gint size, gint size,
gboolean replace,
GError **error) GError **error)
{ {
GimpThumbnail *thumbnail = imagefile->thumbnail; GimpThumbnail *thumbnail = imagefile->thumbnail;
@ -750,7 +781,14 @@ gimp_imagefile_save_thumb (GimpImagefile *imagefile,
g_object_unref (pixbuf); g_object_unref (pixbuf);
if (success) if (success)
gimp_imagefile_update (imagefile); {
if (replace)
gimp_thumbnail_delete_others (thumbnail, size);
else
gimp_thumbnail_delete_failure (thumbnail);
gimp_imagefile_update (imagefile);
}
return success; return success;
} }

View File

@ -68,11 +68,14 @@ void gimp_imagefile_update (GimpImagefile *imagefile);
void gimp_imagefile_create_thumbnail (GimpImagefile *imagefile, void gimp_imagefile_create_thumbnail (GimpImagefile *imagefile,
GimpContext *context, GimpContext *context,
GimpProgress *progress, GimpProgress *progress,
gint thumb_size); gint size,
gboolean replace);
void gimp_imagefile_create_thumbnail_weak (GimpImagefile *imagefile, void gimp_imagefile_create_thumbnail_weak (GimpImagefile *imagefile,
GimpContext *context, GimpContext *context,
GimpProgress *progress, GimpProgress *progress,
gint size); gint size,
gboolean replace);
gboolean gimp_imagefile_check_thumbnail (GimpImagefile *imagefile);
gboolean gimp_imagefile_save_thumbnail (GimpImagefile *imagefile, gboolean gimp_imagefile_save_thumbnail (GimpImagefile *imagefile,
GimpImage *gimage); GimpImage *gimage);
const gchar * gimp_imagefile_get_desc_string (GimpImagefile *imagefile); const gchar * gimp_imagefile_get_desc_string (GimpImagefile *imagefile);

View File

@ -247,7 +247,11 @@ file_open_with_proc_and_display (Gimp *gimp,
*/ */
if (strcmp (uri, gimp_image_get_uri (gimage)) == 0) if (strcmp (uri, gimp_image_get_uri (gimage)) == 0)
{ {
gimp_imagefile_save_thumbnail (imagefile, gimage); /* no need to save a thumbnail if there's a good one already */
if (! gimp_imagefile_check_thumbnail (imagefile))
{
gimp_imagefile_save_thumbnail (imagefile, gimage);
}
} }
gimp_recent_list_add_uri (uri, mime_type); gimp_recent_list_add_uri (uri, mime_type);

View File

@ -677,24 +677,26 @@ gimp_thumb_box_create_thumbnail (GimpThumbBox *box,
if (filename && g_file_test (filename, G_FILE_TEST_IS_REGULAR)) if (filename && g_file_test (filename, G_FILE_TEST_IS_REGULAR))
{ {
gchar *basename = file_utils_uri_to_utf8_basename (uri); GimpThumbnail *thumb = box->imagefile->thumbnail;
gchar *basename;
basename = file_utils_uri_to_utf8_basename (uri);
gtk_label_set_text (GTK_LABEL (box->filename), basename); gtk_label_set_text (GTK_LABEL (box->filename), basename);
g_free (basename); g_free (basename);
if (force)
gimp_thumbs_delete_for_uri (uri);
gimp_object_set_name (GIMP_OBJECT (box->imagefile), uri); gimp_object_set_name (GIMP_OBJECT (box->imagefile), uri);
if (force || if (force ||
gimp_thumbnail_peek_thumb (box->imagefile->thumbnail, size) (gimp_thumbnail_peek_thumb (thumb, size) < GIMP_THUMB_STATE_FAILED &&
< GIMP_THUMB_STATE_FAILED) ! gimp_thumbnail_has_failed (thumb)))
{ {
Gimp *gimp = box->imagefile->gimp;
gimp_imagefile_create_thumbnail (box->imagefile, gimp_imagefile_create_thumbnail (box->imagefile,
gimp_get_user_context (box->imagefile->gimp), gimp_get_user_context (gimp),
GIMP_PROGRESS (box), GIMP_PROGRESS (box),
size); size,
!force);
} }
} }
@ -715,6 +717,7 @@ gimp_thumb_box_auto_thumbnail (GimpThumbBox *box)
case GIMP_THUMB_STATE_NOT_FOUND: case GIMP_THUMB_STATE_NOT_FOUND:
case GIMP_THUMB_STATE_OLD: case GIMP_THUMB_STATE_OLD:
if (thumb->image_filesize < gimp->config->thumbnail_filesize_limit && if (thumb->image_filesize < gimp->config->thumbnail_filesize_limit &&
! gimp_thumbnail_has_failed (thumb) &&
file_utils_find_proc_by_extension (gimp->load_procs, uri)) file_utils_find_proc_by_extension (gimp->load_procs, uri))
{ {
if (thumb->image_filesize > 0) if (thumb->image_filesize > 0)
@ -740,7 +743,8 @@ gimp_thumb_box_auto_thumbnail (GimpThumbBox *box)
gimp_imagefile_create_thumbnail_weak (box->imagefile, gimp_imagefile_create_thumbnail_weak (box->imagefile,
gimp_get_user_context (gimp), gimp_get_user_context (gimp),
GIMP_PROGRESS (box), GIMP_PROGRESS (box),
gimp->config->thumbnail_size); gimp->config->thumbnail_size,
TRUE);
} }
break; break;

View File

@ -1,3 +1,8 @@
2004-10-23 Sven Neumann <sven@gimp.org>
* libgimpthumb/libgimpthumb-sections.txt
* libgimpthumb/tmpl/gimpthumbnail.sgml: updated.
2004-10-14 Sven Neumann <sven@gimp.org> 2004-10-14 Sven Neumann <sven@gimp.org>
* libgimpwidgets/libgimpwidgets-sections.txt: added * libgimpwidgets/libgimpwidgets-sections.txt: added

View File

@ -8,10 +8,15 @@ gimp_thumbnail_set_filename
gimp_thumbnail_set_from_thumb gimp_thumbnail_set_from_thumb
gimp_thumbnail_peek_image gimp_thumbnail_peek_image
gimp_thumbnail_peek_thumb gimp_thumbnail_peek_thumb
gimp_thumbnail_check_thumb
gimp_thumbnail_load_thumb gimp_thumbnail_load_thumb
gimp_thumbnail_save_thumb gimp_thumbnail_save_thumb
gimp_thumbnail_save_failure
gimp_thumbnail_save_thumb_local gimp_thumbnail_save_thumb_local
gimp_thumbnail_save_failure
gimp_thumbnail_delete_failure
gimp_thumbnail_delete_others
gimp_thumbnail_has_failed
<SUBSECTION Standard> <SUBSECTION Standard>
GimpThumbnailClass GimpThumbnailClass
GIMP_THUMBNAIL GIMP_THUMBNAIL

View File

@ -129,6 +129,16 @@ using object properties.
@Returns: @Returns:
<!-- ##### FUNCTION gimp_thumbnail_check_thumb ##### -->
<para>
</para>
@thumbnail:
@size:
@Returns:
<!-- ##### FUNCTION gimp_thumbnail_load_thumb ##### --> <!-- ##### FUNCTION gimp_thumbnail_load_thumb ##### -->
<para> <para>
@ -152,17 +162,6 @@ using object properties.
@Returns: @Returns:
<!-- ##### FUNCTION gimp_thumbnail_save_failure ##### -->
<para>
</para>
@thumbnail:
@software:
@error:
@Returns:
<!-- ##### FUNCTION gimp_thumbnail_save_thumb_local ##### --> <!-- ##### FUNCTION gimp_thumbnail_save_thumb_local ##### -->
<para> <para>
@ -175,3 +174,40 @@ using object properties.
@Returns: @Returns:
<!-- ##### FUNCTION gimp_thumbnail_save_failure ##### -->
<para>
</para>
@thumbnail:
@software:
@error:
@Returns:
<!-- ##### FUNCTION gimp_thumbnail_delete_failure ##### -->
<para>
</para>
@thumbnail:
<!-- ##### FUNCTION gimp_thumbnail_delete_others ##### -->
<para>
</para>
@thumbnail:
@size:
<!-- ##### FUNCTION gimp_thumbnail_has_failed ##### -->
<para>
</para>
@thumbnail:
@Returns:

View File

@ -548,6 +548,30 @@ gimp_thumbs_delete_for_uri_local (const gchar *uri)
} }
} }
void
_gimp_thumbs_delete_others (const gchar *uri,
GimpThumbSize size)
{
gint i;
g_return_if_fail (gimp_thumb_initialized);
g_return_if_fail (uri != NULL);
for (i = 0; i < thumb_num_sizes; i++)
{
if (thumb_sizes[i] != size)
{
gchar *filename = gimp_thumb_name_from_uri (uri, thumb_sizes[i]);
if (filename)
{
unlink (filename);
g_free (filename);
}
}
}
}
static void static void
gimp_thumb_exit (void) gimp_thumb_exit (void)
{ {

View File

@ -57,6 +57,10 @@ gboolean gimp_thumb_ensure_thumb_dir_local (const gchar *dirname,
void gimp_thumbs_delete_for_uri_local (const gchar *uri); void gimp_thumbs_delete_for_uri_local (const gchar *uri);
/* for internal use only */
void _gimp_thumbs_delete_others (const gchar *uri,
GimpThumbSize size);
G_END_DECLS G_END_DECLS

View File

@ -11,7 +11,11 @@ EXPORTS
gimp_thumb_name_from_uri_local gimp_thumb_name_from_uri_local
gimp_thumb_size_get_type gimp_thumb_size_get_type
gimp_thumb_state_get_type gimp_thumb_state_get_type
gimp_thumbnail_check_thumb
gimp_thumbnail_delete_failure
gimp_thumbnail_delete_others
gimp_thumbnail_get_type gimp_thumbnail_get_type
gimp_thumbnail_has_failed
gimp_thumbnail_load_thumb gimp_thumbnail_load_thumb
gimp_thumbnail_new gimp_thumbnail_new
gimp_thumbnail_peek_image gimp_thumbnail_peek_image

View File

@ -561,6 +561,10 @@ gimp_thumbnail_peek_image (GimpThumbnail *thumbnail)
* valid and uptodate for the image file asosciated with the * valid and uptodate for the image file asosciated with the
* @thumbnail. * @thumbnail.
* *
* If you want to check the thumbnail, either attempt to load it using
* gimp_thumbnail_load_thumb(), or, if you don't need the resulting
* thumbnail pixbuf, use gimp_thumbnail_check_thumb().
*
* Return value: the thumbnail's #GimpThumbState after the update * Return value: the thumbnail's #GimpThumbState after the update
**/ **/
GimpThumbState GimpThumbState
@ -582,6 +586,40 @@ gimp_thumbnail_peek_thumb (GimpThumbnail *thumbnail,
return thumbnail->thumb_state; return thumbnail->thumb_state;
} }
/**
* gimp_thumbnail_check_thumb:
* @thumbnail: a #GimpThumbnail object
* @size: the preferred size of the thumbnail image
*
* Checks if a thumbnail file for the @thumbnail exists, loads it and
* verifies it is valid and uptodate for the image file asosciated
* with the @thumbnail.
*
* Return value: the thumbnail's #GimpThumbState after the update
*
* Since: GIMP 2.2
**/
GimpThumbState
gimp_thumbnail_check_thumb (GimpThumbnail *thumbnail,
GimpThumbSize size)
{
GdkPixbuf *pixbuf;
g_return_val_if_fail (GIMP_IS_THUMBNAIL (thumbnail), FALSE);
GIMP_THUMB_DEBUG_CALL (thumbnail);
if (gimp_thumbnail_peek_thumb (thumbnail, size) == GIMP_THUMB_STATE_OK)
return GIMP_THUMB_STATE_OK;
pixbuf = gimp_thumbnail_load_thumb (thumbnail, size, NULL);
if (pixbuf)
g_object_unref (pixbuf);
return thumbnail->thumb_state;
}
static void static void
gimp_thumbnail_update_image (GimpThumbnail *thumbnail) gimp_thumbnail_update_image (GimpThumbnail *thumbnail)
{ {
@ -657,6 +695,11 @@ gimp_thumbnail_update_image (GimpThumbnail *thumbnail)
"image-mtime", mtime, "image-mtime", mtime,
"image-filesize", filesize, "image-filesize", filesize,
NULL); NULL);
if (thumbnail->thumb_state == GIMP_THUMB_STATE_OK)
g_object_set (thumbnail,
"thumb-state", GIMP_THUMB_STATE_OLD,
NULL);
} }
} }
@ -706,8 +749,7 @@ gimp_thumbnail_update_thumb (GimpThumbnail *thumbnail,
if (filename) if (filename)
state = (size > GIMP_THUMB_SIZE_FAIL ? state = (size > GIMP_THUMB_SIZE_FAIL ?
GIMP_THUMB_STATE_EXISTS : GIMP_THUMB_STATE_EXISTS : GIMP_THUMB_STATE_FAILED);
GIMP_THUMB_STATE_FAILED);
thumbnail->thumb_size = size; thumbnail->thumb_size = size;
thumbnail->thumb_filesize = filesize; thumbnail->thumb_filesize = filesize;
@ -887,12 +929,23 @@ gimp_thumbnail_save (GimpThumbnail *thumbnail,
success = (chmod (filename, 0600) == 0); success = (chmod (filename, 0600) == 0);
if (success) if (! success)
gimp_thumbnail_update_thumb (thumbnail, size);
else
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
"Could not set permissions of thumbnail for %s: %s", "Could not set permissions of thumbnail for %s: %s",
thumbnail->image_uri, g_strerror (errno)); thumbnail->image_uri, g_strerror (errno));
g_object_freeze_notify (G_OBJECT (thumbnail));
gimp_thumbnail_update_thumb (thumbnail, size);
if (success &&
thumbnail->thumb_state == GIMP_THUMB_STATE_EXISTS &&
strcmp (filename, thumbnail->thumb_filename) == 0)
{
thumbnail->thumb_state = GIMP_THUMB_STATE_OK;
}
g_object_thaw_notify (G_OBJECT (thumbnail));
} }
unlink (tmpname); unlink (tmpname);
@ -1264,3 +1317,128 @@ gimp_thumbnail_save_failure (GimpThumbnail *thumbnail,
return success; return success;
} }
/**
* gimp_thumbnail_delete_failure:
* @thumbnail: a #GimpThumbnail object
*
* Removes a failure thumbnail if one exists. This function should be
* used after a thumbnail has been successfully created.
*
* Since: GIMP 2.2
**/
void
gimp_thumbnail_delete_failure (GimpThumbnail *thumbnail)
{
gchar *filename;
g_return_if_fail (GIMP_IS_THUMBNAIL (thumbnail));
g_return_if_fail (thumbnail->image_uri != NULL);
GIMP_THUMB_DEBUG_CALL (thumbnail);
filename = gimp_thumb_name_from_uri (thumbnail->image_uri,
GIMP_THUMB_SIZE_FAIL);
if (filename)
{
unlink (filename);
g_free (filename);
}
}
/**
* gimp_thumbnail_delete_others:
* @thumbnail: a #GimpThumbnail object
* @size: the thumbnail size which should not be deleted
*
* Removes all other thumbnails from the global thumbnail
* repository. Only the thumbnail for @size is not deleted. This
* function should be used after a thumbnail has been successfully
* updated. See the spec for a more detailed description on when to
* delete thumbnails.
*
* Since: GIMP 2.2
**/
void
gimp_thumbnail_delete_others (GimpThumbnail *thumbnail,
GimpThumbSize size)
{
g_return_if_fail (GIMP_IS_THUMBNAIL (thumbnail));
g_return_if_fail (thumbnail->image_uri != NULL);
GIMP_THUMB_DEBUG_CALL (thumbnail);
_gimp_thumbs_delete_others (thumbnail->image_uri, size);
}
/**
* gimp_thumbnail_has_failed:
* @thumbnail: a #GimpThumbnail object
*
* Checks if a valid failure thumbnail for the given thumbnail exists
* in the global thumbnail repository. This may be the case even if
* gimp_thumbnail_peek_thumb() doesn't return %GIMP_THUMB_STATE_FAILED
* since there might be a real thumbnail and a failure thumbnail for
* the same image file.
*
* The application should not attempt to create the thumbnail if a
* valid failure thumbnail exists.
*
* Return value: %TRUE if a failure thumbnail exists or
*
* Since: GIMP 2.2
**/
gboolean
gimp_thumbnail_has_failed (GimpThumbnail *thumbnail)
{
GdkPixbuf *pixbuf;
const gchar *option;
gchar *filename;
gint64 image_mtime;
gint64 image_size;
gboolean failed = FALSE;
g_return_val_if_fail (GIMP_IS_THUMBNAIL (thumbnail), FALSE);
g_return_val_if_fail (thumbnail->image_uri != NULL, FALSE);
GIMP_THUMB_DEBUG_CALL (thumbnail);
filename = gimp_thumb_name_from_uri (thumbnail->image_uri,
GIMP_THUMB_SIZE_FAIL);
if (! filename)
return FALSE;
pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
g_free (filename);
if (! pixbuf)
return FALSE;
if (gimp_thumbnail_peek_image (thumbnail) < GIMP_THUMB_STATE_EXISTS)
goto finish;
/* URI and mtime from the thumbnail need to match our file */
option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_URI);
if (! option || strcmp (option, thumbnail->image_uri))
goto finish;
option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_MTIME);
if (!option || sscanf (option, "%" G_GINT64_FORMAT, &image_mtime) != 1)
goto finish;
option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_FILESIZE);
if (option && sscanf (option, "%" G_GINT64_FORMAT, &image_size) != 1)
goto finish;
/* TAG_THUMB_FILESIZE is optional but must match if present */
if (image_mtime == thumbnail->image_mtime &&
(option == NULL || image_size == thumbnail->image_filesize))
{
failed = TRUE;
}
finish:
g_object_unref (pixbuf);
return failed;
}

View File

@ -94,21 +94,31 @@ GimpThumbState gimp_thumbnail_peek_image (GimpThumbnail *thumbnail);
GimpThumbState gimp_thumbnail_peek_thumb (GimpThumbnail *thumbnail, GimpThumbState gimp_thumbnail_peek_thumb (GimpThumbnail *thumbnail,
GimpThumbSize size); GimpThumbSize size);
GimpThumbState gimp_thumbnail_check_thumb (GimpThumbnail *thumbnail,
GimpThumbSize size);
GdkPixbuf * gimp_thumbnail_load_thumb (GimpThumbnail *thumbnail, GdkPixbuf * gimp_thumbnail_load_thumb (GimpThumbnail *thumbnail,
GimpThumbSize size, GimpThumbSize size,
GError **error); GError **error);
gboolean gimp_thumbnail_save_thumb (GimpThumbnail *thumbnail, gboolean gimp_thumbnail_save_thumb (GimpThumbnail *thumbnail,
GdkPixbuf *pixbuf, GdkPixbuf *pixbuf,
const gchar *software, const gchar *software,
GError **error); GError **error);
gboolean gimp_thumbnail_save_failure (GimpThumbnail *thumbnail,
const gchar *software,
GError **error);
gboolean gimp_thumbnail_save_thumb_local (GimpThumbnail *thumbnail, gboolean gimp_thumbnail_save_thumb_local (GimpThumbnail *thumbnail,
GdkPixbuf *pixbuf, GdkPixbuf *pixbuf,
const gchar *software, const gchar *software,
GError **error); GError **error);
gboolean gimp_thumbnail_save_failure (GimpThumbnail *thumbnail,
const gchar *software,
GError **error);
void gimp_thumbnail_delete_failure (GimpThumbnail *thumbnail);
void gimp_thumbnail_delete_others (GimpThumbnail *thumbnail,
GimpThumbSize size);
gboolean gimp_thumbnail_has_failed (GimpThumbnail *thumbnail);
G_END_DECLS G_END_DECLS