diff options
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 104 |
1 files changed, 60 insertions, 44 deletions
diff --git a/src/image.c b/src/image.c index 2c288342028..c085e6e63eb 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License | |||
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | 19 | ||
| 20 | #include <config.h> | 20 | #include <config.h> |
| 21 | #include <stdio.h> | 21 | #include "sysstdio.h" |
| 22 | #include <unistd.h> | 22 | #include <unistd.h> |
| 23 | 23 | ||
| 24 | #ifdef HAVE_PNG | 24 | #ifdef HAVE_PNG |
| @@ -316,7 +316,6 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file) | |||
| 316 | int xhot, yhot, result; | 316 | int xhot, yhot, result; |
| 317 | ptrdiff_t id; | 317 | ptrdiff_t id; |
| 318 | Lisp_Object found; | 318 | Lisp_Object found; |
| 319 | int fd; | ||
| 320 | char *filename; | 319 | char *filename; |
| 321 | 320 | ||
| 322 | /* Look for an existing bitmap with the same name. */ | 321 | /* Look for an existing bitmap with the same name. */ |
| @@ -332,10 +331,8 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file) | |||
| 332 | } | 331 | } |
| 333 | 332 | ||
| 334 | /* Search bitmap-file-path for the file, if appropriate. */ | 333 | /* Search bitmap-file-path for the file, if appropriate. */ |
| 335 | fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil); | 334 | if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0) |
| 336 | if (fd < 0) | ||
| 337 | return -1; | 335 | return -1; |
| 338 | emacs_close (fd); | ||
| 339 | 336 | ||
| 340 | filename = SSDATA (found); | 337 | filename = SSDATA (found); |
| 341 | 338 | ||
| @@ -2260,7 +2257,8 @@ x_find_image_file (Lisp_Object file) | |||
| 2260 | else | 2257 | else |
| 2261 | { | 2258 | { |
| 2262 | file_found = ENCODE_FILE (file_found); | 2259 | file_found = ENCODE_FILE (file_found); |
| 2263 | close (fd); | 2260 | if (fd != -2) |
| 2261 | emacs_close (fd); | ||
| 2264 | } | 2262 | } |
| 2265 | 2263 | ||
| 2266 | return file_found; | 2264 | return file_found; |
| @@ -2274,7 +2272,7 @@ x_find_image_file (Lisp_Object file) | |||
| 2274 | static unsigned char * | 2272 | static unsigned char * |
| 2275 | slurp_file (char *file, ptrdiff_t *size) | 2273 | slurp_file (char *file, ptrdiff_t *size) |
| 2276 | { | 2274 | { |
| 2277 | FILE *fp = fopen (file, "rb"); | 2275 | FILE *fp = emacs_fopen (file, "rb"); |
| 2278 | unsigned char *buf = NULL; | 2276 | unsigned char *buf = NULL; |
| 2279 | struct stat st; | 2277 | struct stat st; |
| 2280 | 2278 | ||
| @@ -4559,7 +4557,6 @@ x_to_xcolors (struct frame *f, struct image *img, bool rgb_p) | |||
| 4559 | XColor *colors, *p; | 4557 | XColor *colors, *p; |
| 4560 | XImagePtr_or_DC ximg; | 4558 | XImagePtr_or_DC ximg; |
| 4561 | #ifdef HAVE_NTGUI | 4559 | #ifdef HAVE_NTGUI |
| 4562 | HDC hdc; | ||
| 4563 | HGDIOBJ prev; | 4560 | HGDIOBJ prev; |
| 4564 | #endif /* HAVE_NTGUI */ | 4561 | #endif /* HAVE_NTGUI */ |
| 4565 | 4562 | ||
| @@ -4929,7 +4926,6 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) | |||
| 4929 | #ifndef HAVE_NTGUI | 4926 | #ifndef HAVE_NTGUI |
| 4930 | XImagePtr mask_img; | 4927 | XImagePtr mask_img; |
| 4931 | #else | 4928 | #else |
| 4932 | HDC frame_dc; | ||
| 4933 | HGDIOBJ prev; | 4929 | HGDIOBJ prev; |
| 4934 | char *mask_img; | 4930 | char *mask_img; |
| 4935 | int row_width; | 4931 | int row_width; |
| @@ -5725,7 +5721,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5725 | } | 5721 | } |
| 5726 | 5722 | ||
| 5727 | /* Open the image file. */ | 5723 | /* Open the image file. */ |
| 5728 | fp = fopen (SSDATA (file), "rb"); | 5724 | fp = emacs_fopen (SSDATA (file), "rb"); |
| 5729 | if (!fp) | 5725 | if (!fp) |
| 5730 | { | 5726 | { |
| 5731 | image_error ("Cannot open image file `%s'", file, Qnil); | 5727 | image_error ("Cannot open image file `%s'", file, Qnil); |
| @@ -6486,7 +6482,7 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6486 | return 0; | 6482 | return 0; |
| 6487 | } | 6483 | } |
| 6488 | 6484 | ||
| 6489 | fp = fopen (SSDATA (file), "rb"); | 6485 | fp = emacs_fopen (SSDATA (file), "rb"); |
| 6490 | if (fp == NULL) | 6486 | if (fp == NULL) |
| 6491 | { | 6487 | { |
| 6492 | image_error ("Cannot open `%s'", file, Qnil); | 6488 | image_error ("Cannot open `%s'", file, Qnil); |
| @@ -7627,6 +7623,31 @@ gif_load (struct frame *f, struct image *img) | |||
| 7627 | #endif /* HAVE_GIF */ | 7623 | #endif /* HAVE_GIF */ |
| 7628 | 7624 | ||
| 7629 | 7625 | ||
| 7626 | #ifdef HAVE_IMAGEMAGICK | ||
| 7627 | |||
| 7628 | /*********************************************************************** | ||
| 7629 | ImageMagick | ||
| 7630 | ***********************************************************************/ | ||
| 7631 | |||
| 7632 | /* Scale an image size by returning SIZE / DIVISOR * MULTIPLIER, | ||
| 7633 | safely rounded and clipped to int range. */ | ||
| 7634 | |||
| 7635 | static int | ||
| 7636 | scale_image_size (int size, size_t divisor, size_t multiplier) | ||
| 7637 | { | ||
| 7638 | if (divisor != 0) | ||
| 7639 | { | ||
| 7640 | double s = size; | ||
| 7641 | double scaled = s * multiplier / divisor + 0.5; | ||
| 7642 | if (scaled < INT_MAX) | ||
| 7643 | return scaled; | ||
| 7644 | } | ||
| 7645 | return INT_MAX; | ||
| 7646 | } | ||
| 7647 | |||
| 7648 | /* Compute the desired size of an image with native size WIDTH x HEIGHT. | ||
| 7649 | Use SPEC to deduce the size. Store the desired size into | ||
| 7650 | *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */ | ||
| 7630 | static void | 7651 | static void |
| 7631 | compute_image_size (size_t width, size_t height, | 7652 | compute_image_size (size_t width, size_t height, |
| 7632 | Lisp_Object spec, | 7653 | Lisp_Object spec, |
| @@ -7640,39 +7661,36 @@ compute_image_size (size_t width, size_t height, | |||
| 7640 | unspecified should be calculated from the specified to preserve | 7661 | unspecified should be calculated from the specified to preserve |
| 7641 | aspect ratio. */ | 7662 | aspect ratio. */ |
| 7642 | value = image_spec_value (spec, QCwidth, NULL); | 7663 | value = image_spec_value (spec, QCwidth, NULL); |
| 7643 | desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); | 7664 | desired_width = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1; |
| 7644 | value = image_spec_value (spec, QCheight, NULL); | 7665 | value = image_spec_value (spec, QCheight, NULL); |
| 7645 | desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); | 7666 | desired_height = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1; |
| 7646 | 7667 | ||
| 7647 | if (desired_width == -1) | 7668 | if (desired_width == -1) |
| 7648 | { | 7669 | { |
| 7649 | value = image_spec_value (spec, QCmax_width, NULL); | 7670 | value = image_spec_value (spec, QCmax_width, NULL); |
| 7650 | if (INTEGERP (value) && | 7671 | if (NATNUMP (value)) |
| 7651 | width > XFASTINT (value)) | ||
| 7652 | { | 7672 | { |
| 7653 | /* The image is wider than :max-width. */ | 7673 | int max_width = min (XFASTINT (value), INT_MAX); |
| 7654 | desired_width = XFASTINT (value); | 7674 | if (max_width < width) |
| 7655 | if (desired_height == -1) | ||
| 7656 | { | 7675 | { |
| 7657 | value = image_spec_value (spec, QCmax_height, NULL); | 7676 | /* The image is wider than :max-width. */ |
| 7658 | if (INTEGERP (value)) | 7677 | desired_width = max_width; |
| 7678 | if (desired_height == -1) | ||
| 7659 | { | 7679 | { |
| 7660 | /* We have no specified height, but we have a | 7680 | desired_height = scale_image_size (desired_width, |
| 7661 | :max-height value, so check that we satisfy both | 7681 | width, height); |
| 7662 | conditions. */ | 7682 | value = image_spec_value (spec, QCmax_height, NULL); |
| 7663 | desired_height = (double) desired_width / width * height; | 7683 | if (NATNUMP (value)) |
| 7664 | if (desired_height > XFASTINT (value)) | ||
| 7665 | { | 7684 | { |
| 7666 | desired_height = XFASTINT (value); | 7685 | int max_height = min (XFASTINT (value), INT_MAX); |
| 7667 | desired_width = (double) desired_height / height * width; | 7686 | if (max_height < desired_height) |
| 7687 | { | ||
| 7688 | desired_height = max_height; | ||
| 7689 | desired_width = scale_image_size (desired_height, | ||
| 7690 | height, width); | ||
| 7691 | } | ||
| 7668 | } | 7692 | } |
| 7669 | } | 7693 | } |
| 7670 | else | ||
| 7671 | { | ||
| 7672 | /* We have no specified height and no specified | ||
| 7673 | max-height, so just compute the height. */ | ||
| 7674 | desired_height = (double) desired_width / width * height; | ||
| 7675 | } | ||
| 7676 | } | 7694 | } |
| 7677 | } | 7695 | } |
| 7678 | } | 7696 | } |
| @@ -7680,28 +7698,26 @@ compute_image_size (size_t width, size_t height, | |||
| 7680 | if (desired_height == -1) | 7698 | if (desired_height == -1) |
| 7681 | { | 7699 | { |
| 7682 | value = image_spec_value (spec, QCmax_height, NULL); | 7700 | value = image_spec_value (spec, QCmax_height, NULL); |
| 7683 | if (INTEGERP (value) && | 7701 | if (NATNUMP (value)) |
| 7684 | height > XFASTINT (value)) | 7702 | { |
| 7685 | desired_height = XFASTINT (value); | 7703 | int max_height = min (XFASTINT (value), INT_MAX); |
| 7704 | if (max_height < height) | ||
| 7705 | desired_height = max_height; | ||
| 7706 | } | ||
| 7686 | } | 7707 | } |
| 7687 | 7708 | ||
| 7688 | if (desired_width != -1 && desired_height == -1) | 7709 | if (desired_width != -1 && desired_height == -1) |
| 7689 | /* w known, calculate h. */ | 7710 | /* w known, calculate h. */ |
| 7690 | desired_height = (double) desired_width / width * height; | 7711 | desired_height = scale_image_size (desired_width, width, height); |
| 7691 | 7712 | ||
| 7692 | if (desired_width == -1 && desired_height != -1) | 7713 | if (desired_width == -1 && desired_height != -1) |
| 7693 | /* h known, calculate w. */ | 7714 | /* h known, calculate w. */ |
| 7694 | desired_width = (double) desired_height / height * width; | 7715 | desired_width = scale_image_size (desired_height, height, width); |
| 7695 | 7716 | ||
| 7696 | *d_width = desired_width; | 7717 | *d_width = desired_width; |
| 7697 | *d_height = desired_height; | 7718 | *d_height = desired_height; |
| 7698 | } | 7719 | } |
| 7699 | 7720 | ||
| 7700 | /*********************************************************************** | ||
| 7701 | ImageMagick | ||
| 7702 | ***********************************************************************/ | ||
| 7703 | #if defined (HAVE_IMAGEMAGICK) | ||
| 7704 | |||
| 7705 | static Lisp_Object Qimagemagick; | 7721 | static Lisp_Object Qimagemagick; |
| 7706 | 7722 | ||
| 7707 | static bool imagemagick_image_p (Lisp_Object); | 7723 | static bool imagemagick_image_p (Lisp_Object); |
| @@ -8036,7 +8052,7 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8036 | 8052 | ||
| 8037 | init_color_table (); | 8053 | init_color_table (); |
| 8038 | 8054 | ||
| 8039 | #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS | 8055 | #if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS) |
| 8040 | if (imagemagick_render_type != 0) | 8056 | if (imagemagick_render_type != 0) |
| 8041 | { | 8057 | { |
| 8042 | /* Magicexportimage is normally faster than pixelpushing. This | 8058 | /* Magicexportimage is normally faster than pixelpushing. This |