* image.c: Shrink memory needed for animation cache.

(SIGNATURE_DIGESTSIZE): New constant.
(struct animation_cache): Make 'signature' a fixed size array of bytes.
(imagemagick_create_cache): Copy the signature.  This saves
several KB of memory that ImageMagick wastes per signature.
Don't bother updating the update_time, as the caller does that now.
(imagemagick_prune_animation_cache): Don't destroy the signature, as
it's a fixed size struct member now.
(imagemagick_get_animation_cache): Always destroy the signature,
as it's now imagemagick_create_cache's responsibility to copy it.
Avoid duplicate calls to strcmp and to imagemagick_create_cache,
and use memcmp rather than strcmp.
eassert that ImageMagick returns a signature of the specified length.
This commit is contained in:
Paul Eggert 2013-08-19 13:47:27 -07:00
parent 453f40228f
commit bb566ceafe
2 changed files with 34 additions and 18 deletions

View file

@ -1,3 +1,19 @@
2013-08-19 Paul Eggert <eggert@cs.ucla.edu>
* image.c: Shrink memory needed for animation cache.
(SIGNATURE_DIGESTSIZE): New constant.
(struct animation_cache): Make 'signature' a fixed size array of bytes.
(imagemagick_create_cache): Copy the signature. This saves
several KB of memory that ImageMagick wastes per signature.
Don't bother updating the update_time, as the caller does that now.
(imagemagick_prune_animation_cache): Don't destroy the signature, as
it's a fixed size struct member now.
(imagemagick_get_animation_cache): Always destroy the signature,
as it's now imagemagick_create_cache's responsibility to copy it.
Avoid duplicate calls to strcmp and to imagemagick_create_cache,
and use memcmp rather than strcmp.
eassert that ImageMagick returns a signature of the specified length.
2013-08-19 Lars Magne Ingebrigtsen <larsi@gnus.org>
* image.c (imagemagick_get_animation_cache): Don't segfault on

View file

@ -7876,13 +7876,17 @@ imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
separate from the image cache, because the images may be scaled
before display. */
/* Size of ImageMagick image signatures, in bytes. It's SHA-256 as a
hex string, so it's 256 bits represented via 4 bits per byte. */
enum { SIGNATURE_DIGESTSIZE = 256 / 4 };
struct animation_cache
{
char *signature;
MagickWand *wand;
int index;
EMACS_TIME update_time;
struct animation_cache *next;
char signature[SIGNATURE_DIGESTSIZE];
};
static struct animation_cache *animation_cache = NULL;
@ -7891,11 +7895,10 @@ static struct animation_cache *
imagemagick_create_cache (char *signature)
{
struct animation_cache *cache = xmalloc (sizeof *cache);
cache->signature = signature;
cache->wand = 0;
cache->index = 0;
cache->next = 0;
cache->update_time = current_emacs_time ();
memcpy (cache->signature, signature, SIGNATURE_DIGESTSIZE);
return cache;
}
@ -7914,7 +7917,6 @@ imagemagick_prune_animation_cache (void)
pcache = &cache->next;
else
{
DestroyString (cache->signature);
if (cache->wand)
DestroyMagickWand (cache->wand);
*pcache = cache->next;
@ -7928,24 +7930,22 @@ imagemagick_get_animation_cache (MagickWand *wand)
{
char *signature = MagickGetImageSignature (wand);
struct animation_cache *cache;
struct animation_cache **pcache = &animation_cache;
eassert (strlen (signature) == SIGNATURE_DIGESTSIZE);
imagemagick_prune_animation_cache ();
cache = animation_cache;
if (! cache)
while (1)
{
animation_cache = imagemagick_create_cache (signature);
return animation_cache;
}
while (strcmp (signature, cache->signature) &&
cache->next)
cache = cache->next;
if (strcmp (signature, cache->signature))
{
cache->next = imagemagick_create_cache (signature);
return cache->next;
cache = *pcache;
if (! cache)
{
*pcache = cache = imagemagick_create_cache (signature);
break;
}
if (memcmp (signature, cache->signature, SIGNATURE_DIGESTSIZE) == 0)
break;
pcache = &cache->next;
}
DestroyString (signature);