aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2013-08-15 17:10:12 +0200
committerLars Magne Ingebrigtsen2013-08-15 17:10:12 +0200
commit6e856b69ffea045be4efe029ecbb44df7fd4da21 (patch)
tree879a1aa007a10e5fc4135ffb96dc3e2428c19839
parentd5a1acfaa5671f09cbb8da211a5283394d8b907f (diff)
downloademacs-6e856b69ffea045be4efe029ecbb44df7fd4da21.tar.gz
emacs-6e856b69ffea045be4efe029ecbb44df7fd4da21.zip
* image.c (imagemagick_compute_animated_image): Implement animated images.
Fixes: debbugs:14700
-rw-r--r--src/ChangeLog5
-rw-r--r--src/image.c79
2 files changed, 80 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1ad3e1cff24..5131f666c6e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
12013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * image.c (imagemagick_compute_animated_image): Implement animated
4 images (bug#14700).
5
12013-08-15 Dmitry Antipov <dmantipov@yandex.ru> 62013-08-15 Dmitry Antipov <dmantipov@yandex.ru>
2 7
3 * lisp.h (FOR_EACH_ALIST_VALUE): New macro 8 * lisp.h (FOR_EACH_ALIST_VALUE): New macro
diff --git a/src/image.c b/src/image.c
index 8d969a6f9c6..c534f181e5c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7864,6 +7864,75 @@ imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
7864 return hint_buffer; 7864 return hint_buffer;
7865} 7865}
7866 7866
7867/* Animated images (e.g., GIF89a) are composed from one "master image"
7868 (which is the first one, and then there's a number of images that
7869 follow. If following images have non-transparent colors, these are
7870 composed "on top" of the master image. So, in general, one has to
7871 compute ann the preceding images to be able to display a particular
7872 sub-image. */
7873
7874static MagickWand *
7875imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7876{
7877 MagickWand *composite_wand;
7878
7879 MagickSetIteratorIndex (super_wand, 0);
7880 composite_wand = MagickGetImage (super_wand);
7881
7882 for (int i = 1; i <= ino; i++) {
7883 MagickWand *sub_wand;
7884 PixelIterator *source_iterator, *dest_iterator;
7885 PixelWand **source, **dest;
7886 long source_width, dest_width;
7887 MagickPixelPacket pixel;
7888
7889 MagickSetIteratorIndex (super_wand, i);
7890 sub_wand = MagickGetImage (super_wand);
7891
7892 source_iterator = NewPixelIterator (sub_wand);
7893 if (! source_iterator)
7894 {
7895 DestroyMagickWand (composite_wand);
7896 DestroyMagickWand (sub_wand);
7897 image_error ("Imagemagick pixel iterator creation failed",
7898 Qnil, Qnil);
7899 return NULL;
7900 }
7901
7902 dest_iterator = NewPixelIterator (composite_wand);
7903 if (! dest_iterator)
7904 {
7905 DestroyMagickWand (composite_wand);
7906 DestroyMagickWand (sub_wand);
7907 DestroyPixelIterator (source_iterator);
7908 image_error ("Imagemagick pixel iterator creation failed",
7909 Qnil, Qnil);
7910 return NULL;
7911 }
7912
7913 while (source = PixelGetNextIteratorRow (source_iterator, &source_width)) {
7914 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width);
7915 for (int x = 0; x < source_width; x++)
7916 {
7917 /* Copy over non-transparent pixels. */
7918 if (PixelGetAlpha (source[x]))
7919 {
7920 PixelGetMagickColor (source[x], &pixel);
7921 PixelSetMagickColor (dest[x], &pixel);
7922 }
7923 }
7924 PixelSyncIterator(dest_iterator);
7925 }
7926
7927 DestroyPixelIterator (source_iterator);
7928 DestroyPixelIterator (dest_iterator);
7929 DestroyMagickWand (sub_wand);
7930 }
7931
7932 return composite_wand;
7933}
7934
7935
7867/* Helper function for imagemagick_load, which does the actual loading 7936/* Helper function for imagemagick_load, which does the actual loading
7868 given contents and size, apart from frame and image structures, 7937 given contents and size, apart from frame and image structures,
7869 passed from imagemagick_load. Uses librimagemagick to do most of 7938 passed from imagemagick_load. Uses librimagemagick to do most of
@@ -7965,12 +8034,14 @@ imagemagick_load_image (struct frame *f, struct image *img,
7965 8034
7966 /* If we have an animated image, get the new wand based on the 8035 /* If we have an animated image, get the new wand based on the
7967 "super-wand". */ 8036 "super-wand". */
7968 if (ino > 0) 8037 if (MagickGetNumberImages (image_wand) > 1)
7969 { 8038 {
7970 MagickWand *super_wand = image_wand; 8039 MagickWand *super_wand = image_wand;
7971 MagickSetIteratorIndex (super_wand, ino); 8040 image_wand = imagemagick_compute_animated_image (super_wand, ino);
7972 image_wand = MagickGetImage (super_wand); 8041 if (! image_wand)
7973 DestroyMagickWand (super_wand); 8042 image_wand = super_wand;
8043 else
8044 DestroyMagickWand (super_wand);
7974 } 8045 }
7975 8046
7976 /* Retrieve the frame's background color, for use later. */ 8047 /* Retrieve the frame's background color, for use later. */