aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorStefan Monnier2012-03-25 16:37:21 -0400
committerStefan Monnier2012-03-25 16:37:21 -0400
commit699c782b7668c44d0fa4446331b0590a6d5dac82 (patch)
tree5dcce364741d0761920a3d274b0fc8aba4103d45 /src/image.c
parent98fb480ee31bf74cf554044f60f21df16566dd7f (diff)
parente99a9b8bdccadded1f6fae88ee7a2a93dfd4eacf (diff)
downloademacs-pending.tar.gz
emacs-pending.zip
Merge from trunkpending
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c674
1 files changed, 405 insertions, 269 deletions
diff --git a/src/image.c b/src/image.c
index 6e8440fb431..73490fe2865 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1,5 +1,5 @@
1/* Functions for image support on window system. 1/* Functions for image support on window system.
2 Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc. 2 Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -56,7 +56,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
56#define COLOR_TABLE_SUPPORT 1 56#define COLOR_TABLE_SUPPORT 1
57 57
58typedef struct x_bitmap_record Bitmap_Record; 58typedef struct x_bitmap_record Bitmap_Record;
59#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y) 59#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
60#define NO_PIXMAP None 60#define NO_PIXMAP None
61 61
62#define RGB_PIXEL_COLOR unsigned long 62#define RGB_PIXEL_COLOR unsigned long
@@ -74,7 +74,7 @@ typedef struct x_bitmap_record Bitmap_Record;
74#undef COLOR_TABLE_SUPPORT 74#undef COLOR_TABLE_SUPPORT
75 75
76typedef struct w32_bitmap_record Bitmap_Record; 76typedef struct w32_bitmap_record Bitmap_Record;
77#define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y) 77#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
78#define NO_PIXMAP 0 78#define NO_PIXMAP 0
79 79
80#define RGB_PIXEL_COLOR COLORREF 80#define RGB_PIXEL_COLOR COLORREF
@@ -106,7 +106,7 @@ Lisp_Object Qlibpng_version;
106 106
107typedef struct ns_bitmap_record Bitmap_Record; 107typedef struct ns_bitmap_record Bitmap_Record;
108 108
109#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y) 109#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
110#define NO_PIXMAP 0 110#define NO_PIXMAP 0
111 111
112#define RGB_PIXEL_COLOR unsigned long 112#define RGB_PIXEL_COLOR unsigned long
@@ -115,7 +115,7 @@ typedef struct ns_bitmap_record Bitmap_Record;
115#define PIX_MASK_RETAIN 0 115#define PIX_MASK_RETAIN 0
116#define PIX_MASK_DRAW 1 116#define PIX_MASK_DRAW 1
117 117
118#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual 118#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO (f)->visual
119#define x_defined_color(f, name, color_def, alloc) \ 119#define x_defined_color(f, name, color_def, alloc) \
120 ns_defined_color (f, name, color_def, alloc, 0) 120 ns_defined_color (f, name, color_def, alloc, 0)
121#define FRAME_X_SCREEN(f) 0 121#define FRAME_X_SCREEN(f) 0
@@ -136,7 +136,6 @@ static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
136#ifdef COLOR_TABLE_SUPPORT 136#ifdef COLOR_TABLE_SUPPORT
137static void free_color_table (void); 137static void free_color_table (void);
138static unsigned long *colors_in_color_table (int *n); 138static unsigned long *colors_in_color_table (int *n);
139static unsigned long lookup_pixel_color (struct frame *f, unsigned long p);
140#endif 139#endif
141static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object); 140static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object);
142 141
@@ -197,6 +196,7 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
197int 196int
198x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) 197x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
199{ 198{
199 /* HAVE_NTGUI needs the explicit cast here. */
200 return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; 200 return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
201} 201}
202#endif 202#endif
@@ -217,15 +217,6 @@ x_allocate_bitmap_record (FRAME_PTR f)
217 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 217 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
218 ptrdiff_t i; 218 ptrdiff_t i;
219 219
220 if (dpyinfo->bitmaps == NULL)
221 {
222 dpyinfo->bitmaps_size = 10;
223 dpyinfo->bitmaps
224 = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
225 dpyinfo->bitmaps_last = 1;
226 return 1;
227 }
228
229 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size) 220 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
230 return ++dpyinfo->bitmaps_last; 221 return ++dpyinfo->bitmaps_last;
231 222
@@ -233,20 +224,16 @@ x_allocate_bitmap_record (FRAME_PTR f)
233 if (dpyinfo->bitmaps[i].refcount == 0) 224 if (dpyinfo->bitmaps[i].refcount == 0)
234 return i + 1; 225 return i + 1;
235 226
236 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2 227 dpyinfo->bitmaps =
237 < dpyinfo->bitmaps_size) 228 xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
238 memory_full (SIZE_MAX); 229 10, -1, sizeof *dpyinfo->bitmaps);
239 dpyinfo->bitmaps_size *= 2;
240 dpyinfo->bitmaps
241 = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
242 dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
243 return ++dpyinfo->bitmaps_last; 230 return ++dpyinfo->bitmaps_last;
244} 231}
245 232
246/* Add one reference to the reference count of the bitmap with id ID. */ 233/* Add one reference to the reference count of the bitmap with id ID. */
247 234
248void 235void
249x_reference_bitmap (FRAME_PTR f, int id) 236x_reference_bitmap (FRAME_PTR f, ptrdiff_t id)
250{ 237{
251 ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; 238 ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
252} 239}
@@ -705,7 +692,7 @@ enum image_value_type
705 IMAGE_STRING_OR_NIL_VALUE, 692 IMAGE_STRING_OR_NIL_VALUE,
706 IMAGE_SYMBOL_VALUE, 693 IMAGE_SYMBOL_VALUE,
707 IMAGE_POSITIVE_INTEGER_VALUE, 694 IMAGE_POSITIVE_INTEGER_VALUE,
708 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 695 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
709 IMAGE_NON_NEGATIVE_INTEGER_VALUE, 696 IMAGE_NON_NEGATIVE_INTEGER_VALUE,
710 IMAGE_ASCENT_VALUE, 697 IMAGE_ASCENT_VALUE,
711 IMAGE_INTEGER_VALUE, 698 IMAGE_INTEGER_VALUE,
@@ -808,29 +795,30 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
808 break; 795 break;
809 796
810 case IMAGE_POSITIVE_INTEGER_VALUE: 797 case IMAGE_POSITIVE_INTEGER_VALUE:
811 if (!INTEGERP (value) || XINT (value) <= 0) 798 if (! RANGED_INTEGERP (1, value, INT_MAX))
812 return 0; 799 return 0;
813 break; 800 break;
814 801
815 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR: 802 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
816 if (INTEGERP (value) && XINT (value) >= 0) 803 if (RANGED_INTEGERP (0, value, INT_MAX))
817 break; 804 break;
818 if (CONSP (value) 805 if (CONSP (value)
819 && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value)) 806 && RANGED_INTEGERP (0, XCAR (value), INT_MAX)
820 && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0) 807 && RANGED_INTEGERP (0, XCDR (value), INT_MAX))
821 break; 808 break;
822 return 0; 809 return 0;
823 810
824 case IMAGE_ASCENT_VALUE: 811 case IMAGE_ASCENT_VALUE:
825 if (SYMBOLP (value) && EQ (value, Qcenter)) 812 if (SYMBOLP (value) && EQ (value, Qcenter))
826 break; 813 break;
827 else if (INTEGERP (value) 814 else if (RANGED_INTEGERP (0, value, 100))
828 && XINT (value) >= 0
829 && XINT (value) <= 100)
830 break; 815 break;
831 return 0; 816 return 0;
832 817
833 case IMAGE_NON_NEGATIVE_INTEGER_VALUE: 818 case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
819 /* Unlike the other integer-related cases, this one does not
820 verify that VALUE fits in 'int'. This is because callers
821 want EMACS_INT. */
834 if (!INTEGERP (value) || XINT (value) < 0) 822 if (!INTEGERP (value) || XINT (value) < 0)
835 return 0; 823 return 0;
836 break; 824 break;
@@ -850,7 +838,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
850 break; 838 break;
851 839
852 case IMAGE_INTEGER_VALUE: 840 case IMAGE_INTEGER_VALUE:
853 if (!INTEGERP (value)) 841 if (! TYPE_RANGED_INTEGERP (int, value))
854 return 0; 842 return 0;
855 break; 843 break;
856 844
@@ -920,7 +908,7 @@ or omitted means use the selected frame. */)
920 if (valid_image_p (spec)) 908 if (valid_image_p (spec))
921 { 909 {
922 struct frame *f = check_x_frame (frame); 910 struct frame *f = check_x_frame (frame);
923 int id = lookup_image (f, spec); 911 ptrdiff_t id = lookup_image (f, spec);
924 struct image *img = IMAGE_FROM_ID (f, id); 912 struct image *img = IMAGE_FROM_ID (f, id);
925 int width = img->width + 2 * img->hmargin; 913 int width = img->width + 2 * img->hmargin;
926 int height = img->height + 2 * img->vmargin; 914 int height = img->height + 2 * img->vmargin;
@@ -950,7 +938,7 @@ or omitted means use the selected frame. */)
950 if (valid_image_p (spec)) 938 if (valid_image_p (spec))
951 { 939 {
952 struct frame *f = check_x_frame (frame); 940 struct frame *f = check_x_frame (frame);
953 int id = lookup_image (f, spec); 941 ptrdiff_t id = lookup_image (f, spec);
954 struct image *img = IMAGE_FROM_ID (f, id); 942 struct image *img = IMAGE_FROM_ID (f, id);
955 if (img->mask) 943 if (img->mask)
956 mask = Qt; 944 mask = Qt;
@@ -973,7 +961,7 @@ or omitted means use the selected frame. */)
973 if (valid_image_p (spec)) 961 if (valid_image_p (spec))
974 { 962 {
975 struct frame *f = check_x_frame (frame); 963 struct frame *f = check_x_frame (frame);
976 int id = lookup_image (f, spec); 964 ptrdiff_t id = lookup_image (f, spec);
977 struct image *img = IMAGE_FROM_ID (f, id); 965 struct image *img = IMAGE_FROM_ID (f, id);
978 ext = img->lisp_data; 966 ext = img->lisp_data;
979 } 967 }
@@ -987,9 +975,8 @@ or omitted means use the selected frame. */)
987 ***********************************************************************/ 975 ***********************************************************************/
988 976
989static void free_image (struct frame *f, struct image *img); 977static void free_image (struct frame *f, struct image *img);
990static int check_image_size (struct frame *f, int width, int height);
991 978
992#define MAX_IMAGE_SIZE 6.0 979#define MAX_IMAGE_SIZE 10.0
993/* Allocate and return a new image structure for image specification 980/* Allocate and return a new image structure for image specification
994 SPEC. SPEC has a hash value of HASH. */ 981 SPEC. SPEC has a hash value of HASH. */
995 982
@@ -1042,7 +1029,7 @@ free_image (struct frame *f, struct image *img)
1042/* Return 1 if the given widths and heights are valid for display; 1029/* Return 1 if the given widths and heights are valid for display;
1043 otherwise, return 0. */ 1030 otherwise, return 0. */
1044 1031
1045int 1032static int
1046check_image_size (struct frame *f, int width, int height) 1033check_image_size (struct frame *f, int width, int height)
1047{ 1034{
1048 int w, h; 1035 int w, h;
@@ -1051,7 +1038,8 @@ check_image_size (struct frame *f, int width, int height)
1051 return 0; 1038 return 0;
1052 1039
1053 if (INTEGERP (Vmax_image_size)) 1040 if (INTEGERP (Vmax_image_size))
1054 w = h = XINT (Vmax_image_size); 1041 return (width <= XINT (Vmax_image_size)
1042 && height <= XINT (Vmax_image_size));
1055 else if (FLOATP (Vmax_image_size)) 1043 else if (FLOATP (Vmax_image_size))
1056 { 1044 {
1057 if (f != NULL) 1045 if (f != NULL)
@@ -1061,13 +1049,11 @@ check_image_size (struct frame *f, int width, int height)
1061 } 1049 }
1062 else 1050 else
1063 w = h = 1024; /* Arbitrary size for unknown frame. */ 1051 w = h = 1024; /* Arbitrary size for unknown frame. */
1064 w = (int) (XFLOAT_DATA (Vmax_image_size) * w); 1052 return (width <= XFLOAT_DATA (Vmax_image_size) * w
1065 h = (int) (XFLOAT_DATA (Vmax_image_size) * h); 1053 && height <= XFLOAT_DATA (Vmax_image_size) * h);
1066 } 1054 }
1067 else 1055 else
1068 return 1; 1056 return 1;
1069
1070 return (width <= w && height <= h);
1071} 1057}
1072 1058
1073/* Prepare image IMG for display on frame F. Must be called before 1059/* Prepare image IMG for display on frame F. Must be called before
@@ -1120,15 +1106,15 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1120 because a typical font is `top-heavy' (due to the presence 1106 because a typical font is `top-heavy' (due to the presence
1121 uppercase letters), so the image placement should err towards 1107 uppercase letters), so the image placement should err towards
1122 being top-heavy too. It also just generally looks better. */ 1108 being top-heavy too. It also just generally looks better. */
1123 ascent = (height + FONT_BASE(face->font) 1109 ascent = (height + FONT_BASE (face->font)
1124 - FONT_DESCENT(face->font) + 1) / 2; 1110 - FONT_DESCENT (face->font) + 1) / 2;
1125#endif /* HAVE_NTGUI */ 1111#endif /* HAVE_NTGUI */
1126 } 1112 }
1127 else 1113 else
1128 ascent = height / 2; 1114 ascent = height / 2;
1129 } 1115 }
1130 else 1116 else
1131 ascent = (int) (height * img->ascent / 100.0); 1117 ascent = height * (img->ascent / 100.0);
1132 1118
1133 return ascent; 1119 return ascent;
1134} 1120}
@@ -1368,15 +1354,18 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
1368 1354
1369 xassert (STRINGP (color_name)); 1355 xassert (STRINGP (color_name));
1370 1356
1371 if (x_defined_color (f, SSDATA (color_name), &color, 1)) 1357 if (x_defined_color (f, SSDATA (color_name), &color, 1)
1358 && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
1359 INT_MAX))
1372 { 1360 {
1373 /* This isn't called frequently so we get away with simply 1361 /* This isn't called frequently so we get away with simply
1374 reallocating the color vector to the needed size, here. */ 1362 reallocating the color vector to the needed size, here. */
1375 ++img->ncolors; 1363 ptrdiff_t ncolors = img->ncolors + 1;
1376 img->colors = 1364 img->colors =
1377 (unsigned long *) xrealloc (img->colors, 1365 (unsigned long *) xrealloc (img->colors,
1378 img->ncolors * sizeof *img->colors); 1366 ncolors * sizeof *img->colors);
1379 img->colors[img->ncolors - 1] = color.pixel; 1367 img->colors[ncolors - 1] = color.pixel;
1368 img->ncolors = ncolors;
1380 result = color.pixel; 1369 result = color.pixel;
1381 } 1370 }
1382 else 1371 else
@@ -1404,8 +1393,9 @@ make_image_cache (void)
1404 int size; 1393 int size;
1405 1394
1406 memset (c, 0, sizeof *c); 1395 memset (c, 0, sizeof *c);
1407 c->size = 50; 1396 size = 50;
1408 c->images = (struct image **) xmalloc (c->size * sizeof *c->images); 1397 c->images = (struct image **) xmalloc (size * sizeof *c->images);
1398 c->size = size;
1409 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; 1399 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
1410 c->buckets = (struct image **) xmalloc (size); 1400 c->buckets = (struct image **) xmalloc (size);
1411 memset (c->buckets, 0, size); 1401 memset (c->buckets, 0, size);
@@ -1471,7 +1461,7 @@ free_image_cache (struct frame *f)
1471 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1461 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1472 if (c) 1462 if (c)
1473 { 1463 {
1474 int i; 1464 ptrdiff_t i;
1475 1465
1476 /* Cache should not be referenced by any frame when freed. */ 1466 /* Cache should not be referenced by any frame when freed. */
1477 xassert (c->refcount == 0); 1467 xassert (c->refcount == 0);
@@ -1501,7 +1491,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1501 1491
1502 if (c) 1492 if (c)
1503 { 1493 {
1504 int i, nfreed = 0; 1494 ptrdiff_t i, nfreed = 0;
1505 1495
1506 /* Block input so that we won't be interrupted by a SIGIO 1496 /* Block input so that we won't be interrupted by a SIGIO
1507 while being in an inconsistent state. */ 1497 while being in an inconsistent state. */
@@ -1525,8 +1515,8 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1525 { 1515 {
1526 /* Free cache based on timestamp. */ 1516 /* Free cache based on timestamp. */
1527 EMACS_TIME t; 1517 EMACS_TIME t;
1528 time_t old; 1518 double old, delay;
1529 int delay, nimages = 0; 1519 ptrdiff_t nimages = 0;
1530 1520
1531 for (i = 0; i < c->used; ++i) 1521 for (i = 0; i < c->used; ++i)
1532 if (c->images[i]) 1522 if (c->images[i])
@@ -1534,9 +1524,10 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1534 1524
1535 /* If the number of cached images has grown unusually large, 1525 /* If the number of cached images has grown unusually large,
1536 decrease the cache eviction delay (Bug#6230). */ 1526 decrease the cache eviction delay (Bug#6230). */
1537 delay = XFASTINT (Vimage_cache_eviction_delay); 1527 delay = XINT (Vimage_cache_eviction_delay);
1538 if (nimages > 40) 1528 if (nimages > 40)
1539 delay = max (1, 1600 * delay / (nimages*nimages)); 1529 delay = 1600 * delay / nimages / nimages;
1530 delay = max (delay, 1);
1540 1531
1541 EMACS_GET_TIME (t); 1532 EMACS_GET_TIME (t);
1542 old = EMACS_SECS (t) - delay; 1533 old = EMACS_SECS (t) - delay;
@@ -1712,7 +1703,7 @@ postprocess_image (struct frame *f, struct image *img)
1712/* Return the id of image with Lisp specification SPEC on frame F. 1703/* Return the id of image with Lisp specification SPEC on frame F.
1713 SPEC must be a valid Lisp image specification (see valid_image_p). */ 1704 SPEC must be a valid Lisp image specification (see valid_image_p). */
1714 1705
1715int 1706ptrdiff_t
1716lookup_image (struct frame *f, Lisp_Object spec) 1707lookup_image (struct frame *f, Lisp_Object spec)
1717{ 1708{
1718 struct image *img; 1709 struct image *img;
@@ -1771,15 +1762,12 @@ lookup_image (struct frame *f, Lisp_Object spec)
1771 img->ascent = CENTERED_IMAGE_ASCENT; 1762 img->ascent = CENTERED_IMAGE_ASCENT;
1772 1763
1773 margin = image_spec_value (spec, QCmargin, NULL); 1764 margin = image_spec_value (spec, QCmargin, NULL);
1774 if (INTEGERP (margin) && XINT (margin) >= 0) 1765 if (INTEGERP (margin))
1775 img->vmargin = img->hmargin = XFASTINT (margin); 1766 img->vmargin = img->hmargin = XFASTINT (margin);
1776 else if (CONSP (margin) && INTEGERP (XCAR (margin)) 1767 else if (CONSP (margin))
1777 && INTEGERP (XCDR (margin)))
1778 { 1768 {
1779 if (XINT (XCAR (margin)) > 0) 1769 img->hmargin = XFASTINT (XCAR (margin));
1780 img->hmargin = XFASTINT (XCAR (margin)); 1770 img->vmargin = XFASTINT (XCDR (margin));
1781 if (XINT (XCDR (margin)) > 0)
1782 img->vmargin = XFASTINT (XCDR (margin));
1783 } 1771 }
1784 1772
1785 relief = image_spec_value (spec, QCrelief, NULL); 1773 relief = image_spec_value (spec, QCrelief, NULL);
@@ -1826,7 +1814,7 @@ static void
1826cache_image (struct frame *f, struct image *img) 1814cache_image (struct frame *f, struct image *img)
1827{ 1815{
1828 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1816 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1829 int i; 1817 ptrdiff_t i;
1830 1818
1831 /* Find a free slot in c->images. */ 1819 /* Find a free slot in c->images. */
1832 for (i = 0; i < c->used; ++i) 1820 for (i = 0; i < c->used; ++i)
@@ -1835,13 +1823,7 @@ cache_image (struct frame *f, struct image *img)
1835 1823
1836 /* If no free slot found, maybe enlarge c->images. */ 1824 /* If no free slot found, maybe enlarge c->images. */
1837 if (i == c->used && c->used == c->size) 1825 if (i == c->used && c->used == c->size)
1838 { 1826 c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
1839 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size)
1840 memory_full (SIZE_MAX);
1841 c->size *= 2;
1842 c->images = (struct image **) xrealloc (c->images,
1843 c->size * sizeof *c->images);
1844 }
1845 1827
1846 /* Add IMG to c->images, and assign IMG an id. */ 1828 /* Add IMG to c->images, and assign IMG an id. */
1847 c->images[i] = img; 1829 c->images[i] = img;
@@ -1880,7 +1862,7 @@ mark_image_cache (struct image_cache *c)
1880{ 1862{
1881 if (c) 1863 if (c)
1882 { 1864 {
1883 int i; 1865 ptrdiff_t i;
1884 for (i = 0; i < c->used; ++i) 1866 for (i = 0; i < c->used; ++i)
1885 if (c->images[i]) 1867 if (c->images[i])
1886 mark_image (c->images[i]); 1868 mark_image (c->images[i]);
@@ -1911,6 +1893,44 @@ static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
1911static void x_destroy_x_image (XImagePtr); 1893static void x_destroy_x_image (XImagePtr);
1912static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int); 1894static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int);
1913 1895
1896/* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break the
1897 windowing system.
1898 WIDTH and HEIGHT must both be positive.
1899 If XIMG is null, assume it is a bitmap. */
1900static int
1901x_check_image_size (XImagePtr ximg, int width, int height)
1902{
1903#ifdef HAVE_X_WINDOWS
1904 /* Respect Xlib's limits: it cannot deal with images that have more
1905 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
1906 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
1907 enum
1908 {
1909 XLIB_BYTES_MAX = min (INT_MAX, UINT_MAX),
1910 X_IMAGE_BYTES_MAX = min (XLIB_BYTES_MAX, min (PTRDIFF_MAX, SIZE_MAX))
1911 };
1912
1913 int bitmap_pad, depth, bytes_per_line;
1914 if (ximg)
1915 {
1916 bitmap_pad = ximg->bitmap_pad;
1917 depth = ximg->depth;
1918 bytes_per_line = ximg->bytes_per_line;
1919 }
1920 else
1921 {
1922 bitmap_pad = 8;
1923 depth = 1;
1924 bytes_per_line = (width >> 3) + ((width & 7) != 0);
1925 }
1926 return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
1927 && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
1928#else
1929 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
1930 For now, assume that every image size is allowed on these systems. */
1931 return 1;
1932#endif
1933}
1914 1934
1915/* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on 1935/* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
1916 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created. 1936 frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
@@ -1943,6 +1963,15 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
1943 return 0; 1963 return 0;
1944 } 1964 }
1945 1965
1966 if (! x_check_image_size (*ximg, width, height))
1967 {
1968 x_destroy_x_image (*ximg);
1969 *ximg = NULL;
1970 image_error ("Image too large (%dx%d)",
1971 make_number (width), make_number (height));
1972 return 0;
1973 }
1974
1946 /* Allocate image raster. */ 1975 /* Allocate image raster. */
1947 (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height); 1976 (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
1948 1977
@@ -1986,14 +2015,9 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
1986 /* Bitmaps with a depth less than 16 need a palette. */ 2015 /* Bitmaps with a depth less than 16 need a palette. */
1987 /* BITMAPINFO structure already contains the first RGBQUAD. */ 2016 /* BITMAPINFO structure already contains the first RGBQUAD. */
1988 if (depth < 16) 2017 if (depth < 16)
1989 palette_colors = 1 << depth - 1; 2018 palette_colors = 1 << (depth - 1);
1990 2019
1991 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD)); 2020 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
1992 if (*ximg == NULL)
1993 {
1994 image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
1995 return 0;
1996 }
1997 2021
1998 header = &(*ximg)->info.bmiHeader; 2022 header = &(*ximg)->info.bmiHeader;
1999 memset (&(*ximg)->info, 0, sizeof (BITMAPINFO)); 2023 memset (&(*ximg)->info, 0, sizeof (BITMAPINFO));
@@ -2035,7 +2059,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
2035 DWORD err = GetLastError (); 2059 DWORD err = GetLastError ();
2036 Lisp_Object errcode; 2060 Lisp_Object errcode;
2037 /* All system errors are < 10000, so the following is safe. */ 2061 /* All system errors are < 10000, so the following is safe. */
2038 XSETINT (errcode, (int) err); 2062 XSETINT (errcode, err);
2039 image_error ("Unable to create bitmap, error code %d", errcode, Qnil); 2063 image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2040 x_destroy_x_image (*ximg); 2064 x_destroy_x_image (*ximg);
2041 return 0; 2065 return 0;
@@ -2233,7 +2257,7 @@ static const struct image_keyword xbm_format[XBM_LAST] =
2233 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, 2257 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
2234 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, 2258 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
2235 {":ascent", IMAGE_ASCENT_VALUE, 0}, 2259 {":ascent", IMAGE_ASCENT_VALUE, 0},
2236 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 2260 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
2237 {":relief", IMAGE_INTEGER_VALUE, 0}, 2261 {":relief", IMAGE_INTEGER_VALUE, 0},
2238 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 2262 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2239 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 2263 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -2314,7 +2338,7 @@ xbm_image_p (Lisp_Object object)
2314 else 2338 else
2315 { 2339 {
2316 Lisp_Object data; 2340 Lisp_Object data;
2317 EMACS_INT width, height; 2341 int width, height;
2318 2342
2319 /* Entries for `:width', `:height' and `:data' must be present. */ 2343 /* Entries for `:width', `:height' and `:data' must be present. */
2320 if (!kw[XBM_WIDTH].count 2344 if (!kw[XBM_WIDTH].count
@@ -2365,7 +2389,7 @@ xbm_image_p (Lisp_Object object)
2365 } 2389 }
2366 else if (BOOL_VECTOR_P (data)) 2390 else if (BOOL_VECTOR_P (data))
2367 { 2391 {
2368 if (XBOOL_VECTOR (data)->size < width * height) 2392 if (XBOOL_VECTOR (data)->size / height < width)
2369 return 0; 2393 return 0;
2370 } 2394 }
2371 else 2395 else
@@ -2561,13 +2585,15 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
2561 img->pixmap = ns_image_from_XBM (data, img->width, img->height); 2585 img->pixmap = ns_image_from_XBM (data, img->width, img->height);
2562 2586
2563#else 2587#else
2564 img->pixmap 2588 img->pixmap =
2565 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f), 2589 (x_check_image_size (0, img->width, img->height)
2590 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
2566 FRAME_X_WINDOW (f), 2591 FRAME_X_WINDOW (f),
2567 data, 2592 data,
2568 img->width, img->height, 2593 img->width, img->height,
2569 fg, bg, 2594 fg, bg,
2570 DefaultDepthOfScreen (FRAME_X_SCREEN (f))); 2595 DefaultDepthOfScreen (FRAME_X_SCREEN (f)))
2596 : NO_PIXMAP);
2571#endif /* !HAVE_NTGUI && !HAVE_NS */ 2597#endif /* !HAVE_NTGUI && !HAVE_NS */
2572} 2598}
2573 2599
@@ -2674,6 +2700,13 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
2674 expect ('='); 2700 expect ('=');
2675 expect ('{'); 2701 expect ('{');
2676 2702
2703 if (! x_check_image_size (0, *width, *height))
2704 {
2705 if (!inhibit_image_error)
2706 image_error ("Image too large (%dx%d)",
2707 make_number (*width), make_number (*height));
2708 goto failure;
2709 }
2677 bytes_per_line = (*width + 7) / 8 + padding_p; 2710 bytes_per_line = (*width + 7) / 8 + padding_p;
2678 nbytes = bytes_per_line * *height; 2711 nbytes = bytes_per_line * *height;
2679 p = *data = (char *) xmalloc (nbytes); 2712 p = *data = (char *) xmalloc (nbytes);
@@ -2864,6 +2897,12 @@ xbm_load (struct frame *f, struct image *img)
2864 img->width = XFASTINT (fmt[XBM_WIDTH].value); 2897 img->width = XFASTINT (fmt[XBM_WIDTH].value);
2865 img->height = XFASTINT (fmt[XBM_HEIGHT].value); 2898 img->height = XFASTINT (fmt[XBM_HEIGHT].value);
2866 xassert (img->width > 0 && img->height > 0); 2899 xassert (img->width > 0 && img->height > 0);
2900 if (!check_image_size (f, img->width, img->height))
2901 {
2902 image_error ("Invalid image size (see `max-image-size')",
2903 Qnil, Qnil);
2904 return 0;
2905 }
2867 } 2906 }
2868 2907
2869 /* Get foreground and background colors, maybe allocate colors. */ 2908 /* Get foreground and background colors, maybe allocate colors. */
@@ -2925,9 +2964,13 @@ xbm_load (struct frame *f, struct image *img)
2925#endif 2964#endif
2926 /* Create the pixmap. */ 2965 /* Create the pixmap. */
2927 2966
2928 Create_Pixmap_From_Bitmap_Data (f, img, bits, 2967 if (x_check_image_size (0, img->width, img->height))
2929 foreground, background, 2968 Create_Pixmap_From_Bitmap_Data (f, img, bits,
2930 non_default_colors); 2969 foreground, background,
2970 non_default_colors);
2971 else
2972 img->pixmap = NO_PIXMAP;
2973
2931 if (img->pixmap) 2974 if (img->pixmap)
2932 success_p = 1; 2975 success_p = 1;
2933 else 2976 else
@@ -3009,7 +3052,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
3009 {":file", IMAGE_STRING_VALUE, 0}, 3052 {":file", IMAGE_STRING_VALUE, 0},
3010 {":data", IMAGE_STRING_VALUE, 0}, 3053 {":data", IMAGE_STRING_VALUE, 0},
3011 {":ascent", IMAGE_ASCENT_VALUE, 0}, 3054 {":ascent", IMAGE_ASCENT_VALUE, 0},
3012 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 3055 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
3013 {":relief", IMAGE_INTEGER_VALUE, 0}, 3056 {":relief", IMAGE_INTEGER_VALUE, 0},
3014 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 3057 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3015 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 3058 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -3125,12 +3168,8 @@ xpm_free_color_cache (void)
3125static int 3168static int
3126xpm_color_bucket (char *color_name) 3169xpm_color_bucket (char *color_name)
3127{ 3170{
3128 unsigned h = 0; 3171 EMACS_UINT hash = hash_string (color_name, strlen (color_name));
3129 char *s; 3172 return hash % XPM_COLOR_CACHE_BUCKETS;
3130
3131 for (s = color_name; *s; ++s)
3132 h = (h << 2) ^ *s;
3133 return h %= XPM_COLOR_CACHE_BUCKETS;
3134} 3173}
3135 3174
3136 3175
@@ -3147,7 +3186,7 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
3147 if (bucket < 0) 3186 if (bucket < 0)
3148 bucket = xpm_color_bucket (color_name); 3187 bucket = xpm_color_bucket (color_name);
3149 3188
3150 nbytes = sizeof *p + strlen (color_name); 3189 nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
3151 p = (struct xpm_cached_color *) xmalloc (nbytes); 3190 p = (struct xpm_cached_color *) xmalloc (nbytes);
3152 strcpy (p->name, color_name); 3191 strcpy (p->name, color_name);
3153 p->color = *color; 3192 p->color = *color;
@@ -3531,9 +3570,8 @@ xpm_load (struct frame *f, struct image *img)
3531#endif /* HAVE_NTGUI */ 3570#endif /* HAVE_NTGUI */
3532 3571
3533 /* Remember allocated colors. */ 3572 /* Remember allocated colors. */
3573 img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
3534 img->ncolors = attrs.nalloc_pixels; 3574 img->ncolors = attrs.nalloc_pixels;
3535 img->colors = (unsigned long *) xmalloc (img->ncolors
3536 * sizeof *img->colors);
3537 for (i = 0; i < attrs.nalloc_pixels; ++i) 3575 for (i = 0; i < attrs.nalloc_pixels; ++i)
3538 { 3576 {
3539 img->colors[i] = attrs.alloc_pixels[i]; 3577 img->colors[i] = attrs.alloc_pixels[i];
@@ -3757,8 +3795,8 @@ xpm_get_color_table_h (Lisp_Object color_table,
3757 int chars_len) 3795 int chars_len)
3758{ 3796{
3759 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); 3797 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3760 int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), 3798 ptrdiff_t i =
3761 NULL); 3799 hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL);
3762 3800
3763 return i >= 0 ? HASH_VALUE (table, i) : Qnil; 3801 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
3764} 3802}
@@ -3849,6 +3887,18 @@ xpm_load_image (struct frame *f,
3849 goto failure; 3887 goto failure;
3850 } 3888 }
3851 3889
3890 if (!x_create_x_image_and_pixmap (f, width, height, 0,
3891 &ximg, &img->pixmap)
3892#ifndef HAVE_NS
3893 || !x_create_x_image_and_pixmap (f, width, height, 1,
3894 &mask_img, &img->mask)
3895#endif
3896 )
3897 {
3898 image_error ("Image too large", Qnil, Qnil);
3899 goto failure;
3900 }
3901
3852 expect (','); 3902 expect (',');
3853 3903
3854 XSETFRAME (frame, f); 3904 XSETFRAME (frame, f);
@@ -3942,18 +3992,6 @@ xpm_load_image (struct frame *f,
3942 expect (','); 3992 expect (',');
3943 } 3993 }
3944 3994
3945 if (!x_create_x_image_and_pixmap (f, width, height, 0,
3946 &ximg, &img->pixmap)
3947#ifndef HAVE_NS
3948 || !x_create_x_image_and_pixmap (f, width, height, 1,
3949 &mask_img, &img->mask)
3950#endif
3951 )
3952 {
3953 image_error ("Out of memory (%s)", img->spec, Qnil);
3954 goto error;
3955 }
3956
3957 for (y = 0; y < height; y++) 3995 for (y = 0; y < height; y++)
3958 { 3996 {
3959 expect (XPM_TK_STRING); 3997 expect (XPM_TK_STRING);
@@ -4107,6 +4145,12 @@ static struct ct_color **ct_table;
4107/* Number of entries in the color table. */ 4145/* Number of entries in the color table. */
4108 4146
4109static int ct_colors_allocated; 4147static int ct_colors_allocated;
4148enum
4149{
4150 ct_colors_allocated_max =
4151 min (INT_MAX,
4152 min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long))
4153};
4110 4154
4111/* Initialize the color table. */ 4155/* Initialize the color table. */
4112 4156
@@ -4193,7 +4237,14 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
4193 XColor color; 4237 XColor color;
4194 Colormap cmap; 4238 Colormap cmap;
4195 int rc; 4239 int rc;
4240#else
4241 COLORREF color;
4242#endif
4196 4243
4244 if (ct_colors_allocated_max <= ct_colors_allocated)
4245 return FRAME_FOREGROUND_PIXEL (f);
4246
4247#ifdef HAVE_X_WINDOWS
4197 color.red = r; 4248 color.red = r;
4198 color.green = g; 4249 color.green = g;
4199 color.blue = b; 4250 color.blue = b;
@@ -4215,7 +4266,6 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
4215 return FRAME_FOREGROUND_PIXEL (f); 4266 return FRAME_FOREGROUND_PIXEL (f);
4216 4267
4217#else 4268#else
4218 COLORREF color;
4219#ifdef HAVE_NTGUI 4269#ifdef HAVE_NTGUI
4220 color = PALETTERGB (r, g, b); 4270 color = PALETTERGB (r, g, b);
4221#else 4271#else
@@ -4256,6 +4306,9 @@ lookup_pixel_color (struct frame *f, unsigned long pixel)
4256 Colormap cmap; 4306 Colormap cmap;
4257 int rc; 4307 int rc;
4258 4308
4309 if (ct_colors_allocated_max <= ct_colors_allocated)
4310 return FRAME_FOREGROUND_PIXEL (f);
4311
4259#ifdef HAVE_X_WINDOWS 4312#ifdef HAVE_X_WINDOWS
4260 cmap = FRAME_X_COLORMAP (f); 4313 cmap = FRAME_X_COLORMAP (f);
4261 color.pixel = pixel; 4314 color.pixel = pixel;
@@ -4394,7 +4447,9 @@ x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
4394 HGDIOBJ prev; 4447 HGDIOBJ prev;
4395#endif /* HAVE_NTGUI */ 4448#endif /* HAVE_NTGUI */
4396 4449
4397 colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); 4450 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height)
4451 memory_full (SIZE_MAX);
4452 colors = (XColor *) xmalloc (sizeof *colors * img->width * img->height);
4398 4453
4399#ifndef HAVE_NTGUI 4454#ifndef HAVE_NTGUI
4400 /* Get the X image IMG->pixmap. */ 4455 /* Get the X image IMG->pixmap. */
@@ -4546,7 +4601,9 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus
4546 4601
4547#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) 4602#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4548 4603
4549 new = (XColor *) xmalloc (img->width * img->height * sizeof *new); 4604 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height)
4605 memory_full (SIZE_MAX);
4606 new = (XColor *) xmalloc (sizeof *new * img->width * img->height);
4550 4607
4551 for (y = 0; y < img->height; ++y) 4608 for (y = 0; y < img->height; ++y)
4552 { 4609 {
@@ -4924,7 +4981,7 @@ static const struct image_keyword pbm_format[PBM_LAST] =
4924 {":file", IMAGE_STRING_VALUE, 0}, 4981 {":file", IMAGE_STRING_VALUE, 0},
4925 {":data", IMAGE_STRING_VALUE, 0}, 4982 {":data", IMAGE_STRING_VALUE, 0},
4926 {":ascent", IMAGE_ASCENT_VALUE, 0}, 4983 {":ascent", IMAGE_ASCENT_VALUE, 0},
4927 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 4984 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
4928 {":relief", IMAGE_INTEGER_VALUE, 0}, 4985 {":relief", IMAGE_INTEGER_VALUE, 0},
4929 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 4986 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4930 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 4987 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -5007,9 +5064,7 @@ pbm_scan_number (unsigned char **s, unsigned char *end)
5007 occurred. *SIZE is set to the size of the file. */ 5064 occurred. *SIZE is set to the size of the file. */
5008 5065
5009static char * 5066static char *
5010pbm_read_file (file, size) 5067pbm_read_file (Lisp_Object file, int *size)
5011 Lisp_Object file;
5012 int *size;
5013{ 5068{
5014 FILE *fp = NULL; 5069 FILE *fp = NULL;
5015 char *buf = NULL; 5070 char *buf = NULL;
@@ -5341,7 +5396,7 @@ static const struct image_keyword png_format[PNG_LAST] =
5341 {":data", IMAGE_STRING_VALUE, 0}, 5396 {":data", IMAGE_STRING_VALUE, 0},
5342 {":file", IMAGE_STRING_VALUE, 0}, 5397 {":file", IMAGE_STRING_VALUE, 0},
5343 {":ascent", IMAGE_ASCENT_VALUE, 0}, 5398 {":ascent", IMAGE_ASCENT_VALUE, 0},
5344 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 5399 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
5345 {":relief", IMAGE_INTEGER_VALUE, 0}, 5400 {":relief", IMAGE_INTEGER_VALUE, 0},
5346 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5401 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5347 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5402 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -5490,7 +5545,7 @@ init_png_functions (Lisp_Object libraries)
5490/* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */ 5545/* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
5491#define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1)) 5546#define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
5492#define PNG_JMPBUF(ptr) \ 5547#define PNG_JMPBUF(ptr) \
5493 (*fn_png_set_longjmp_fn((ptr), longjmp, sizeof (jmp_buf))) 5548 (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf)))
5494#endif 5549#endif
5495 5550
5496/* Error and warning handlers installed when the PNG library 5551/* Error and warning handlers installed when the PNG library
@@ -5520,8 +5575,8 @@ my_png_warning (png_struct *png_ptr, const char *msg)
5520struct png_memory_storage 5575struct png_memory_storage
5521{ 5576{
5522 unsigned char *bytes; /* The data */ 5577 unsigned char *bytes; /* The data */
5523 size_t len; /* How big is it? */ 5578 ptrdiff_t len; /* How big is it? */
5524 int index; /* Where are we? */ 5579 ptrdiff_t index; /* Where are we? */
5525}; 5580};
5526 5581
5527 5582
@@ -5565,7 +5620,8 @@ png_load (struct frame *f, struct image *img)
5565{ 5620{
5566 Lisp_Object file, specified_file; 5621 Lisp_Object file, specified_file;
5567 Lisp_Object specified_data; 5622 Lisp_Object specified_data;
5568 int x, y, i; 5623 int x, y;
5624 ptrdiff_t i;
5569 XImagePtr ximg, mask_img = NULL; 5625 XImagePtr ximg, mask_img = NULL;
5570 png_struct *png_ptr = NULL; 5626 png_struct *png_ptr = NULL;
5571 png_info *info_ptr = NULL, *end_info = NULL; 5627 png_info *info_ptr = NULL, *end_info = NULL;
@@ -5685,11 +5741,19 @@ png_load (struct frame *f, struct image *img)
5685 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 5741 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
5686 &interlace_type, NULL, NULL); 5742 &interlace_type, NULL, NULL);
5687 5743
5688 if (!check_image_size (f, width, height)) 5744 if (! (width <= INT_MAX && height <= INT_MAX
5745 && check_image_size (f, width, height)))
5689 { 5746 {
5690 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 5747 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
5691 goto error; 5748 goto error;
5692 } 5749 }
5750
5751 /* Create the X image and pixmap now, so that the work below can be
5752 omitted if the image is too large for X. */
5753 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
5754 &img->pixmap))
5755 goto error;
5756
5693 /* If image contains simply transparency data, we prefer to 5757 /* If image contains simply transparency data, we prefer to
5694 construct a clipping mask. */ 5758 construct a clipping mask. */
5695 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) 5759 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
@@ -5778,7 +5842,10 @@ png_load (struct frame *f, struct image *img)
5778 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr); 5842 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
5779 5843
5780 /* Allocate memory for the image. */ 5844 /* Allocate memory for the image. */
5781 pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels); 5845 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
5846 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
5847 memory_full (SIZE_MAX);
5848 pixels = (png_byte *) xmalloc (sizeof *pixels * row_bytes * height);
5782 rows = (png_byte **) xmalloc (height * sizeof *rows); 5849 rows = (png_byte **) xmalloc (height * sizeof *rows);
5783 for (i = 0; i < height; ++i) 5850 for (i = 0; i < height; ++i)
5784 rows[i] = pixels + i * row_bytes; 5851 rows[i] = pixels + i * row_bytes;
@@ -5792,11 +5859,6 @@ png_load (struct frame *f, struct image *img)
5792 fp = NULL; 5859 fp = NULL;
5793 } 5860 }
5794 5861
5795 /* Create the X image and pixmap. */
5796 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
5797 &img->pixmap))
5798 goto error;
5799
5800 /* Create an image and pixmap serving as mask if the PNG image 5862 /* Create an image and pixmap serving as mask if the PNG image
5801 contains an alpha channel. */ 5863 contains an alpha channel. */
5802 if (channels == 4 5864 if (channels == 4
@@ -5819,7 +5881,7 @@ png_load (struct frame *f, struct image *img)
5819 5881
5820 for (x = 0; x < width; ++x) 5882 for (x = 0; x < width; ++x)
5821 { 5883 {
5822 unsigned r, g, b; 5884 int r, g, b;
5823 5885
5824 r = *p++ << 8; 5886 r = *p++ << 8;
5825 g = *p++ << 8; 5887 g = *p++ << 8;
@@ -5904,9 +5966,9 @@ png_load (struct frame *f, struct image *img)
5904static int 5966static int
5905png_load (struct frame *f, struct image *img) 5967png_load (struct frame *f, struct image *img)
5906{ 5968{
5907 return ns_load_image(f, img, 5969 return ns_load_image (f, img,
5908 image_spec_value (img->spec, QCfile, NULL), 5970 image_spec_value (img->spec, QCfile, NULL),
5909 image_spec_value (img->spec, QCdata, NULL)); 5971 image_spec_value (img->spec, QCdata, NULL));
5910} 5972}
5911#endif /* HAVE_NS */ 5973#endif /* HAVE_NS */
5912 5974
@@ -5954,7 +6016,7 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
5954 {":data", IMAGE_STRING_VALUE, 0}, 6016 {":data", IMAGE_STRING_VALUE, 0},
5955 {":file", IMAGE_STRING_VALUE, 0}, 6017 {":file", IMAGE_STRING_VALUE, 0},
5956 {":ascent", IMAGE_ASCENT_VALUE, 0}, 6018 {":ascent", IMAGE_ASCENT_VALUE, 0},
5957 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 6019 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
5958 {":relief", IMAGE_INTEGER_VALUE, 0}, 6020 {":relief", IMAGE_INTEGER_VALUE, 0},
5959 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6021 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5960 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6022 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -6053,7 +6115,7 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
6053 6115
6054#else 6116#else
6055 6117
6056#define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress(a) 6118#define fn_jpeg_CreateDecompress(a,b,c) jpeg_create_decompress (a)
6057#define fn_jpeg_start_decompress jpeg_start_decompress 6119#define fn_jpeg_start_decompress jpeg_start_decompress
6058#define fn_jpeg_finish_decompress jpeg_finish_decompress 6120#define fn_jpeg_finish_decompress jpeg_finish_decompress
6059#define fn_jpeg_destroy_decompress jpeg_destroy_decompress 6121#define fn_jpeg_destroy_decompress jpeg_destroy_decompress
@@ -6194,7 +6256,7 @@ our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
6194 src = (struct jpeg_stdio_mgr *) cinfo->src; 6256 src = (struct jpeg_stdio_mgr *) cinfo->src;
6195 if (!src->finished) 6257 if (!src->finished)
6196 { 6258 {
6197 size_t bytes; 6259 ptrdiff_t bytes;
6198 6260
6199 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file); 6261 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
6200 if (bytes > 0) 6262 if (bytes > 0)
@@ -6504,7 +6566,7 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
6504 {":data", IMAGE_STRING_VALUE, 0}, 6566 {":data", IMAGE_STRING_VALUE, 0},
6505 {":file", IMAGE_STRING_VALUE, 0}, 6567 {":file", IMAGE_STRING_VALUE, 0},
6506 {":ascent", IMAGE_ASCENT_VALUE, 0}, 6568 {":ascent", IMAGE_ASCENT_VALUE, 0},
6507 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 6569 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6508 {":relief", IMAGE_INTEGER_VALUE, 0}, 6570 {":relief", IMAGE_INTEGER_VALUE, 0},
6509 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6571 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6510 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6572 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -6604,34 +6666,33 @@ init_tiff_functions (Lisp_Object libraries)
6604typedef struct 6666typedef struct
6605{ 6667{
6606 unsigned char *bytes; 6668 unsigned char *bytes;
6607 size_t len; 6669 ptrdiff_t len;
6608 int index; 6670 ptrdiff_t index;
6609} 6671}
6610tiff_memory_source; 6672tiff_memory_source;
6611 6673
6612static size_t 6674static tsize_t
6613tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size) 6675tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
6614{ 6676{
6615 tiff_memory_source *src = (tiff_memory_source *) data; 6677 tiff_memory_source *src = (tiff_memory_source *) data;
6616 6678
6617 if (size > src->len - src->index) 6679 size = min (size, src->len - src->index);
6618 return (size_t) -1;
6619 memcpy (buf, src->bytes + src->index, size); 6680 memcpy (buf, src->bytes + src->index, size);
6620 src->index += size; 6681 src->index += size;
6621 return size; 6682 return size;
6622} 6683}
6623 6684
6624static size_t 6685static tsize_t
6625tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size) 6686tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size)
6626{ 6687{
6627 return (size_t) -1; 6688 return -1;
6628} 6689}
6629 6690
6630static toff_t 6691static toff_t
6631tiff_seek_in_memory (thandle_t data, toff_t off, int whence) 6692tiff_seek_in_memory (thandle_t data, toff_t off, int whence)
6632{ 6693{
6633 tiff_memory_source *src = (tiff_memory_source *) data; 6694 tiff_memory_source *src = (tiff_memory_source *) data;
6634 int idx; 6695 ptrdiff_t idx;
6635 6696
6636 switch (whence) 6697 switch (whence)
6637 { 6698 {
@@ -6684,18 +6745,41 @@ tiff_size_of_memory (thandle_t data)
6684 return ((tiff_memory_source *) data)->len; 6745 return ((tiff_memory_source *) data)->len;
6685} 6746}
6686 6747
6748/* GCC 3.x on x86 Windows targets has a bug that triggers an internal
6749 compiler error compiling tiff_handler, see Bugzilla bug #17406
6750 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring
6751 this function as external works around that problem. */
6752#if defined (__MINGW32__) && __GNUC__ == 3
6753# define MINGW_STATIC
6754#else
6755# define MINGW_STATIC static
6756#endif
6757
6758MINGW_STATIC void
6759tiff_handler (const char *, const char *, const char *, va_list)
6760 ATTRIBUTE_FORMAT_PRINTF (3, 0);
6761MINGW_STATIC void
6762tiff_handler (const char *log_format, const char *title,
6763 const char *format, va_list ap)
6764{
6765 /* doprnt is not suitable here, as TIFF handlers are called from
6766 libtiff and are passed arbitrary printf directives. Instead, use
6767 vsnprintf, taking care to be portable to nonstandard environments
6768 where vsnprintf returns -1 on buffer overflow. Since it's just a
6769 log entry, it's OK to truncate it. */
6770 char buf[4000];
6771 int len = vsnprintf (buf, sizeof buf, format, ap);
6772 add_to_log (log_format, build_string (title),
6773 make_string (buf, max (0, min (len, sizeof buf - 1))));
6774}
6775#undef MINGW_STATIC
6687 6776
6688static void tiff_error_handler (const char *, const char *, va_list) 6777static void tiff_error_handler (const char *, const char *, va_list)
6689 ATTRIBUTE_FORMAT_PRINTF (2, 0); 6778 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6690static void 6779static void
6691tiff_error_handler (const char *title, const char *format, va_list ap) 6780tiff_error_handler (const char *title, const char *format, va_list ap)
6692{ 6781{
6693 char buf[512]; 6782 tiff_handler ("TIFF error: %s %s", title, format, ap);
6694 int len;
6695
6696 len = sprintf (buf, "TIFF error: %s ", title);
6697 vsprintf (buf + len, format, ap);
6698 add_to_log (buf, Qnil, Qnil);
6699} 6783}
6700 6784
6701 6785
@@ -6704,12 +6788,7 @@ static void tiff_warning_handler (const char *, const char *, va_list)
6704static void 6788static void
6705tiff_warning_handler (const char *title, const char *format, va_list ap) 6789tiff_warning_handler (const char *title, const char *format, va_list ap)
6706{ 6790{
6707 char buf[512]; 6791 tiff_handler ("TIFF warning: %s %s", title, format, ap);
6708 int len;
6709
6710 len = sprintf (buf, "TIFF warning: %s ", title);
6711 vsprintf (buf + len, format, ap);
6712 add_to_log (buf, Qnil, Qnil);
6713} 6792}
6714 6793
6715 6794
@@ -6767,8 +6846,8 @@ tiff_load (struct frame *f, struct image *img)
6767 memsrc.index = 0; 6846 memsrc.index = 0;
6768 6847
6769 tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc, 6848 tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
6770 (TIFFReadWriteProc) tiff_read_from_memory, 6849 tiff_read_from_memory,
6771 (TIFFReadWriteProc) tiff_write_from_memory, 6850 tiff_write_from_memory,
6772 tiff_seek_in_memory, 6851 tiff_seek_in_memory,
6773 tiff_close_memory, 6852 tiff_close_memory,
6774 tiff_size_of_memory, 6853 tiff_size_of_memory,
@@ -6785,8 +6864,9 @@ tiff_load (struct frame *f, struct image *img)
6785 image = image_spec_value (img->spec, QCindex, NULL); 6864 image = image_spec_value (img->spec, QCindex, NULL);
6786 if (INTEGERP (image)) 6865 if (INTEGERP (image))
6787 { 6866 {
6788 int ino = XFASTINT (image); 6867 EMACS_INT ino = XFASTINT (image);
6789 if (!fn_TIFFSetDirectory (tiff, ino)) 6868 if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
6869 && fn_TIFFSetDirectory (tiff, ino)))
6790 { 6870 {
6791 image_error ("Invalid image number `%s' in image `%s'", 6871 image_error ("Invalid image number `%s' in image `%s'",
6792 image, img->spec); 6872 image, img->spec);
@@ -6807,7 +6887,16 @@ tiff_load (struct frame *f, struct image *img)
6807 return 0; 6887 return 0;
6808 } 6888 }
6809 6889
6810 buf = (uint32 *) xmalloc (width * height * sizeof *buf); 6890 /* Create the X image and pixmap. */
6891 if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width
6892 && x_create_x_image_and_pixmap (f, width, height, 0,
6893 &ximg, &img->pixmap)))
6894 {
6895 fn_TIFFClose (tiff);
6896 return 0;
6897 }
6898
6899 buf = (uint32 *) xmalloc (sizeof *buf * width * height);
6811 6900
6812 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0); 6901 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
6813 6902
@@ -6828,13 +6917,6 @@ tiff_load (struct frame *f, struct image *img)
6828 return 0; 6917 return 0;
6829 } 6918 }
6830 6919
6831 /* Create the X image and pixmap. */
6832 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6833 {
6834 xfree (buf);
6835 return 0;
6836 }
6837
6838 /* Initialize the color table. */ 6920 /* Initialize the color table. */
6839 init_color_table (); 6921 init_color_table ();
6840 6922
@@ -6932,7 +7014,7 @@ static const struct image_keyword gif_format[GIF_LAST] =
6932 {":data", IMAGE_STRING_VALUE, 0}, 7014 {":data", IMAGE_STRING_VALUE, 0},
6933 {":file", IMAGE_STRING_VALUE, 0}, 7015 {":file", IMAGE_STRING_VALUE, 0},
6934 {":ascent", IMAGE_ASCENT_VALUE, 0}, 7016 {":ascent", IMAGE_ASCENT_VALUE, 0},
6935 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7017 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6936 {":relief", IMAGE_INTEGER_VALUE, 0}, 7018 {":relief", IMAGE_INTEGER_VALUE, 0},
6937 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7019 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6938 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7020 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -7036,8 +7118,8 @@ init_gif_functions (Lisp_Object libraries)
7036typedef struct 7118typedef struct
7037{ 7119{
7038 unsigned char *bytes; 7120 unsigned char *bytes;
7039 size_t len; 7121 ptrdiff_t len;
7040 int index; 7122 ptrdiff_t index;
7041} 7123}
7042gif_memory_source; 7124gif_memory_source;
7043 7125
@@ -7077,13 +7159,12 @@ gif_load (struct frame *f, struct image *img)
7077 ColorMapObject *gif_color_map; 7159 ColorMapObject *gif_color_map;
7078 unsigned long pixel_colors[256]; 7160 unsigned long pixel_colors[256];
7079 GifFileType *gif; 7161 GifFileType *gif;
7080 int image_height, image_width;
7081 gif_memory_source memsrc; 7162 gif_memory_source memsrc;
7082 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); 7163 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7083 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); 7164 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
7084 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL); 7165 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
7085 unsigned long bgcolor = 0; 7166 unsigned long bgcolor = 0;
7086 int idx; 7167 EMACS_INT idx;
7087 7168
7088 if (NILP (specified_data)) 7169 if (NILP (specified_data))
7089 { 7170 {
@@ -7154,19 +7235,15 @@ gif_load (struct frame *f, struct image *img)
7154 } 7235 }
7155 } 7236 }
7156 7237
7157 img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top; 7238 width = img->width = gif->SWidth;
7158 img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left; 7239 height = img->height = gif->SHeight;
7159 image_height = gif->SavedImages[idx].ImageDesc.Height;
7160 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
7161 image_width = gif->SavedImages[idx].ImageDesc.Width;
7162 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
7163 7240
7164 width = img->width = max (gif->SWidth, 7241 img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
7165 max (gif->Image.Left + gif->Image.Width, 7242 img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
7166 img->corners[RIGHT_CORNER])); 7243 img->corners[BOT_CORNER]
7167 height = img->height = max (gif->SHeight, 7244 = img->corners[TOP_CORNER] + gif->SavedImages[0].ImageDesc.Height;
7168 max (gif->Image.Top + gif->Image.Height, 7245 img->corners[RIGHT_CORNER]
7169 img->corners[BOT_CORNER])); 7246 = img->corners[LEFT_CORNER] + gif->SavedImages[0].ImageDesc.Width;
7170 7247
7171 if (!check_image_size (f, width, height)) 7248 if (!check_image_size (f, width, height))
7172 { 7249 {
@@ -7221,6 +7298,10 @@ gif_load (struct frame *f, struct image *img)
7221 unsigned char *raster = (unsigned char *) subimage->RasterBits; 7298 unsigned char *raster = (unsigned char *) subimage->RasterBits;
7222 int transparency_color_index = -1; 7299 int transparency_color_index = -1;
7223 int disposal = 0; 7300 int disposal = 0;
7301 int subimg_width = subimage->ImageDesc.Width;
7302 int subimg_height = subimage->ImageDesc.Height;
7303 int subimg_top = subimage->ImageDesc.Top;
7304 int subimg_left = subimage->ImageDesc.Left;
7224 7305
7225 /* Find the Graphic Control Extension block for this sub-image. 7306 /* Find the Graphic Control Extension block for this sub-image.
7226 Extract the disposal method and transparency color. */ 7307 Extract the disposal method and transparency color. */
@@ -7244,6 +7325,13 @@ gif_load (struct frame *f, struct image *img)
7244 if (j == 0) 7325 if (j == 0)
7245 disposal = 2; 7326 disposal = 2;
7246 7327
7328 /* For disposal == 0, the spec says "No disposal specified. The
7329 decoder is not required to take any action." In practice, it
7330 seems we need to treat this like "keep in place", see e.g.
7331 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7332 if (disposal == 0)
7333 disposal = 1;
7334
7247 /* Allocate subimage colors. */ 7335 /* Allocate subimage colors. */
7248 memset (pixel_colors, 0, sizeof pixel_colors); 7336 memset (pixel_colors, 0, sizeof pixel_colors);
7249 gif_color_map = subimage->ImageDesc.ColorMap; 7337 gif_color_map = subimage->ImageDesc.ColorMap;
@@ -7271,34 +7359,34 @@ gif_load (struct frame *f, struct image *img)
7271 int row, pass; 7359 int row, pass;
7272 7360
7273 for (y = 0, row = interlace_start[0], pass = 0; 7361 for (y = 0, row = interlace_start[0], pass = 0;
7274 y < image_height; 7362 y < subimg_height;
7275 y++, row += interlace_increment[pass]) 7363 y++, row += interlace_increment[pass])
7276 { 7364 {
7277 if (row >= image_height) 7365 if (row >= subimg_height)
7278 { 7366 {
7279 row = interlace_start[++pass]; 7367 row = interlace_start[++pass];
7280 while (row >= image_height) 7368 while (row >= subimg_height)
7281 row = interlace_start[++pass]; 7369 row = interlace_start[++pass];
7282 } 7370 }
7283 7371
7284 for (x = 0; x < image_width; x++) 7372 for (x = 0; x < subimg_width; x++)
7285 { 7373 {
7286 int c = raster[y * image_width + x]; 7374 int c = raster[y * subimg_width + x];
7287 if (transparency_color_index != c || disposal != 1) 7375 if (transparency_color_index != c || disposal != 1)
7288 XPutPixel (ximg, x + img->corners[LEFT_CORNER], 7376 XPutPixel (ximg, x + subimg_left, row + subimg_top,
7289 row + img->corners[TOP_CORNER], pixel_colors[c]); 7377 pixel_colors[c]);
7290 } 7378 }
7291 } 7379 }
7292 } 7380 }
7293 else 7381 else
7294 { 7382 {
7295 for (y = 0; y < image_height; ++y) 7383 for (y = 0; y < subimg_height; ++y)
7296 for (x = 0; x < image_width; ++x) 7384 for (x = 0; x < subimg_width; ++x)
7297 { 7385 {
7298 int c = raster[y * image_width + x]; 7386 int c = raster[y * subimg_width + x];
7299 if (transparency_color_index != c || disposal != 1) 7387 if (transparency_color_index != c || disposal != 1)
7300 XPutPixel (ximg, x + img->corners[LEFT_CORNER], 7388 XPutPixel (ximg, x + subimg_left, y + subimg_top,
7301 y + img->corners[TOP_CORNER], pixel_colors[c]); 7389 pixel_colors[c]);
7302 } 7390 }
7303 } 7391 }
7304 } 7392 }
@@ -7313,7 +7401,7 @@ gif_load (struct frame *f, struct image *img)
7313 img->lisp_data = Qnil; 7401 img->lisp_data = Qnil;
7314 if (gif->SavedImages[idx].ExtensionBlockCount > 0) 7402 if (gif->SavedImages[idx].ExtensionBlockCount > 0)
7315 { 7403 {
7316 unsigned int delay = 0; 7404 int delay = 0;
7317 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks; 7405 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
7318 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++) 7406 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
7319 /* Append (... FUNCTION "BYTES") */ 7407 /* Append (... FUNCTION "BYTES") */
@@ -7334,7 +7422,7 @@ gif_load (struct frame *f, struct image *img)
7334 if (delay) 7422 if (delay)
7335 img->lisp_data 7423 img->lisp_data
7336 = Fcons (Qdelay, 7424 = Fcons (Qdelay,
7337 Fcons (make_float (((double) delay) * 0.01), 7425 Fcons (make_float (delay / 100.0),
7338 img->lisp_data)); 7426 img->lisp_data));
7339 } 7427 }
7340 7428
@@ -7413,7 +7501,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7413 {":data", IMAGE_STRING_VALUE, 0}, 7501 {":data", IMAGE_STRING_VALUE, 0},
7414 {":file", IMAGE_STRING_VALUE, 0}, 7502 {":file", IMAGE_STRING_VALUE, 0},
7415 {":ascent", IMAGE_ASCENT_VALUE, 0}, 7503 {":ascent", IMAGE_ASCENT_VALUE, 0},
7416 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7504 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7417 {":relief", IMAGE_INTEGER_VALUE, 0}, 7505 {":relief", IMAGE_INTEGER_VALUE, 0},
7418 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7506 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7419 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7507 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -7464,7 +7552,7 @@ imagemagick_image_p (Lisp_Object object)
7464} 7552}
7465 7553
7466/* The GIF library also defines DrawRectangle, but its never used in Emacs. 7554/* The GIF library also defines DrawRectangle, but its never used in Emacs.
7467 Therefore rename the function so it doesnt collide with ImageMagick. */ 7555 Therefore rename the function so it doesn't collide with ImageMagick. */
7468#define DrawRectangle DrawRectangleGif 7556#define DrawRectangle DrawRectangleGif
7469#include <wand/MagickWand.h> 7557#include <wand/MagickWand.h>
7470 7558
@@ -7476,6 +7564,22 @@ extern WandExport void PixelGetMagickColor (const PixelWand *,
7476 MagickPixelPacket *); 7564 MagickPixelPacket *);
7477#endif 7565#endif
7478 7566
7567/* Log ImageMagick error message.
7568 Useful when a ImageMagick function returns the status `MagickFalse'. */
7569
7570static void
7571imagemagick_error (MagickWand *wand)
7572{
7573 char *description;
7574 ExceptionType severity;
7575
7576 description = MagickGetException (wand, &severity);
7577 image_error ("ImageMagick error: %s",
7578 make_string (description, strlen (description)),
7579 Qnil);
7580 description = (char *) MagickRelinquishMemory (description);
7581}
7582
7479/* Helper function for imagemagick_load, which does the actual loading 7583/* Helper function for imagemagick_load, which does the actual loading
7480 given contents and size, apart from frame and image structures, 7584 given contents and size, apart from frame and image structures,
7481 passed from imagemagick_load. Uses librimagemagick to do most of 7585 passed from imagemagick_load. Uses librimagemagick to do most of
@@ -7510,10 +7614,9 @@ imagemagick_load_image (struct frame *f, struct image *img,
7510 Lisp_Object image; 7614 Lisp_Object image;
7511 Lisp_Object value; 7615 Lisp_Object value;
7512 Lisp_Object crop; 7616 Lisp_Object crop;
7513 long ino; 7617 EMACS_INT ino;
7514 int desired_width, desired_height; 7618 int desired_width, desired_height;
7515 double rotation; 7619 double rotation;
7516 int imagemagick_rendermethod;
7517 int pixelwidth; 7620 int pixelwidth;
7518 ImageInfo *image_info; 7621 ImageInfo *image_info;
7519 ExceptionInfo *exception; 7622 ExceptionInfo *exception;
@@ -7530,7 +7633,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7530 image = image_spec_value (img->spec, QCindex, NULL); 7633 image = image_spec_value (img->spec, QCindex, NULL);
7531 ino = INTEGERP (image) ? XFASTINT (image) : 0; 7634 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7532 ping_wand = NewMagickWand (); 7635 ping_wand = NewMagickWand ();
7533 MagickSetResolution (ping_wand, 2, 2); 7636 /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
7637
7534 if (filename != NULL) 7638 if (filename != NULL)
7535 { 7639 {
7536 status = MagickPingImage (ping_wand, filename); 7640 status = MagickPingImage (ping_wand, filename);
@@ -7540,7 +7644,14 @@ imagemagick_load_image (struct frame *f, struct image *img,
7540 status = MagickPingImageBlob (ping_wand, contents, size); 7644 status = MagickPingImageBlob (ping_wand, contents, size);
7541 } 7645 }
7542 7646
7543 if (ino >= MagickGetNumberImages (ping_wand)) 7647 if (status == MagickFalse)
7648 {
7649 imagemagick_error (ping_wand);
7650 DestroyMagickWand (ping_wand);
7651 return 0;
7652 }
7653
7654 if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand)))
7544 { 7655 {
7545 image_error ("Invalid image number `%s' in image `%s'", 7656 image_error ("Invalid image number `%s' in image `%s'",
7546 image, img->spec); 7657 image, img->spec);
@@ -7548,7 +7659,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
7548 return 0; 7659 return 0;
7549 } 7660 }
7550 7661
7551 if (MagickGetNumberImages(ping_wand) > 1) 7662 if (MagickGetNumberImages (ping_wand) > 1)
7552 img->lisp_data = 7663 img->lisp_data =
7553 Fcons (Qcount, 7664 Fcons (Qcount,
7554 Fcons (make_number (MagickGetNumberImages (ping_wand)), 7665 Fcons (make_number (MagickGetNumberImages (ping_wand)),
@@ -7573,13 +7684,16 @@ imagemagick_load_image (struct frame *f, struct image *img,
7573 if (im_image == NULL) 7684 if (im_image == NULL)
7574 goto imagemagick_no_wand; 7685 goto imagemagick_no_wand;
7575 image_wand = NewMagickWandFromImage (im_image); 7686 image_wand = NewMagickWandFromImage (im_image);
7576 DestroyImage(im_image); 7687 DestroyImage (im_image);
7577 } 7688 }
7578 else 7689 else
7579 { 7690 {
7580 image_wand = NewMagickWand (); 7691 image_wand = NewMagickWand ();
7581 if (MagickReadImageBlob (image_wand, contents, size) == MagickFalse) 7692 if (MagickReadImageBlob (image_wand, contents, size) == MagickFalse)
7582 goto imagemagick_error; 7693 {
7694 imagemagick_error (image_wand);
7695 goto imagemagick_error;
7696 }
7583 } 7697 }
7584 7698
7585 /* If width and/or height is set in the display spec assume we want 7699 /* If width and/or height is set in the display spec assume we want
@@ -7607,6 +7721,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
7607 if (status == MagickFalse) 7721 if (status == MagickFalse)
7608 { 7722 {
7609 image_error ("Imagemagick scale failed", Qnil, Qnil); 7723 image_error ("Imagemagick scale failed", Qnil, Qnil);
7724 imagemagick_error (image_wand);
7610 goto imagemagick_error; 7725 goto imagemagick_error;
7611 } 7726 }
7612 } 7727 }
@@ -7615,28 +7730,28 @@ imagemagick_load_image (struct frame *f, struct image *img,
7615 efficient. */ 7730 efficient. */
7616 crop = image_spec_value (img->spec, QCcrop, NULL); 7731 crop = image_spec_value (img->spec, QCcrop, NULL);
7617 7732
7618 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7733 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
7619 { 7734 {
7620 /* After some testing, it seems MagickCropImage is the fastest crop 7735 /* After some testing, it seems MagickCropImage is the fastest crop
7621 function in ImageMagick. This crop function seems to do less copying 7736 function in ImageMagick. This crop function seems to do less copying
7622 than the alternatives, but it still reads the entire image into memory 7737 than the alternatives, but it still reads the entire image into memory
7623 before croping, which is aparently difficult to avoid when using 7738 before cropping, which is apparently difficult to avoid when using
7624 imagemagick. */ 7739 imagemagick. */
7625 int w, h; 7740 size_t crop_width = XINT (XCAR (crop));
7626 w = XFASTINT (XCAR (crop));
7627 crop = XCDR (crop); 7741 crop = XCDR (crop);
7628 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7742 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
7629 { 7743 {
7630 h = XFASTINT (XCAR (crop)); 7744 size_t crop_height = XINT (XCAR (crop));
7631 crop = XCDR (crop); 7745 crop = XCDR (crop);
7632 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7746 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
7633 { 7747 {
7634 x = XFASTINT (XCAR (crop)); 7748 ssize_t crop_x = XINT (XCAR (crop));
7635 crop = XCDR (crop); 7749 crop = XCDR (crop);
7636 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7750 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
7637 { 7751 {
7638 y = XFASTINT (XCAR (crop)); 7752 ssize_t crop_y = XINT (XCAR (crop));
7639 MagickCropImage (image_wand, w, h, x, y); 7753 MagickCropImage (image_wand, crop_width, crop_height,
7754 crop_x, crop_y);
7640 } 7755 }
7641 } 7756 }
7642 } 7757 }
@@ -7661,16 +7776,18 @@ imagemagick_load_image (struct frame *f, struct image *img,
7661 if (status == MagickFalse) 7776 if (status == MagickFalse)
7662 { 7777 {
7663 image_error ("Imagemagick image rotate failed", Qnil, Qnil); 7778 image_error ("Imagemagick image rotate failed", Qnil, Qnil);
7779 imagemagick_error (image_wand);
7664 goto imagemagick_error; 7780 goto imagemagick_error;
7665 } 7781 }
7666 } 7782 }
7667 7783
7668 /* Finally we are done manipulating the image. Figure out the 7784 /* Finally we are done manipulating the image. Figure out the
7669 resulting width/height and transfer ownerwship to Emacs. */ 7785 resulting width/height and transfer ownership to Emacs. */
7670 height = MagickGetImageHeight (image_wand); 7786 height = MagickGetImageHeight (image_wand);
7671 width = MagickGetImageWidth (image_wand); 7787 width = MagickGetImageWidth (image_wand);
7672 7788
7673 if (! check_image_size (f, width, height)) 7789 if (! (width <= INT_MAX && height <= INT_MAX
7790 && check_image_size (f, width, height)))
7674 { 7791 {
7675 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 7792 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7676 goto imagemagick_error; 7793 goto imagemagick_error;
@@ -7680,10 +7797,11 @@ imagemagick_load_image (struct frame *f, struct image *img,
7680 went ok. */ 7797 went ok. */
7681 7798
7682 init_color_table (); 7799 init_color_table ();
7683 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type) 7800
7684 ? XFASTINT (Vimagemagick_render_type) : 0); 7801 if (imagemagick_render_type == 0)
7685 if (imagemagick_rendermethod == 0)
7686 { 7802 {
7803 size_t image_height;
7804
7687 /* Try to create a x pixmap to hold the imagemagick pixmap. */ 7805 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7688 if (!x_create_x_image_and_pixmap (f, width, height, 0, 7806 if (!x_create_x_image_and_pixmap (f, width, height, 0,
7689 &ximg, &img->pixmap)) 7807 &ximg, &img->pixmap))
@@ -7691,11 +7809,11 @@ imagemagick_load_image (struct frame *f, struct image *img,
7691#ifdef COLOR_TABLE_SUPPORT 7809#ifdef COLOR_TABLE_SUPPORT
7692 free_color_table (); 7810 free_color_table ();
7693#endif 7811#endif
7694 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); 7812 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7695 goto imagemagick_error; 7813 goto imagemagick_error;
7696 } 7814 }
7697 7815
7698 /* Copy imagegmagick image to x with primitive yet robust pixel 7816 /* Copy imagemagick image to x with primitive yet robust pixel
7699 pusher loop. This has been tested a lot with many different 7817 pusher loop. This has been tested a lot with many different
7700 images. */ 7818 images. */
7701 7819
@@ -7712,7 +7830,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7712 goto imagemagick_error; 7830 goto imagemagick_error;
7713 } 7831 }
7714 7832
7715 for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++) 7833 image_height = MagickGetImageHeight (image_wand);
7834 for (y = 0; y < image_height; y++)
7716 { 7835 {
7717 pixels = PixelGetNextIteratorRow (iterator, &width); 7836 pixels = PixelGetNextIteratorRow (iterator, &width);
7718 if (pixels == (PixelWand **) NULL) 7837 if (pixels == (PixelWand **) NULL)
@@ -7729,10 +7848,9 @@ imagemagick_load_image (struct frame *f, struct image *img,
7729 } 7848 }
7730 DestroyPixelIterator (iterator); 7849 DestroyPixelIterator (iterator);
7731 } 7850 }
7732 7851 else /* imagemagick_render_type != 0 */
7733 if (imagemagick_rendermethod == 1)
7734 { 7852 {
7735 /* Magicexportimage is normaly faster than pixelpushing. This 7853 /* Magicexportimage is normally faster than pixelpushing. This
7736 method is also well tested. Some aspects of this method are 7854 method is also well tested. Some aspects of this method are
7737 ad-hoc and needs to be more researched. */ 7855 ad-hoc and needs to be more researched. */
7738 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/ 7856 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
@@ -7744,12 +7862,12 @@ imagemagick_load_image (struct frame *f, struct image *img,
7744#ifdef COLOR_TABLE_SUPPORT 7862#ifdef COLOR_TABLE_SUPPORT
7745 free_color_table (); 7863 free_color_table ();
7746#endif 7864#endif
7747 image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); 7865 image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
7748 goto imagemagick_error; 7866 goto imagemagick_error;
7749 } 7867 }
7750 7868
7751 7869
7752 /* Oddly, the below code doesnt seem to work:*/ 7870 /* Oddly, the below code doesn't seem to work:*/
7753 /* switch(ximg->bitmap_unit){ */ 7871 /* switch(ximg->bitmap_unit){ */
7754 /* case 8: */ 7872 /* case 8: */
7755 /* pixelwidth=CharPixel; */ 7873 /* pixelwidth=CharPixel; */
@@ -7778,7 +7896,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
7778 /*&(img->pixmap));*/ 7896 /*&(img->pixmap));*/
7779 ximg->data); 7897 ximg->data);
7780#else 7898#else
7781 image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!", 7899 image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!",
7782 Qnil, Qnil); 7900 Qnil, Qnil);
7783#endif 7901#endif
7784 } 7902 }
@@ -7865,6 +7983,7 @@ DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
7865Each entry in this list is a symbol named after an ImageMagick format 7983Each entry in this list is a symbol named after an ImageMagick format
7866tag. See the ImageMagick manual for a list of ImageMagick formats and 7984tag. See the ImageMagick manual for a list of ImageMagick formats and
7867their descriptions (http://www.imagemagick.org/script/formats.php). 7985their descriptions (http://www.imagemagick.org/script/formats.php).
7986You can also try the shell command: `identify -list format'.
7868 7987
7869Note that ImageMagick recognizes many file-types that Emacs does not 7988Note that ImageMagick recognizes many file-types that Emacs does not
7870recognize as images, such as C. See `imagemagick-types-inhibit'. */) 7989recognize as images, such as C. See `imagemagick-types-inhibit'. */)
@@ -7874,14 +7993,14 @@ recognize as images, such as C. See `imagemagick-types-inhibit'. */)
7874 size_t numf = 0; 7993 size_t numf = 0;
7875 ExceptionInfo ex; 7994 ExceptionInfo ex;
7876 char **imtypes = GetMagickList ("*", &numf, &ex); 7995 char **imtypes = GetMagickList ("*", &numf, &ex);
7877 int i; 7996 size_t i;
7878 Lisp_Object Qimagemagicktype; 7997 Lisp_Object Qimagemagicktype;
7879 for (i = 0; i < numf; i++) 7998 for (i = 0; i < numf; i++)
7880 { 7999 {
7881 Qimagemagicktype = intern (imtypes[i]); 8000 Qimagemagicktype = intern (imtypes[i]);
7882 typelist = Fcons (Qimagemagicktype, typelist); 8001 typelist = Fcons (Qimagemagicktype, typelist);
7883 } 8002 }
7884 return typelist; 8003 return Fnreverse (typelist);
7885} 8004}
7886 8005
7887#endif /* defined (HAVE_IMAGEMAGICK) */ 8006#endif /* defined (HAVE_IMAGEMAGICK) */
@@ -7932,7 +8051,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
7932 {":data", IMAGE_STRING_VALUE, 0}, 8051 {":data", IMAGE_STRING_VALUE, 0},
7933 {":file", IMAGE_STRING_VALUE, 0}, 8052 {":file", IMAGE_STRING_VALUE, 0},
7934 {":ascent", IMAGE_ASCENT_VALUE, 0}, 8053 {":ascent", IMAGE_ASCENT_VALUE, 0},
7935 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 8054 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7936 {":relief", IMAGE_INTEGER_VALUE, 0}, 8055 {":relief", IMAGE_INTEGER_VALUE, 0},
7937 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8056 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7938 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8057 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -8218,10 +8337,10 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
8218 { 8337 {
8219 for (x = 0; x < width; ++x) 8338 for (x = 0; x < width; ++x)
8220 { 8339 {
8221 unsigned red; 8340 int red;
8222 unsigned green; 8341 int green;
8223 unsigned blue; 8342 int blue;
8224 unsigned opacity; 8343 int opacity;
8225 8344
8226 red = *pixels++; 8345 red = *pixels++;
8227 green = *pixels++; 8346 green = *pixels++;
@@ -8327,7 +8446,7 @@ static const struct image_keyword gs_format[GS_LAST] =
8327 {":loader", IMAGE_FUNCTION_VALUE, 0}, 8446 {":loader", IMAGE_FUNCTION_VALUE, 0},
8328 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, 8447 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
8329 {":ascent", IMAGE_ASCENT_VALUE, 0}, 8448 {":ascent", IMAGE_ASCENT_VALUE, 0},
8330 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 8449 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
8331 {":relief", IMAGE_INTEGER_VALUE, 0}, 8450 {":relief", IMAGE_INTEGER_VALUE, 0},
8332 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8451 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8333 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8452 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -8402,7 +8521,8 @@ gs_image_p (Lisp_Object object)
8402static int 8521static int
8403gs_load (struct frame *f, struct image *img) 8522gs_load (struct frame *f, struct image *img)
8404{ 8523{
8405 char buffer[100]; 8524 uprintmax_t printnum1, printnum2;
8525 char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)];
8406 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; 8526 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
8407 Lisp_Object frame; 8527 Lisp_Object frame;
8408 double in_width, in_height; 8528 double in_width, in_height;
@@ -8414,26 +8534,32 @@ gs_load (struct frame *f, struct image *img)
8414 info. */ 8534 info. */
8415 pt_width = image_spec_value (img->spec, QCpt_width, NULL); 8535 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
8416 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0; 8536 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
8417 img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; 8537 in_width *= FRAME_X_DISPLAY_INFO (f)->resx;
8418 pt_height = image_spec_value (img->spec, QCpt_height, NULL); 8538 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
8419 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0; 8539 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
8420 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; 8540 in_height *= FRAME_X_DISPLAY_INFO (f)->resy;
8421 8541
8422 if (!check_image_size (f, img->width, img->height)) 8542 if (! (in_width <= INT_MAX && in_height <= INT_MAX
8543 && check_image_size (f, in_width, in_height)))
8423 { 8544 {
8424 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 8545 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
8425 return 0; 8546 return 0;
8426 } 8547 }
8548 img->width = in_width;
8549 img->height = in_height;
8427 8550
8428 /* Create the pixmap. */ 8551 /* Create the pixmap. */
8429 xassert (img->pixmap == NO_PIXMAP); 8552 xassert (img->pixmap == NO_PIXMAP);
8430 8553
8431 /* Only W32 version did BLOCK_INPUT here. ++kfs */ 8554 if (x_check_image_size (0, img->width, img->height))
8432 BLOCK_INPUT; 8555 {
8433 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 8556 /* Only W32 version did BLOCK_INPUT here. ++kfs */
8434 img->width, img->height, 8557 BLOCK_INPUT;
8435 DefaultDepthOfScreen (FRAME_X_SCREEN (f))); 8558 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
8436 UNBLOCK_INPUT; 8559 img->width, img->height,
8560 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
8561 UNBLOCK_INPUT;
8562 }
8437 8563
8438 if (!img->pixmap) 8564 if (!img->pixmap)
8439 { 8565 {
@@ -8445,14 +8571,14 @@ gs_load (struct frame *f, struct image *img)
8445 if successful. We do not record_unwind_protect here because 8571 if successful. We do not record_unwind_protect here because
8446 other places in redisplay like calling window scroll functions 8572 other places in redisplay like calling window scroll functions
8447 don't either. Let the Lisp loader use `unwind-protect' instead. */ 8573 don't either. Let the Lisp loader use `unwind-protect' instead. */
8448 sprintf (buffer, "%lu %lu", 8574 printnum1 = FRAME_X_WINDOW (f);
8449 (unsigned long) FRAME_X_WINDOW (f), 8575 printnum2 = img->pixmap;
8450 (unsigned long) img->pixmap); 8576 sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
8451 window_and_pixmap_id = build_string (buffer); 8577 window_and_pixmap_id = build_string (buffer);
8452 8578
8453 sprintf (buffer, "%lu %lu", 8579 printnum1 = FRAME_FOREGROUND_PIXEL (f);
8454 FRAME_FOREGROUND_PIXEL (f), 8580 printnum2 = FRAME_BACKGROUND_PIXEL (f);
8455 FRAME_BACKGROUND_PIXEL (f)); 8581 sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
8456 pixel_colors = build_string (buffer); 8582 pixel_colors = build_string (buffer);
8457 8583
8458 XSETFRAME (frame, f); 8584 XSETFRAME (frame, f);
@@ -8477,7 +8603,8 @@ void
8477x_kill_gs_process (Pixmap pixmap, struct frame *f) 8603x_kill_gs_process (Pixmap pixmap, struct frame *f)
8478{ 8604{
8479 struct image_cache *c = FRAME_IMAGE_CACHE (f); 8605 struct image_cache *c = FRAME_IMAGE_CACHE (f);
8480 int class, i; 8606 int class;
8607 ptrdiff_t i;
8481 struct image *img; 8608 struct image *img;
8482 8609
8483 /* Find the image containing PIXMAP. */ 8610 /* Find the image containing PIXMAP. */
@@ -8581,7 +8708,7 @@ DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
8581DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") 8708DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8582 (Lisp_Object spec) 8709 (Lisp_Object spec)
8583{ 8710{
8584 int id = -1; 8711 ptrdiff_t id = -1;
8585 8712
8586 if (valid_image_p (spec)) 8713 if (valid_image_p (spec))
8587 id = lookup_image (SELECTED_FRAME (), spec); 8714 id = lookup_image (SELECTED_FRAME (), spec);
@@ -8681,7 +8808,7 @@ syms_of_image (void)
8681 operation on GNU/Linux of calling dump-emacs after loading some images. */ 8808 operation on GNU/Linux of calling dump-emacs after loading some images. */
8682 image_types = NULL; 8809 image_types = NULL;
8683 8810
8684 /* Must be defined now becase we're going to update it below, while 8811 /* Must be defined now because we're going to update it below, while
8685 defining the supported image types. */ 8812 defining the supported image types. */
8686 DEFVAR_LISP ("image-types", Vimage_types, 8813 DEFVAR_LISP ("image-types", Vimage_types,
8687 doc: /* List of potentially supported image types. 8814 doc: /* List of potentially supported image types.
@@ -8829,8 +8956,17 @@ The value can also be nil, meaning the cache is never cleared.
8829The function `clear-image-cache' disregards this variable. */); 8956The function `clear-image-cache' disregards this variable. */);
8830 Vimage_cache_eviction_delay = make_number (300); 8957 Vimage_cache_eviction_delay = make_number (300);
8831#ifdef HAVE_IMAGEMAGICK 8958#ifdef HAVE_IMAGEMAGICK
8832 DEFVAR_LISP ("imagemagick-render-type", Vimagemagick_render_type, 8959 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type,
8833 doc: /* Choose between ImageMagick render methods. */); 8960 doc: /* Integer indicating which ImageMagick rendering method to use.
8961The options are:
8962 0 -- the default method (pixel pushing)
8963 1 -- a newer method ("MagickExportImagePixels") that may perform
8964 better (speed etc) in some cases, but has not been as thoroughly
8965 tested with Emacs as the default method. This method requires
8966 ImageMagick version 6.4.6 (approximately) or later.
8967*/);
8968 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
8969 imagemagick_render_type = 0;
8834#endif 8970#endif
8835 8971
8836} 8972}