aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/image.c33
2 files changed, 36 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 6ee3ec6f089..9087f8b12b8 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): Animate correctly
4 when sub-images are smaller than the main image.
5
12013-08-15 Jan Djärv <jan.h.d@swipnet.se> 62013-08-15 Jan Djärv <jan.h.d@swipnet.se>
2 7
3 * nsmenu.m (menuWillOpen:): Fix preprocessor test (Bug#15001). 8 * nsmenu.m (menuWillOpen:): Fix preprocessor test (Bug#15001).
diff --git a/src/image.c b/src/image.c
index bc9f9ab123a..348f6a8209b 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7879,6 +7879,7 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7879{ 7879{
7880 int i; 7880 int i;
7881 MagickWand *composite_wand; 7881 MagickWand *composite_wand;
7882 size_t dest_width, dest_height;
7882 7883
7883 MagickSetIteratorIndex (super_wand, 0); 7884 MagickSetIteratorIndex (super_wand, 0);
7884 7885
@@ -7887,18 +7888,36 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7887 else 7888 else
7888 composite_wand = animation_cache; 7889 composite_wand = animation_cache;
7889 7890
7891 dest_width = MagickGetImageWidth (composite_wand);
7892 dest_height = MagickGetImageHeight (composite_wand);
7893
7890 for (i = max (1, animation_index + 1); i <= ino; i++) 7894 for (i = max (1, animation_index + 1); i <= ino; i++)
7891 { 7895 {
7892 MagickWand *sub_wand; 7896 MagickWand *sub_wand;
7893 PixelIterator *source_iterator, *dest_iterator; 7897 PixelIterator *source_iterator, *dest_iterator;
7894 PixelWand **source, **dest; 7898 PixelWand **source, **dest;
7895 size_t source_width, dest_width; 7899 size_t source_width, source_height;
7900 ssize_t source_left, source_top;
7896 MagickPixelPacket pixel; 7901 MagickPixelPacket pixel;
7897 DisposeType dispose; 7902 DisposeType dispose;
7898 7903
7899 MagickSetIteratorIndex (super_wand, i); 7904 MagickSetIteratorIndex (super_wand, i);
7900 sub_wand = MagickGetImage (super_wand); 7905 sub_wand = MagickGetImage (super_wand);
7901 7906
7907 MagickGetImagePage (sub_wand, &source_width, &source_height,
7908 &source_left, &source_top);
7909
7910 /* Sanity check. The sub-image should not be bigger than the
7911 base image. */
7912 if (source_height + source_top > dest_height)
7913 {
7914 DestroyMagickWand (composite_wand);
7915 DestroyMagickWand (sub_wand);
7916 animation_cache = NULL;
7917 image_error ("Inconsinstent animation size", Qnil, Qnil);
7918 return NULL;
7919 }
7920
7902 dispose = MagickGetImageDispose (sub_wand); 7921 dispose = MagickGetImageDispose (sub_wand);
7903 7922
7904 source_iterator = NewPixelIterator (sub_wand); 7923 source_iterator = NewPixelIterator (sub_wand);
@@ -7906,6 +7925,7 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7906 { 7925 {
7907 DestroyMagickWand (composite_wand); 7926 DestroyMagickWand (composite_wand);
7908 DestroyMagickWand (sub_wand); 7927 DestroyMagickWand (sub_wand);
7928 animation_cache = NULL;
7909 image_error ("Imagemagick pixel iterator creation failed", 7929 image_error ("Imagemagick pixel iterator creation failed",
7910 Qnil, Qnil); 7930 Qnil, Qnil);
7911 return NULL; 7931 return NULL;
@@ -7917,11 +7937,16 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7917 DestroyMagickWand (composite_wand); 7937 DestroyMagickWand (composite_wand);
7918 DestroyMagickWand (sub_wand); 7938 DestroyMagickWand (sub_wand);
7919 DestroyPixelIterator (source_iterator); 7939 DestroyPixelIterator (source_iterator);
7940 animation_cache = NULL;
7920 image_error ("Imagemagick pixel iterator creation failed", 7941 image_error ("Imagemagick pixel iterator creation failed",
7921 Qnil, Qnil); 7942 Qnil, Qnil);
7922 return NULL; 7943 return NULL;
7923 } 7944 }
7924 7945
7946 /* The sub-image may not start at origo, so move the destination
7947 iterator to where the sub-image should start. */
7948 PixelSetIteratorRow (dest_iterator, source_top);
7949
7925 while ((source = PixelGetNextIteratorRow (source_iterator, &source_width)) 7950 while ((source = PixelGetNextIteratorRow (source_iterator, &source_width))
7926 != NULL) 7951 != NULL)
7927 { 7952 {
@@ -7929,6 +7954,10 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7929 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width); 7954 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width);
7930 for (x = 0; x < source_width; x++) 7955 for (x = 0; x < source_width; x++)
7931 { 7956 {
7957 /* Sanity check. This shouldn't happen, but apparently
7958 does in some pictures. */
7959 if (x + source_left > dest_width)
7960 break;
7932 /* Normally we only copy over non-transparent pixels, 7961 /* Normally we only copy over non-transparent pixels,
7933 but if the disposal method is "Background", then we 7962 but if the disposal method is "Background", then we
7934 copy over all pixels. */ 7963 copy over all pixels. */
@@ -7936,7 +7965,7 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7936 PixelGetAlpha (source[x])) 7965 PixelGetAlpha (source[x]))
7937 { 7966 {
7938 PixelGetMagickColor (source[x], &pixel); 7967 PixelGetMagickColor (source[x], &pixel);
7939 PixelSetMagickColor (dest[x], &pixel); 7968 PixelSetMagickColor (dest[x + source_left], &pixel);
7940 } 7969 }
7941 } 7970 }
7942 PixelSyncIterator(dest_iterator); 7971 PixelSyncIterator(dest_iterator);