diff options
| author | Lars Magne Ingebrigtsen | 2013-08-15 20:34:23 +0200 |
|---|---|---|
| committer | Lars Magne Ingebrigtsen | 2013-08-15 20:34:23 +0200 |
| commit | 703dbebab0c46f059593df55698c488df15dd806 (patch) | |
| tree | 4f33b11768d9bf4575b196ba43d1ec62a7a26136 /src/image.c | |
| parent | 63216c5ee19df8da21574fd5fbafeea8321433a9 (diff) | |
| download | emacs-703dbebab0c46f059593df55698c488df15dd806.tar.gz emacs-703dbebab0c46f059593df55698c488df15dd806.zip | |
image.c animation touchups
* image.c (imagemagick_compute_animated_image): Animate correctly
when sub-images are smaller than the main image.
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 33 |
1 files changed, 31 insertions, 2 deletions
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); |