aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorPaul Eggert2011-09-03 16:03:38 -0700
committerPaul Eggert2011-09-03 16:03:38 -0700
commitb49e353d9d01adbe60bc5d0b1658b4ef978b0b06 (patch)
tree9f2ffa6f7a6562abf661a4951012b488ad8b1ae7 /src/image.c
parent74b880cbc18bd0194c7b1fc44c4a983ee05adae2 (diff)
parentbc3200871917d5c54c8c4299a06bf8f8ba2ea02d (diff)
downloademacs-b49e353d9d01adbe60bc5d0b1658b4ef978b0b06.tar.gz
emacs-b49e353d9d01adbe60bc5d0b1658b4ef978b0b06.zip
Merge from trunk.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c327
1 files changed, 174 insertions, 153 deletions
diff --git a/src/image.c b/src/image.c
index d1091aec6f3..c5dcbb32e5d 100644
--- a/src/image.c
+++ b/src/image.c
@@ -196,6 +196,7 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
196int 196int
197x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) 197x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
198{ 198{
199 /* HAVE_NTGUI needs the explicit cast here. */
199 return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; 200 return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
200} 201}
201#endif 202#endif
@@ -216,15 +217,6 @@ x_allocate_bitmap_record (FRAME_PTR f)
216 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 217 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
217 ptrdiff_t i; 218 ptrdiff_t i;
218 219
219 if (dpyinfo->bitmaps == NULL)
220 {
221 dpyinfo->bitmaps_size = 10;
222 dpyinfo->bitmaps
223 = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
224 dpyinfo->bitmaps_last = 1;
225 return 1;
226 }
227
228 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size) 220 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
229 return ++dpyinfo->bitmaps_last; 221 return ++dpyinfo->bitmaps_last;
230 222
@@ -232,20 +224,16 @@ x_allocate_bitmap_record (FRAME_PTR f)
232 if (dpyinfo->bitmaps[i].refcount == 0) 224 if (dpyinfo->bitmaps[i].refcount == 0)
233 return i + 1; 225 return i + 1;
234 226
235 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2 227 dpyinfo->bitmaps =
236 < dpyinfo->bitmaps_size) 228 xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
237 memory_full (SIZE_MAX); 229 10, -1, sizeof *dpyinfo->bitmaps);
238 dpyinfo->bitmaps_size *= 2;
239 dpyinfo->bitmaps
240 = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
241 dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
242 return ++dpyinfo->bitmaps_last; 230 return ++dpyinfo->bitmaps_last;
243} 231}
244 232
245/* 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. */
246 234
247void 235void
248x_reference_bitmap (FRAME_PTR f, int id) 236x_reference_bitmap (FRAME_PTR f, ptrdiff_t id)
249{ 237{
250 ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; 238 ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
251} 239}
@@ -704,7 +692,7 @@ enum image_value_type
704 IMAGE_STRING_OR_NIL_VALUE, 692 IMAGE_STRING_OR_NIL_VALUE,
705 IMAGE_SYMBOL_VALUE, 693 IMAGE_SYMBOL_VALUE,
706 IMAGE_POSITIVE_INTEGER_VALUE, 694 IMAGE_POSITIVE_INTEGER_VALUE,
707 IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 695 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
708 IMAGE_NON_NEGATIVE_INTEGER_VALUE, 696 IMAGE_NON_NEGATIVE_INTEGER_VALUE,
709 IMAGE_ASCENT_VALUE, 697 IMAGE_ASCENT_VALUE,
710 IMAGE_INTEGER_VALUE, 698 IMAGE_INTEGER_VALUE,
@@ -807,29 +795,30 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
807 break; 795 break;
808 796
809 case IMAGE_POSITIVE_INTEGER_VALUE: 797 case IMAGE_POSITIVE_INTEGER_VALUE:
810 if (!INTEGERP (value) || XINT (value) <= 0) 798 if (! RANGED_INTEGERP (1, value, INT_MAX))
811 return 0; 799 return 0;
812 break; 800 break;
813 801
814 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR: 802 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
815 if (INTEGERP (value) && XINT (value) >= 0) 803 if (RANGED_INTEGERP (0, value, INT_MAX))
816 break; 804 break;
817 if (CONSP (value) 805 if (CONSP (value)
818 && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value)) 806 && RANGED_INTEGERP (0, XCAR (value), INT_MAX)
819 && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0) 807 && RANGED_INTEGERP (0, XCDR (value), INT_MAX))
820 break; 808 break;
821 return 0; 809 return 0;
822 810
823 case IMAGE_ASCENT_VALUE: 811 case IMAGE_ASCENT_VALUE:
824 if (SYMBOLP (value) && EQ (value, Qcenter)) 812 if (SYMBOLP (value) && EQ (value, Qcenter))
825 break; 813 break;
826 else if (INTEGERP (value) 814 else if (RANGED_INTEGERP (0, value, 100))
827 && XINT (value) >= 0
828 && XINT (value) <= 100)
829 break; 815 break;
830 return 0; 816 return 0;
831 817
832 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. */
833 if (!INTEGERP (value) || XINT (value) < 0) 822 if (!INTEGERP (value) || XINT (value) < 0)
834 return 0; 823 return 0;
835 break; 824 break;
@@ -849,7 +838,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
849 break; 838 break;
850 839
851 case IMAGE_INTEGER_VALUE: 840 case IMAGE_INTEGER_VALUE:
852 if (!INTEGERP (value)) 841 if (! TYPE_RANGED_INTEGERP (int, value))
853 return 0; 842 return 0;
854 break; 843 break;
855 844
@@ -919,7 +908,7 @@ or omitted means use the selected frame. */)
919 if (valid_image_p (spec)) 908 if (valid_image_p (spec))
920 { 909 {
921 struct frame *f = check_x_frame (frame); 910 struct frame *f = check_x_frame (frame);
922 int id = lookup_image (f, spec); 911 ptrdiff_t id = lookup_image (f, spec);
923 struct image *img = IMAGE_FROM_ID (f, id); 912 struct image *img = IMAGE_FROM_ID (f, id);
924 int width = img->width + 2 * img->hmargin; 913 int width = img->width + 2 * img->hmargin;
925 int height = img->height + 2 * img->vmargin; 914 int height = img->height + 2 * img->vmargin;
@@ -949,7 +938,7 @@ or omitted means use the selected frame. */)
949 if (valid_image_p (spec)) 938 if (valid_image_p (spec))
950 { 939 {
951 struct frame *f = check_x_frame (frame); 940 struct frame *f = check_x_frame (frame);
952 int id = lookup_image (f, spec); 941 ptrdiff_t id = lookup_image (f, spec);
953 struct image *img = IMAGE_FROM_ID (f, id); 942 struct image *img = IMAGE_FROM_ID (f, id);
954 if (img->mask) 943 if (img->mask)
955 mask = Qt; 944 mask = Qt;
@@ -972,7 +961,7 @@ or omitted means use the selected frame. */)
972 if (valid_image_p (spec)) 961 if (valid_image_p (spec))
973 { 962 {
974 struct frame *f = check_x_frame (frame); 963 struct frame *f = check_x_frame (frame);
975 int id = lookup_image (f, spec); 964 ptrdiff_t id = lookup_image (f, spec);
976 struct image *img = IMAGE_FROM_ID (f, id); 965 struct image *img = IMAGE_FROM_ID (f, id);
977 ext = img->lisp_data; 966 ext = img->lisp_data;
978 } 967 }
@@ -1125,7 +1114,7 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1125 ascent = height / 2; 1114 ascent = height / 2;
1126 } 1115 }
1127 else 1116 else
1128 ascent = (int) (height * img->ascent / 100.0); 1117 ascent = height * (img->ascent / 100.0);
1129 1118
1130 return ascent; 1119 return ascent;
1131} 1120}
@@ -1371,11 +1360,12 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
1371 { 1360 {
1372 /* This isn't called frequently so we get away with simply 1361 /* This isn't called frequently so we get away with simply
1373 reallocating the color vector to the needed size, here. */ 1362 reallocating the color vector to the needed size, here. */
1374 ++img->ncolors; 1363 ptrdiff_t ncolors = img->ncolors + 1;
1375 img->colors = 1364 img->colors =
1376 (unsigned long *) xrealloc (img->colors, 1365 (unsigned long *) xrealloc (img->colors,
1377 img->ncolors * sizeof *img->colors); 1366 ncolors * sizeof *img->colors);
1378 img->colors[img->ncolors - 1] = color.pixel; 1367 img->colors[ncolors - 1] = color.pixel;
1368 img->ncolors = ncolors;
1379 result = color.pixel; 1369 result = color.pixel;
1380 } 1370 }
1381 else 1371 else
@@ -1403,8 +1393,9 @@ make_image_cache (void)
1403 int size; 1393 int size;
1404 1394
1405 memset (c, 0, sizeof *c); 1395 memset (c, 0, sizeof *c);
1406 c->size = 50; 1396 size = 50;
1407 c->images = (struct image **) xmalloc (c->size * sizeof *c->images); 1397 c->images = (struct image **) xmalloc (size * sizeof *c->images);
1398 c->size = size;
1408 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; 1399 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
1409 c->buckets = (struct image **) xmalloc (size); 1400 c->buckets = (struct image **) xmalloc (size);
1410 memset (c->buckets, 0, size); 1401 memset (c->buckets, 0, size);
@@ -1470,7 +1461,7 @@ free_image_cache (struct frame *f)
1470 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1461 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1471 if (c) 1462 if (c)
1472 { 1463 {
1473 int i; 1464 ptrdiff_t i;
1474 1465
1475 /* Cache should not be referenced by any frame when freed. */ 1466 /* Cache should not be referenced by any frame when freed. */
1476 xassert (c->refcount == 0); 1467 xassert (c->refcount == 0);
@@ -1500,7 +1491,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1500 1491
1501 if (c) 1492 if (c)
1502 { 1493 {
1503 int i, nfreed = 0; 1494 ptrdiff_t i, nfreed = 0;
1504 1495
1505 /* 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
1506 while being in an inconsistent state. */ 1497 while being in an inconsistent state. */
@@ -1524,8 +1515,8 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1524 { 1515 {
1525 /* Free cache based on timestamp. */ 1516 /* Free cache based on timestamp. */
1526 EMACS_TIME t; 1517 EMACS_TIME t;
1527 time_t old; 1518 double old, delay;
1528 int delay, nimages = 0; 1519 ptrdiff_t nimages = 0;
1529 1520
1530 for (i = 0; i < c->used; ++i) 1521 for (i = 0; i < c->used; ++i)
1531 if (c->images[i]) 1522 if (c->images[i])
@@ -1533,9 +1524,10 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1533 1524
1534 /* If the number of cached images has grown unusually large, 1525 /* If the number of cached images has grown unusually large,
1535 decrease the cache eviction delay (Bug#6230). */ 1526 decrease the cache eviction delay (Bug#6230). */
1536 delay = XFASTINT (Vimage_cache_eviction_delay); 1527 delay = XINT (Vimage_cache_eviction_delay);
1537 if (nimages > 40) 1528 if (nimages > 40)
1538 delay = max (1, 1600 * delay / (nimages*nimages)); 1529 delay = 1600 * delay / nimages / nimages;
1530 delay = max (delay, 1);
1539 1531
1540 EMACS_GET_TIME (t); 1532 EMACS_GET_TIME (t);
1541 old = EMACS_SECS (t) - delay; 1533 old = EMACS_SECS (t) - delay;
@@ -1711,7 +1703,7 @@ postprocess_image (struct frame *f, struct image *img)
1711/* 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.
1712 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). */
1713 1705
1714int 1706ptrdiff_t
1715lookup_image (struct frame *f, Lisp_Object spec) 1707lookup_image (struct frame *f, Lisp_Object spec)
1716{ 1708{
1717 struct image *img; 1709 struct image *img;
@@ -1770,15 +1762,12 @@ lookup_image (struct frame *f, Lisp_Object spec)
1770 img->ascent = CENTERED_IMAGE_ASCENT; 1762 img->ascent = CENTERED_IMAGE_ASCENT;
1771 1763
1772 margin = image_spec_value (spec, QCmargin, NULL); 1764 margin = image_spec_value (spec, QCmargin, NULL);
1773 if (INTEGERP (margin) && XINT (margin) >= 0) 1765 if (INTEGERP (margin))
1774 img->vmargin = img->hmargin = XFASTINT (margin); 1766 img->vmargin = img->hmargin = XFASTINT (margin);
1775 else if (CONSP (margin) && INTEGERP (XCAR (margin)) 1767 else if (CONSP (margin))
1776 && INTEGERP (XCDR (margin)))
1777 { 1768 {
1778 if (XINT (XCAR (margin)) > 0) 1769 img->hmargin = XFASTINT (XCAR (margin));
1779 img->hmargin = XFASTINT (XCAR (margin)); 1770 img->vmargin = XFASTINT (XCDR (margin));
1780 if (XINT (XCDR (margin)) > 0)
1781 img->vmargin = XFASTINT (XCDR (margin));
1782 } 1771 }
1783 1772
1784 relief = image_spec_value (spec, QCrelief, NULL); 1773 relief = image_spec_value (spec, QCrelief, NULL);
@@ -1825,7 +1814,7 @@ static void
1825cache_image (struct frame *f, struct image *img) 1814cache_image (struct frame *f, struct image *img)
1826{ 1815{
1827 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1816 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1828 int i; 1817 ptrdiff_t i;
1829 1818
1830 /* Find a free slot in c->images. */ 1819 /* Find a free slot in c->images. */
1831 for (i = 0; i < c->used; ++i) 1820 for (i = 0; i < c->used; ++i)
@@ -1834,13 +1823,7 @@ cache_image (struct frame *f, struct image *img)
1834 1823
1835 /* If no free slot found, maybe enlarge c->images. */ 1824 /* If no free slot found, maybe enlarge c->images. */
1836 if (i == c->used && c->used == c->size) 1825 if (i == c->used && c->used == c->size)
1837 { 1826 c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
1838 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size)
1839 memory_full (SIZE_MAX);
1840 c->size *= 2;
1841 c->images = (struct image **) xrealloc (c->images,
1842 c->size * sizeof *c->images);
1843 }
1844 1827
1845 /* Add IMG to c->images, and assign IMG an id. */ 1828 /* Add IMG to c->images, and assign IMG an id. */
1846 c->images[i] = img; 1829 c->images[i] = img;
@@ -1879,7 +1862,7 @@ mark_image_cache (struct image_cache *c)
1879{ 1862{
1880 if (c) 1863 if (c)
1881 { 1864 {
1882 int i; 1865 ptrdiff_t i;
1883 for (i = 0; i < c->used; ++i) 1866 for (i = 0; i < c->used; ++i)
1884 if (c->images[i]) 1867 if (c->images[i])
1885 mark_image (c->images[i]); 1868 mark_image (c->images[i]);
@@ -2076,7 +2059,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
2076 DWORD err = GetLastError (); 2059 DWORD err = GetLastError ();
2077 Lisp_Object errcode; 2060 Lisp_Object errcode;
2078 /* All system errors are < 10000, so the following is safe. */ 2061 /* All system errors are < 10000, so the following is safe. */
2079 XSETINT (errcode, (int) err); 2062 XSETINT (errcode, err);
2080 image_error ("Unable to create bitmap, error code %d", errcode, Qnil); 2063 image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2081 x_destroy_x_image (*ximg); 2064 x_destroy_x_image (*ximg);
2082 return 0; 2065 return 0;
@@ -2274,7 +2257,7 @@ static const struct image_keyword xbm_format[XBM_LAST] =
2274 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, 2257 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
2275 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, 2258 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
2276 {":ascent", IMAGE_ASCENT_VALUE, 0}, 2259 {":ascent", IMAGE_ASCENT_VALUE, 0},
2277 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 2260 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
2278 {":relief", IMAGE_INTEGER_VALUE, 0}, 2261 {":relief", IMAGE_INTEGER_VALUE, 0},
2279 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 2262 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
2280 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 2263 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -2355,7 +2338,7 @@ xbm_image_p (Lisp_Object object)
2355 else 2338 else
2356 { 2339 {
2357 Lisp_Object data; 2340 Lisp_Object data;
2358 EMACS_INT width, height; 2341 int width, height;
2359 2342
2360 /* Entries for `:width', `:height' and `:data' must be present. */ 2343 /* Entries for `:width', `:height' and `:data' must be present. */
2361 if (!kw[XBM_WIDTH].count 2344 if (!kw[XBM_WIDTH].count
@@ -3069,7 +3052,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
3069 {":file", IMAGE_STRING_VALUE, 0}, 3052 {":file", IMAGE_STRING_VALUE, 0},
3070 {":data", IMAGE_STRING_VALUE, 0}, 3053 {":data", IMAGE_STRING_VALUE, 0},
3071 {":ascent", IMAGE_ASCENT_VALUE, 0}, 3054 {":ascent", IMAGE_ASCENT_VALUE, 0},
3072 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 3055 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
3073 {":relief", IMAGE_INTEGER_VALUE, 0}, 3056 {":relief", IMAGE_INTEGER_VALUE, 0},
3074 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 3057 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3075 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 3058 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -3587,9 +3570,8 @@ xpm_load (struct frame *f, struct image *img)
3587#endif /* HAVE_NTGUI */ 3570#endif /* HAVE_NTGUI */
3588 3571
3589 /* Remember allocated colors. */ 3572 /* Remember allocated colors. */
3573 img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
3590 img->ncolors = attrs.nalloc_pixels; 3574 img->ncolors = attrs.nalloc_pixels;
3591 img->colors = (unsigned long *) xmalloc (img->ncolors
3592 * sizeof *img->colors);
3593 for (i = 0; i < attrs.nalloc_pixels; ++i) 3575 for (i = 0; i < attrs.nalloc_pixels; ++i)
3594 { 3576 {
3595 img->colors[i] = attrs.alloc_pixels[i]; 3577 img->colors[i] = attrs.alloc_pixels[i];
@@ -3813,8 +3795,8 @@ xpm_get_color_table_h (Lisp_Object color_table,
3813 int chars_len) 3795 int chars_len)
3814{ 3796{
3815 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); 3797 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3816 int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), 3798 ptrdiff_t i =
3817 NULL); 3799 hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL);
3818 3800
3819 return i >= 0 ? HASH_VALUE (table, i) : Qnil; 3801 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
3820} 3802}
@@ -4163,6 +4145,12 @@ static struct ct_color **ct_table;
4163/* Number of entries in the color table. */ 4145/* Number of entries in the color table. */
4164 4146
4165static 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};
4166 4154
4167/* Initialize the color table. */ 4155/* Initialize the color table. */
4168 4156
@@ -4249,7 +4237,14 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
4249 XColor color; 4237 XColor color;
4250 Colormap cmap; 4238 Colormap cmap;
4251 int rc; 4239 int rc;
4240#else
4241 COLORREF color;
4242#endif
4252 4243
4244 if (ct_colors_allocated_max <= ct_colors_allocated)
4245 return FRAME_FOREGROUND_PIXEL (f);
4246
4247#ifdef HAVE_X_WINDOWS
4253 color.red = r; 4248 color.red = r;
4254 color.green = g; 4249 color.green = g;
4255 color.blue = b; 4250 color.blue = b;
@@ -4271,7 +4266,6 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
4271 return FRAME_FOREGROUND_PIXEL (f); 4266 return FRAME_FOREGROUND_PIXEL (f);
4272 4267
4273#else 4268#else
4274 COLORREF color;
4275#ifdef HAVE_NTGUI 4269#ifdef HAVE_NTGUI
4276 color = PALETTERGB (r, g, b); 4270 color = PALETTERGB (r, g, b);
4277#else 4271#else
@@ -4312,6 +4306,9 @@ lookup_pixel_color (struct frame *f, unsigned long pixel)
4312 Colormap cmap; 4306 Colormap cmap;
4313 int rc; 4307 int rc;
4314 4308
4309 if (ct_colors_allocated_max <= ct_colors_allocated)
4310 return FRAME_FOREGROUND_PIXEL (f);
4311
4315#ifdef HAVE_X_WINDOWS 4312#ifdef HAVE_X_WINDOWS
4316 cmap = FRAME_X_COLORMAP (f); 4313 cmap = FRAME_X_COLORMAP (f);
4317 color.pixel = pixel; 4314 color.pixel = pixel;
@@ -4450,7 +4447,9 @@ x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
4450 HGDIOBJ prev; 4447 HGDIOBJ prev;
4451#endif /* HAVE_NTGUI */ 4448#endif /* HAVE_NTGUI */
4452 4449
4453 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);
4454 4453
4455#ifndef HAVE_NTGUI 4454#ifndef HAVE_NTGUI
4456 /* Get the X image IMG->pixmap. */ 4455 /* Get the X image IMG->pixmap. */
@@ -4602,7 +4601,9 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus
4602 4601
4603#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) 4602#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
4604 4603
4605 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);
4606 4607
4607 for (y = 0; y < img->height; ++y) 4608 for (y = 0; y < img->height; ++y)
4608 { 4609 {
@@ -4980,7 +4981,7 @@ static const struct image_keyword pbm_format[PBM_LAST] =
4980 {":file", IMAGE_STRING_VALUE, 0}, 4981 {":file", IMAGE_STRING_VALUE, 0},
4981 {":data", IMAGE_STRING_VALUE, 0}, 4982 {":data", IMAGE_STRING_VALUE, 0},
4982 {":ascent", IMAGE_ASCENT_VALUE, 0}, 4983 {":ascent", IMAGE_ASCENT_VALUE, 0},
4983 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 4984 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
4984 {":relief", IMAGE_INTEGER_VALUE, 0}, 4985 {":relief", IMAGE_INTEGER_VALUE, 0},
4985 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 4986 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4986 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 4987 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -5395,7 +5396,7 @@ static const struct image_keyword png_format[PNG_LAST] =
5395 {":data", IMAGE_STRING_VALUE, 0}, 5396 {":data", IMAGE_STRING_VALUE, 0},
5396 {":file", IMAGE_STRING_VALUE, 0}, 5397 {":file", IMAGE_STRING_VALUE, 0},
5397 {":ascent", IMAGE_ASCENT_VALUE, 0}, 5398 {":ascent", IMAGE_ASCENT_VALUE, 0},
5398 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 5399 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
5399 {":relief", IMAGE_INTEGER_VALUE, 0}, 5400 {":relief", IMAGE_INTEGER_VALUE, 0},
5400 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5401 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
5401 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 5402 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -5880,7 +5881,7 @@ png_load (struct frame *f, struct image *img)
5880 5881
5881 for (x = 0; x < width; ++x) 5882 for (x = 0; x < width; ++x)
5882 { 5883 {
5883 unsigned r, g, b; 5884 int r, g, b;
5884 5885
5885 r = *p++ << 8; 5886 r = *p++ << 8;
5886 g = *p++ << 8; 5887 g = *p++ << 8;
@@ -6015,7 +6016,7 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
6015 {":data", IMAGE_STRING_VALUE, 0}, 6016 {":data", IMAGE_STRING_VALUE, 0},
6016 {":file", IMAGE_STRING_VALUE, 0}, 6017 {":file", IMAGE_STRING_VALUE, 0},
6017 {":ascent", IMAGE_ASCENT_VALUE, 0}, 6018 {":ascent", IMAGE_ASCENT_VALUE, 0},
6018 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 6019 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6019 {":relief", IMAGE_INTEGER_VALUE, 0}, 6020 {":relief", IMAGE_INTEGER_VALUE, 0},
6020 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6021 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6021 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6022 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -6565,7 +6566,7 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
6565 {":data", IMAGE_STRING_VALUE, 0}, 6566 {":data", IMAGE_STRING_VALUE, 0},
6566 {":file", IMAGE_STRING_VALUE, 0}, 6567 {":file", IMAGE_STRING_VALUE, 0},
6567 {":ascent", IMAGE_ASCENT_VALUE, 0}, 6568 {":ascent", IMAGE_ASCENT_VALUE, 0},
6568 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 6569 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6569 {":relief", IMAGE_INTEGER_VALUE, 0}, 6570 {":relief", IMAGE_INTEGER_VALUE, 0},
6570 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6571 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6571 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 6572 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -6745,17 +6746,29 @@ tiff_size_of_memory (thandle_t data)
6745} 6746}
6746 6747
6747 6748
6749static void tiff_handler (const char *, const char *, const char *, va_list)
6750 ATTRIBUTE_FORMAT_PRINTF (3, 0);
6751static void
6752tiff_handler (const char *log_format, const char *title,
6753 const char *format, va_list ap)
6754{
6755 /* doprnt is not suitable here, as TIFF handlers are called from
6756 libtiff and are passed arbitrary printf directives. Instead, use
6757 vsnprintf, taking care to be portable to nonstandard environments
6758 where vsnprintf returns -1 on buffer overflow. Since it's just a
6759 log entry, it's OK to truncate it. */
6760 char buf[4000];
6761 int len = vsnprintf (buf, sizeof buf, format, ap);
6762 add_to_log (log_format, build_string (title),
6763 make_string (buf, max (0, min (len, sizeof buf - 1))));
6764}
6765
6748static void tiff_error_handler (const char *, const char *, va_list) 6766static void tiff_error_handler (const char *, const char *, va_list)
6749 ATTRIBUTE_FORMAT_PRINTF (2, 0); 6767 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6750static void 6768static void
6751tiff_error_handler (const char *title, const char *format, va_list ap) 6769tiff_error_handler (const char *title, const char *format, va_list ap)
6752{ 6770{
6753 char buf[512]; 6771 tiff_handler ("TIFF error: %s %s", title, format, ap);
6754 int len;
6755
6756 len = sprintf (buf, "TIFF error: %s ", title);
6757 vsprintf (buf + len, format, ap);
6758 add_to_log (buf, Qnil, Qnil);
6759} 6772}
6760 6773
6761 6774
@@ -6764,12 +6777,7 @@ static void tiff_warning_handler (const char *, const char *, va_list)
6764static void 6777static void
6765tiff_warning_handler (const char *title, const char *format, va_list ap) 6778tiff_warning_handler (const char *title, const char *format, va_list ap)
6766{ 6779{
6767 char buf[512]; 6780 tiff_handler ("TIFF warning: %s %s", title, format, ap);
6768 int len;
6769
6770 len = sprintf (buf, "TIFF warning: %s ", title);
6771 vsprintf (buf + len, format, ap);
6772 add_to_log (buf, Qnil, Qnil);
6773} 6781}
6774 6782
6775 6783
@@ -6845,8 +6853,9 @@ tiff_load (struct frame *f, struct image *img)
6845 image = image_spec_value (img->spec, QCindex, NULL); 6853 image = image_spec_value (img->spec, QCindex, NULL);
6846 if (INTEGERP (image)) 6854 if (INTEGERP (image))
6847 { 6855 {
6848 int ino = XFASTINT (image); 6856 EMACS_INT ino = XFASTINT (image);
6849 if (!fn_TIFFSetDirectory (tiff, ino)) 6857 if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
6858 && fn_TIFFSetDirectory (tiff, ino)))
6850 { 6859 {
6851 image_error ("Invalid image number `%s' in image `%s'", 6860 image_error ("Invalid image number `%s' in image `%s'",
6852 image, img->spec); 6861 image, img->spec);
@@ -6994,7 +7003,7 @@ static const struct image_keyword gif_format[GIF_LAST] =
6994 {":data", IMAGE_STRING_VALUE, 0}, 7003 {":data", IMAGE_STRING_VALUE, 0},
6995 {":file", IMAGE_STRING_VALUE, 0}, 7004 {":file", IMAGE_STRING_VALUE, 0},
6996 {":ascent", IMAGE_ASCENT_VALUE, 0}, 7005 {":ascent", IMAGE_ASCENT_VALUE, 0},
6997 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7006 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6998 {":relief", IMAGE_INTEGER_VALUE, 0}, 7007 {":relief", IMAGE_INTEGER_VALUE, 0},
6999 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7008 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7000 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7009 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -7139,13 +7148,12 @@ gif_load (struct frame *f, struct image *img)
7139 ColorMapObject *gif_color_map; 7148 ColorMapObject *gif_color_map;
7140 unsigned long pixel_colors[256]; 7149 unsigned long pixel_colors[256];
7141 GifFileType *gif; 7150 GifFileType *gif;
7142 int image_height, image_width;
7143 gif_memory_source memsrc; 7151 gif_memory_source memsrc;
7144 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); 7152 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7145 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); 7153 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
7146 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL); 7154 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
7147 unsigned long bgcolor = 0; 7155 unsigned long bgcolor = 0;
7148 int idx; 7156 EMACS_INT idx;
7149 7157
7150 if (NILP (specified_data)) 7158 if (NILP (specified_data))
7151 { 7159 {
@@ -7216,19 +7224,13 @@ gif_load (struct frame *f, struct image *img)
7216 } 7224 }
7217 } 7225 }
7218 7226
7219 img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top; 7227 width = img->width = gif->SWidth;
7220 img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left; 7228 height = img->height = gif->SHeight;
7221 image_height = gif->SavedImages[idx].ImageDesc.Height;
7222 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
7223 image_width = gif->SavedImages[idx].ImageDesc.Width;
7224 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
7225 7229
7226 width = img->width = max (gif->SWidth, 7230 img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
7227 max (gif->Image.Left + gif->Image.Width, 7231 img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
7228 img->corners[RIGHT_CORNER])); 7232 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + height;
7229 height = img->height = max (gif->SHeight, 7233 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + width;
7230 max (gif->Image.Top + gif->Image.Height,
7231 img->corners[BOT_CORNER]));
7232 7234
7233 if (!check_image_size (f, width, height)) 7235 if (!check_image_size (f, width, height))
7234 { 7236 {
@@ -7283,6 +7285,10 @@ gif_load (struct frame *f, struct image *img)
7283 unsigned char *raster = (unsigned char *) subimage->RasterBits; 7285 unsigned char *raster = (unsigned char *) subimage->RasterBits;
7284 int transparency_color_index = -1; 7286 int transparency_color_index = -1;
7285 int disposal = 0; 7287 int disposal = 0;
7288 int subimg_width = subimage->ImageDesc.Width;
7289 int subimg_height = subimage->ImageDesc.Height;
7290 int subimg_top = subimage->ImageDesc.Top;
7291 int subimg_left = subimage->ImageDesc.Left;
7286 7292
7287 /* Find the Graphic Control Extension block for this sub-image. 7293 /* Find the Graphic Control Extension block for this sub-image.
7288 Extract the disposal method and transparency color. */ 7294 Extract the disposal method and transparency color. */
@@ -7306,6 +7312,13 @@ gif_load (struct frame *f, struct image *img)
7306 if (j == 0) 7312 if (j == 0)
7307 disposal = 2; 7313 disposal = 2;
7308 7314
7315 /* For disposal == 0, the spec says "No disposal specified. The
7316 decoder is not required to take any action." In practice, it
7317 seems we need to treat this like "keep in place", see e.g.
7318 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7319 if (disposal == 0)
7320 disposal = 1;
7321
7309 /* Allocate subimage colors. */ 7322 /* Allocate subimage colors. */
7310 memset (pixel_colors, 0, sizeof pixel_colors); 7323 memset (pixel_colors, 0, sizeof pixel_colors);
7311 gif_color_map = subimage->ImageDesc.ColorMap; 7324 gif_color_map = subimage->ImageDesc.ColorMap;
@@ -7333,34 +7346,34 @@ gif_load (struct frame *f, struct image *img)
7333 int row, pass; 7346 int row, pass;
7334 7347
7335 for (y = 0, row = interlace_start[0], pass = 0; 7348 for (y = 0, row = interlace_start[0], pass = 0;
7336 y < image_height; 7349 y < subimg_height;
7337 y++, row += interlace_increment[pass]) 7350 y++, row += interlace_increment[pass])
7338 { 7351 {
7339 if (row >= image_height) 7352 if (row >= subimg_height)
7340 { 7353 {
7341 row = interlace_start[++pass]; 7354 row = interlace_start[++pass];
7342 while (row >= image_height) 7355 while (row >= subimg_height)
7343 row = interlace_start[++pass]; 7356 row = interlace_start[++pass];
7344 } 7357 }
7345 7358
7346 for (x = 0; x < image_width; x++) 7359 for (x = 0; x < subimg_width; x++)
7347 { 7360 {
7348 int c = raster[y * image_width + x]; 7361 int c = raster[y * subimg_width + x];
7349 if (transparency_color_index != c || disposal != 1) 7362 if (transparency_color_index != c || disposal != 1)
7350 XPutPixel (ximg, x + img->corners[LEFT_CORNER], 7363 XPutPixel (ximg, x + subimg_left, row + subimg_top,
7351 row + img->corners[TOP_CORNER], pixel_colors[c]); 7364 pixel_colors[c]);
7352 } 7365 }
7353 } 7366 }
7354 } 7367 }
7355 else 7368 else
7356 { 7369 {
7357 for (y = 0; y < image_height; ++y) 7370 for (y = 0; y < subimg_height; ++y)
7358 for (x = 0; x < image_width; ++x) 7371 for (x = 0; x < subimg_width; ++x)
7359 { 7372 {
7360 int c = raster[y * image_width + x]; 7373 int c = raster[y * subimg_width + x];
7361 if (transparency_color_index != c || disposal != 1) 7374 if (transparency_color_index != c || disposal != 1)
7362 XPutPixel (ximg, x + img->corners[LEFT_CORNER], 7375 XPutPixel (ximg, x + subimg_left, y + subimg_top,
7363 y + img->corners[TOP_CORNER], pixel_colors[c]); 7376 pixel_colors[c]);
7364 } 7377 }
7365 } 7378 }
7366 } 7379 }
@@ -7375,7 +7388,7 @@ gif_load (struct frame *f, struct image *img)
7375 img->lisp_data = Qnil; 7388 img->lisp_data = Qnil;
7376 if (gif->SavedImages[idx].ExtensionBlockCount > 0) 7389 if (gif->SavedImages[idx].ExtensionBlockCount > 0)
7377 { 7390 {
7378 unsigned int delay = 0; 7391 int delay = 0;
7379 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks; 7392 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
7380 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++) 7393 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
7381 /* Append (... FUNCTION "BYTES") */ 7394 /* Append (... FUNCTION "BYTES") */
@@ -7396,7 +7409,7 @@ gif_load (struct frame *f, struct image *img)
7396 if (delay) 7409 if (delay)
7397 img->lisp_data 7410 img->lisp_data
7398 = Fcons (Qdelay, 7411 = Fcons (Qdelay,
7399 Fcons (make_float (((double) delay) * 0.01), 7412 Fcons (make_float (delay / 100.0),
7400 img->lisp_data)); 7413 img->lisp_data));
7401 } 7414 }
7402 7415
@@ -7475,7 +7488,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7475 {":data", IMAGE_STRING_VALUE, 0}, 7488 {":data", IMAGE_STRING_VALUE, 0},
7476 {":file", IMAGE_STRING_VALUE, 0}, 7489 {":file", IMAGE_STRING_VALUE, 0},
7477 {":ascent", IMAGE_ASCENT_VALUE, 0}, 7490 {":ascent", IMAGE_ASCENT_VALUE, 0},
7478 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 7491 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7479 {":relief", IMAGE_INTEGER_VALUE, 0}, 7492 {":relief", IMAGE_INTEGER_VALUE, 0},
7480 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7493 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7481 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7494 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -7572,10 +7585,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
7572 Lisp_Object image; 7585 Lisp_Object image;
7573 Lisp_Object value; 7586 Lisp_Object value;
7574 Lisp_Object crop; 7587 Lisp_Object crop;
7575 long ino; 7588 EMACS_INT ino;
7576 int desired_width, desired_height; 7589 int desired_width, desired_height;
7577 double rotation; 7590 double rotation;
7578 int imagemagick_rendermethod; 7591 EMACS_INT imagemagick_rendermethod;
7579 int pixelwidth; 7592 int pixelwidth;
7580 ImageInfo *image_info; 7593 ImageInfo *image_info;
7581 ExceptionInfo *exception; 7594 ExceptionInfo *exception;
@@ -7602,7 +7615,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
7602 status = MagickPingImageBlob (ping_wand, contents, size); 7615 status = MagickPingImageBlob (ping_wand, contents, size);
7603 } 7616 }
7604 7617
7605 if (ino >= MagickGetNumberImages (ping_wand)) 7618 if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand)))
7606 { 7619 {
7607 image_error ("Invalid image number `%s' in image `%s'", 7620 image_error ("Invalid image number `%s' in image `%s'",
7608 image, img->spec); 7621 image, img->spec);
@@ -7677,28 +7690,28 @@ imagemagick_load_image (struct frame *f, struct image *img,
7677 efficient. */ 7690 efficient. */
7678 crop = image_spec_value (img->spec, QCcrop, NULL); 7691 crop = image_spec_value (img->spec, QCcrop, NULL);
7679 7692
7680 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7693 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
7681 { 7694 {
7682 /* After some testing, it seems MagickCropImage is the fastest crop 7695 /* After some testing, it seems MagickCropImage is the fastest crop
7683 function in ImageMagick. This crop function seems to do less copying 7696 function in ImageMagick. This crop function seems to do less copying
7684 than the alternatives, but it still reads the entire image into memory 7697 than the alternatives, but it still reads the entire image into memory
7685 before croping, which is aparently difficult to avoid when using 7698 before cropping, which is apparently difficult to avoid when using
7686 imagemagick. */ 7699 imagemagick. */
7687 int w, h; 7700 size_t crop_width = XINT (XCAR (crop));
7688 w = XFASTINT (XCAR (crop));
7689 crop = XCDR (crop); 7701 crop = XCDR (crop);
7690 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7702 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
7691 { 7703 {
7692 h = XFASTINT (XCAR (crop)); 7704 size_t crop_height = XINT (XCAR (crop));
7693 crop = XCDR (crop); 7705 crop = XCDR (crop);
7694 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7706 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
7695 { 7707 {
7696 x = XFASTINT (XCAR (crop)); 7708 ssize_t crop_x = XINT (XCAR (crop));
7697 crop = XCDR (crop); 7709 crop = XCDR (crop);
7698 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7710 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
7699 { 7711 {
7700 y = XFASTINT (XCAR (crop)); 7712 ssize_t crop_y = XINT (XCAR (crop));
7701 MagickCropImage (image_wand, w, h, x, y); 7713 MagickCropImage (image_wand, crop_width, crop_height,
7714 crop_x, crop_y);
7702 } 7715 }
7703 } 7716 }
7704 } 7717 }
@@ -7744,9 +7757,11 @@ imagemagick_load_image (struct frame *f, struct image *img,
7744 7757
7745 init_color_table (); 7758 init_color_table ();
7746 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type) 7759 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
7747 ? XFASTINT (Vimagemagick_render_type) : 0); 7760 ? XINT (Vimagemagick_render_type) : 0);
7748 if (imagemagick_rendermethod == 0) 7761 if (imagemagick_rendermethod == 0)
7749 { 7762 {
7763 size_t image_height;
7764
7750 /* Try to create a x pixmap to hold the imagemagick pixmap. */ 7765 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7751 if (!x_create_x_image_and_pixmap (f, width, height, 0, 7766 if (!x_create_x_image_and_pixmap (f, width, height, 0,
7752 &ximg, &img->pixmap)) 7767 &ximg, &img->pixmap))
@@ -7775,7 +7790,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7775 goto imagemagick_error; 7790 goto imagemagick_error;
7776 } 7791 }
7777 7792
7778 for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++) 7793 image_height = MagickGetImageHeight (image_wand);
7794 for (y = 0; y < image_height; y++)
7779 { 7795 {
7780 pixels = PixelGetNextIteratorRow (iterator, &width); 7796 pixels = PixelGetNextIteratorRow (iterator, &width);
7781 if (pixels == (PixelWand **) NULL) 7797 if (pixels == (PixelWand **) NULL)
@@ -7995,7 +8011,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
7995 {":data", IMAGE_STRING_VALUE, 0}, 8011 {":data", IMAGE_STRING_VALUE, 0},
7996 {":file", IMAGE_STRING_VALUE, 0}, 8012 {":file", IMAGE_STRING_VALUE, 0},
7997 {":ascent", IMAGE_ASCENT_VALUE, 0}, 8013 {":ascent", IMAGE_ASCENT_VALUE, 0},
7998 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 8014 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7999 {":relief", IMAGE_INTEGER_VALUE, 0}, 8015 {":relief", IMAGE_INTEGER_VALUE, 0},
8000 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8016 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8001 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8017 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -8281,10 +8297,10 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
8281 { 8297 {
8282 for (x = 0; x < width; ++x) 8298 for (x = 0; x < width; ++x)
8283 { 8299 {
8284 unsigned red; 8300 int red;
8285 unsigned green; 8301 int green;
8286 unsigned blue; 8302 int blue;
8287 unsigned opacity; 8303 int opacity;
8288 8304
8289 red = *pixels++; 8305 red = *pixels++;
8290 green = *pixels++; 8306 green = *pixels++;
@@ -8390,7 +8406,7 @@ static const struct image_keyword gs_format[GS_LAST] =
8390 {":loader", IMAGE_FUNCTION_VALUE, 0}, 8406 {":loader", IMAGE_FUNCTION_VALUE, 0},
8391 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, 8407 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
8392 {":ascent", IMAGE_ASCENT_VALUE, 0}, 8408 {":ascent", IMAGE_ASCENT_VALUE, 0},
8393 {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, 8409 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
8394 {":relief", IMAGE_INTEGER_VALUE, 0}, 8410 {":relief", IMAGE_INTEGER_VALUE, 0},
8395 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8411 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8396 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 8412 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -8465,7 +8481,8 @@ gs_image_p (Lisp_Object object)
8465static int 8481static int
8466gs_load (struct frame *f, struct image *img) 8482gs_load (struct frame *f, struct image *img)
8467{ 8483{
8468 char buffer[100]; 8484 uprintmax_t printnum1, printnum2;
8485 char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)];
8469 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; 8486 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
8470 Lisp_Object frame; 8487 Lisp_Object frame;
8471 double in_width, in_height; 8488 double in_width, in_height;
@@ -8477,16 +8494,19 @@ gs_load (struct frame *f, struct image *img)
8477 info. */ 8494 info. */
8478 pt_width = image_spec_value (img->spec, QCpt_width, NULL); 8495 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
8479 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0; 8496 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
8480 img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; 8497 in_width *= FRAME_X_DISPLAY_INFO (f)->resx;
8481 pt_height = image_spec_value (img->spec, QCpt_height, NULL); 8498 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
8482 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0; 8499 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
8483 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; 8500 in_height *= FRAME_X_DISPLAY_INFO (f)->resy;
8484 8501
8485 if (!check_image_size (f, img->width, img->height)) 8502 if (! (in_width <= INT_MAX && in_height <= INT_MAX
8503 && check_image_size (f, in_width, in_height)))
8486 { 8504 {
8487 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 8505 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
8488 return 0; 8506 return 0;
8489 } 8507 }
8508 img->width = in_width;
8509 img->height = in_height;
8490 8510
8491 /* Create the pixmap. */ 8511 /* Create the pixmap. */
8492 xassert (img->pixmap == NO_PIXMAP); 8512 xassert (img->pixmap == NO_PIXMAP);
@@ -8511,14 +8531,14 @@ gs_load (struct frame *f, struct image *img)
8511 if successful. We do not record_unwind_protect here because 8531 if successful. We do not record_unwind_protect here because
8512 other places in redisplay like calling window scroll functions 8532 other places in redisplay like calling window scroll functions
8513 don't either. Let the Lisp loader use `unwind-protect' instead. */ 8533 don't either. Let the Lisp loader use `unwind-protect' instead. */
8514 sprintf (buffer, "%lu %lu", 8534 printnum1 = FRAME_X_WINDOW (f);
8515 (unsigned long) FRAME_X_WINDOW (f), 8535 printnum2 = img->pixmap;
8516 (unsigned long) img->pixmap); 8536 sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
8517 window_and_pixmap_id = build_string (buffer); 8537 window_and_pixmap_id = build_string (buffer);
8518 8538
8519 sprintf (buffer, "%lu %lu", 8539 printnum1 = FRAME_FOREGROUND_PIXEL (f);
8520 FRAME_FOREGROUND_PIXEL (f), 8540 printnum2 = FRAME_BACKGROUND_PIXEL (f);
8521 FRAME_BACKGROUND_PIXEL (f)); 8541 sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
8522 pixel_colors = build_string (buffer); 8542 pixel_colors = build_string (buffer);
8523 8543
8524 XSETFRAME (frame, f); 8544 XSETFRAME (frame, f);
@@ -8543,7 +8563,8 @@ void
8543x_kill_gs_process (Pixmap pixmap, struct frame *f) 8563x_kill_gs_process (Pixmap pixmap, struct frame *f)
8544{ 8564{
8545 struct image_cache *c = FRAME_IMAGE_CACHE (f); 8565 struct image_cache *c = FRAME_IMAGE_CACHE (f);
8546 int class, i; 8566 int class;
8567 ptrdiff_t i;
8547 struct image *img; 8568 struct image *img;
8548 8569
8549 /* Find the image containing PIXMAP. */ 8570 /* Find the image containing PIXMAP. */
@@ -8647,7 +8668,7 @@ DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
8647DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") 8668DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8648 (Lisp_Object spec) 8669 (Lisp_Object spec)
8649{ 8670{
8650 int id = -1; 8671 ptrdiff_t id = -1;
8651 8672
8652 if (valid_image_p (spec)) 8673 if (valid_image_p (spec))
8653 id = lookup_image (SELECTED_FRAME (), spec); 8674 id = lookup_image (SELECTED_FRAME (), spec);