summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2022-07-14 11:40:49 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2022-07-14 11:49:47 +0200
commit4738aa1e12460ecf55ef08b72c585cbbafe51520 (patch)
tree3f385c353f9928689f10f06b7ce5851b5fbfb38d
parent3ec7b278521c19b435a7168e55ddbdd918817edd (diff)
downloademacs-4738aa1e12460ecf55ef08b72c585cbbafe51520.tar.gz
Make clear-image-cache clear the animation cache
* src/dispextern.h: Declare image_prune_animation_caches for use in gc. * src/image.c (Fclear_image_cache): Clear animation cache. (anim_prune_animation_cache, anim_get_animation_cache): Allow clearing in addition to pruning. (imagemagick_prune_animation_cache) (imagemagick_get_animation_cache): Ditto. (image_prune_animation_caches): New function (bug#56546).
-rw-r--r--src/dispextern.h1
-rw-r--r--src/image.c41
2 files changed, 30 insertions, 12 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index ca7834dec55..916dba53198 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3540,6 +3540,7 @@ struct image_cache *make_image_cache (void);
void free_image_cache (struct frame *);
void clear_image_caches (Lisp_Object);
void mark_image_cache (struct image_cache *);
+void image_prune_animation_caches (bool);
bool valid_image_p (Lisp_Object);
void prepare_image_for_display (struct frame *, struct image *);
ptrdiff_t lookup_image (struct frame *, Lisp_Object, int);
diff --git a/src/image.c b/src/image.c
index c0a7b85cb3b..aa7bb3ba667 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2133,6 +2133,9 @@ which is then usually a filename. */)
else
clear_image_cache (decode_window_system_frame (filter), Qt);
+ /* Also clear the animation caches. */
+ image_prune_animation_caches (true);
+
return Qnil;
}
@@ -3046,9 +3049,10 @@ anim_create_cache (Lisp_Object spec)
return cache;
}
-/* Discard cached images that haven't been used for a minute. */
+/* Discard cached images that haven't been used for a minute. If
+ CLEAR, remove all animation cache entries. */
static void
-anim_prune_animation_cache (void)
+anim_prune_animation_cache (bool clear)
{
struct anim_cache **pcache = &anim_cache;
struct timespec old = timespec_sub (current_timespec (),
@@ -3057,9 +3061,7 @@ anim_prune_animation_cache (void)
while (*pcache)
{
struct anim_cache *cache = *pcache;
- if (timespec_cmp (old, cache->update_time) <= 0)
- pcache = &cache->next;
- else
+ if (clear || timespec_cmp (old, cache->update_time) > 0)
{
if (cache->handle)
cache->destructor (cache);
@@ -3068,6 +3070,8 @@ anim_prune_animation_cache (void)
*pcache = cache->next;
xfree (cache);
}
+ else
+ pcache = &cache->next;
}
}
@@ -3077,7 +3081,7 @@ anim_get_animation_cache (Lisp_Object spec)
struct anim_cache *cache;
struct anim_cache **pcache = &anim_cache;
- anim_prune_animation_cache ();
+ anim_prune_animation_cache (false);
while (1)
{
@@ -10082,9 +10086,10 @@ imagemagick_create_cache (char *signature)
return cache;
}
-/* Discard cached images that haven't been used for a minute. */
+/* Discard cached images that haven't been used for a minute. If
+ CLEAR, discard all cached animated images. */
static void
-imagemagick_prune_animation_cache (void)
+imagemagick_prune_animation_cache (bool clear)
{
struct animation_cache **pcache = &animation_cache;
struct timespec old = timespec_sub (current_timespec (),
@@ -10093,15 +10098,15 @@ imagemagick_prune_animation_cache (void)
while (*pcache)
{
struct animation_cache *cache = *pcache;
- if (timespec_cmp (old, cache->update_time) <= 0)
- pcache = &cache->next;
- else
+ if (clear || timespec_cmp (old, cache->update_time) > 0)
{
if (cache->wand)
DestroyMagickWand (cache->wand);
*pcache = cache->next;
xfree (cache);
}
+ else
+ pcache = &cache->next;
}
}
@@ -10112,7 +10117,7 @@ imagemagick_get_animation_cache (MagickWand *wand)
struct animation_cache *cache;
struct animation_cache **pcache = &animation_cache;
- imagemagick_prune_animation_cache ();
+ imagemagick_prune_animation_cache (false);
while (1)
{
@@ -11951,6 +11956,18 @@ lookup_image_type (Lisp_Object type)
return NULL;
}
+/* Prune the animation caches. If CLEAR, remove all animation cache
+ entries. */
+void
+image_prune_animation_caches (bool clear)
+{
+#if defined (HAVE_WEBP) || defined (HAVE_GIF)
+ anim_prune_animation_cache (clear);
+#endif
+#ifdef HAVE_IMAGEMAGICK
+ imagemagick_prune_animation_cache (clear);
+#endif
+}
void
syms_of_image (void)