aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Ingebrigtsen2022-04-11 16:52:34 +0200
committerLars Ingebrigtsen2022-04-11 16:52:34 +0200
commit0e7185cefae6033e2e0628ce91009e1fbf328206 (patch)
tree4713536394b95a134a738653b1e114e91ad3285a /src
parentbe48dfe0b3a80c0896f4d562c6a8f428ec91d19e (diff)
downloademacs-0e7185cefae6033e2e0628ce91009e1fbf328206.tar.gz
emacs-0e7185cefae6033e2e0628ce91009e1fbf328206.zip
Make gif_load work across architectures again
* src/image.c (gif_load): Invert the way animated pixmaps are created: Work on the cached computed-so-far pixmap, and then copy the entire thing to the ximg with PUT_PIXEL at the end. This should work across platforms, which the previous version didn't.
Diffstat (limited to 'src')
-rw-r--r--src/image.c62
1 files changed, 39 insertions, 23 deletions
diff --git a/src/image.c b/src/image.c
index f28eb5eb6e1..d6c2af7f199 100644
--- a/src/image.c
+++ b/src/image.c
@@ -8775,6 +8775,7 @@ gif_load (struct frame *f, struct image *img)
8775 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); 8775 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8776 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); 8776 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
8777 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL); 8777 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
8778 unsigned long *pixmap = NULL;
8778 EMACS_INT idx = -1; 8779 EMACS_INT idx = -1;
8779 int gif_err; 8780 int gif_err;
8780 struct anim_cache* cache = NULL; 8781 struct anim_cache* cache = NULL;
@@ -8794,7 +8795,10 @@ gif_load (struct frame *f, struct image *img)
8794 /* We have an old cache entry, and it looks correct, so use 8795 /* We have an old cache entry, and it looks correct, so use
8795 it. */ 8796 it. */
8796 if (cache->index == idx - 1) 8797 if (cache->index == idx - 1)
8797 gif = cache->handle; 8798 {
8799 gif = cache->handle;
8800 pixmap = cache->temp;
8801 }
8798 } 8802 }
8799 } 8803 }
8800 8804
@@ -8958,6 +8962,15 @@ gif_load (struct frame *f, struct image *img)
8958 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 8962 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
8959 goto gif_error; 8963 goto gif_error;
8960 8964
8965 /* We construct the (possibly composited animated) image in this
8966 buffer. */
8967 if (!pixmap)
8968 {
8969 pixmap = xmalloc (width * height * sizeof (unsigned long));
8970 if (cache)
8971 cache->temp = pixmap;
8972 }
8973
8961 /* Clear the part of the screen image not covered by the image. 8974 /* Clear the part of the screen image not covered by the image.
8962 Full animated GIF support requires more here (see the gif89 spec, 8975 Full animated GIF support requires more here (see the gif89 spec,
8963 disposal methods). Let's simply assume that the part not covered 8976 disposal methods). Let's simply assume that the part not covered
@@ -8972,20 +8985,21 @@ gif_load (struct frame *f, struct image *img)
8972 frame_bg = lookup_rgb_color (f, color.red, color.green, color.blue); 8985 frame_bg = lookup_rgb_color (f, color.red, color.green, color.blue);
8973 } 8986 }
8974#endif /* USE_CAIRO */ 8987#endif /* USE_CAIRO */
8988
8975 for (y = 0; y < img->corners[TOP_CORNER]; ++y) 8989 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
8976 for (x = 0; x < width; ++x) 8990 for (x = 0; x < width; ++x)
8977 PUT_PIXEL (ximg, x, y, frame_bg); 8991 *(pixmap + x + y * width) = frame_bg;
8978 8992
8979 for (y = img->corners[BOT_CORNER]; y < height; ++y) 8993 for (y = img->corners[BOT_CORNER]; y < height; ++y)
8980 for (x = 0; x < width; ++x) 8994 for (x = 0; x < width; ++x)
8981 PUT_PIXEL (ximg, x, y, frame_bg); 8995 *(pixmap + x + y * width) = frame_bg;
8982 8996
8983 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y) 8997 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
8984 { 8998 {
8985 for (x = 0; x < img->corners[LEFT_CORNER]; ++x) 8999 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
8986 PUT_PIXEL (ximg, x, y, frame_bg); 9000 *(pixmap + x + y * width) = frame_bg;
8987 for (x = img->corners[RIGHT_CORNER]; x < width; ++x) 9001 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
8988 PUT_PIXEL (ximg, x, y, frame_bg); 9002 *(pixmap + x + y * width) = frame_bg;
8989 } 9003 }
8990 9004
8991 /* Read the GIF image into the X image. */ 9005 /* Read the GIF image into the X image. */
@@ -9006,13 +9020,12 @@ gif_load (struct frame *f, struct image *img)
9006 9020
9007 int start_frame = 0; 9021 int start_frame = 0;
9008 9022
9009 /* We have animation data in the cache, so copy it over so that we 9023 /* We have animation data in the cache. */
9010 can alter it. */
9011 int cache_image_size = width * height * ximg->bits_per_pixel / 8;
9012 if (cache && cache->temp) 9024 if (cache && cache->temp)
9013 { 9025 {
9014 memcpy (ximg->data, cache->temp, cache_image_size); 9026 start_frame = cache->index + 1;
9015 start_frame = cache->index; 9027 if (start_frame > idx)
9028 start_frame = 0;
9016 cache->index = idx; 9029 cache->index = idx;
9017 } 9030 }
9018 9031
@@ -9106,8 +9119,8 @@ gif_load (struct frame *f, struct image *img)
9106 int c = raster[y * subimg_width + x]; 9119 int c = raster[y * subimg_width + x];
9107 if (transparency_color_index != c || disposal != DISPOSE_DO_NOT) 9120 if (transparency_color_index != c || disposal != DISPOSE_DO_NOT)
9108 { 9121 {
9109 PUT_PIXEL (ximg, x + subimg_left, row + subimg_top, 9122 *(pixmap + x + subimg_left + (y + subimg_top) * width) =
9110 pixel_colors[c]); 9123 pixel_colors[c];
9111 } 9124 }
9112 } 9125 }
9113 } 9126 }
@@ -9120,21 +9133,18 @@ gif_load (struct frame *f, struct image *img)
9120 int c = raster[y * subimg_width + x]; 9133 int c = raster[y * subimg_width + x];
9121 if (transparency_color_index != c || disposal != DISPOSE_DO_NOT) 9134 if (transparency_color_index != c || disposal != DISPOSE_DO_NOT)
9122 { 9135 {
9123 PUT_PIXEL (ximg, x + subimg_left, y + subimg_top, 9136 *(pixmap + x + subimg_left + (y + subimg_top) * width) =
9124 pixel_colors[c]); 9137 pixel_colors[c];
9125 } 9138 }
9126 } 9139 }
9127 } 9140 }
9128 } 9141 }
9129 9142
9130 if (cache) 9143 /* We now have the complete image (possibly composed from a series
9131 { 9144 of animated frames) in pixmap. Put it into ximg. */
9132 /* Allocate an area to store what we have computed so far. */ 9145 for (y = 0; y < height; ++y)
9133 if (! cache->temp) 9146 for (x = 0; x < width; ++x)
9134 cache->temp = xmalloc (cache_image_size); 9147 PUT_PIXEL (ximg, x, y, *(pixmap + x + y * width));
9135 /* Copy over the data to the cache. */
9136 memcpy (cache->temp, ximg->data, cache_image_size);
9137 }
9138 9148
9139#ifdef COLOR_TABLE_SUPPORT 9149#ifdef COLOR_TABLE_SUPPORT
9140 img->colors = colors_in_color_table (&img->ncolors); 9150 img->colors = colors_in_color_table (&img->ncolors);
@@ -9178,6 +9188,8 @@ gif_load (struct frame *f, struct image *img)
9178 9188
9179 if (!cache) 9189 if (!cache)
9180 { 9190 {
9191 if (pixmap)
9192 xfree (pixmap);
9181 if (gif_close (gif, &gif_err) == GIF_ERROR) 9193 if (gif_close (gif, &gif_err) == GIF_ERROR)
9182 { 9194 {
9183#if HAVE_GIFERRORSTRING 9195#if HAVE_GIFERRORSTRING
@@ -9204,7 +9216,11 @@ gif_load (struct frame *f, struct image *img)
9204 9216
9205 gif_error: 9217 gif_error:
9206 if (!cache) 9218 if (!cache)
9207 gif_close (gif, NULL); 9219 {
9220 if (pixmap)
9221 xfree (pixmap);
9222 gif_close (gif, NULL);
9223 }
9208 return false; 9224 return false;
9209} 9225}
9210 9226