diff options
| author | Paul Eggert | 2011-09-03 16:03:38 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-09-03 16:03:38 -0700 |
| commit | b49e353d9d01adbe60bc5d0b1658b4ef978b0b06 (patch) | |
| tree | 9f2ffa6f7a6562abf661a4951012b488ad8b1ae7 /src/image.c | |
| parent | 74b880cbc18bd0194c7b1fc44c4a983ee05adae2 (diff) | |
| parent | bc3200871917d5c54c8c4299a06bf8f8ba2ea02d (diff) | |
| download | emacs-b49e353d9d01adbe60bc5d0b1658b4ef978b0b06.tar.gz emacs-b49e353d9d01adbe60bc5d0b1658b4ef978b0b06.zip | |
Merge from trunk.
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 327 |
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) | |||
| 196 | int | 196 | int |
| 197 | x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) | 197 | x_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 | ||
| 247 | void | 235 | void |
| 248 | x_reference_bitmap (FRAME_PTR f, int id) | 236 | x_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 | ||
| 1714 | int | 1706 | ptrdiff_t |
| 1715 | lookup_image (struct frame *f, Lisp_Object spec) | 1707 | lookup_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 | |||
| 1825 | cache_image (struct frame *f, struct image *img) | 1814 | cache_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 | ||
| 4165 | static int ct_colors_allocated; | 4147 | static int ct_colors_allocated; |
| 4148 | enum | ||
| 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 | ||
| 6749 | static void tiff_handler (const char *, const char *, const char *, va_list) | ||
| 6750 | ATTRIBUTE_FORMAT_PRINTF (3, 0); | ||
| 6751 | static void | ||
| 6752 | tiff_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 | |||
| 6748 | static void tiff_error_handler (const char *, const char *, va_list) | 6766 | static void tiff_error_handler (const char *, const char *, va_list) |
| 6749 | ATTRIBUTE_FORMAT_PRINTF (2, 0); | 6767 | ATTRIBUTE_FORMAT_PRINTF (2, 0); |
| 6750 | static void | 6768 | static void |
| 6751 | tiff_error_handler (const char *title, const char *format, va_list ap) | 6769 | tiff_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) | |||
| 6764 | static void | 6777 | static void |
| 6765 | tiff_warning_handler (const char *title, const char *format, va_list ap) | 6778 | tiff_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) | |||
| 8465 | static int | 8481 | static int |
| 8466 | gs_load (struct frame *f, struct image *img) | 8482 | gs_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 | |||
| 8543 | x_kill_gs_process (Pixmap pixmap, struct frame *f) | 8563 | x_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, | |||
| 8647 | DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") | 8668 | DEFUN ("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); |