aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-07-04 08:25:54 -0700
committerPaul Eggert2013-07-04 08:25:54 -0700
commitb9ed53d53585d9e1122eb3e452c74db1f2506324 (patch)
tree03e6ca8998c87a2f2f6da1de688eeab6e37e93bf /src
parentcf13177e99d20e8db632ad6ed5defd3818f7d901 (diff)
downloademacs-b9ed53d53585d9e1122eb3e452c74db1f2506324.tar.gz
emacs-b9ed53d53585d9e1122eb3e452c74db1f2506324.zip
Scale ImageMagick images more carefully.
* image.c (scale_image_size) [HAVE_IMAGEMAGICK]: New function. (compute_image_size): Use it. Define only if HAVE_IMAGEMAGICK. Be more careful about avoiding undefined behavior after integer overflow and division by zero.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/image.c84
2 files changed, 60 insertions, 32 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9012f5ba16a..478e2bdf37a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12013-07-04 Paul Eggert <eggert@cs.ucla.edu>
2
3 Scale ImageMagick images more carefully.
4 * image.c (scale_image_size) [HAVE_IMAGEMAGICK]: New function.
5 (compute_image_size): Use it. Define only if HAVE_IMAGEMAGICK.
6 Be more careful about avoiding undefined behavior after
7 integer overflow and division by zero.
8
12013-07-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 92013-07-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2 10
3 * w32fns.c (Qgeometry, Qworkarea, Qmm_size, Qframes): New variables. 11 * w32fns.c (Qgeometry, Qworkarea, Qmm_size, Qframes): New variables.
diff --git a/src/image.c b/src/image.c
index 2f9a8442256..a3e103f9559 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7625,6 +7625,31 @@ gif_load (struct frame *f, struct image *img)
7625#endif /* HAVE_GIF */ 7625#endif /* HAVE_GIF */
7626 7626
7627 7627
7628#ifdef HAVE_IMAGEMAGICK
7629
7630/***********************************************************************
7631 ImageMagick
7632***********************************************************************/
7633
7634/* Scale an image size by returning SIZE / DIVISOR * MULTIPLIER,
7635 safely rounded and clipped to int range. */
7636
7637static int
7638scale_image_size (int size, size_t divisor, size_t multiplier)
7639{
7640 if (divisor != 0)
7641 {
7642 double s = size;
7643 double scaled = s * multiplier / divisor + 0.5;
7644 if (scaled < INT_MAX)
7645 return scaled;
7646 }
7647 return INT_MAX;
7648}
7649
7650/* Compute the desired size of an image with native size WIDTH x HEIGHT.
7651 Use SPEC to deduce the size. Store the desired size into
7652 *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
7628static void 7653static void
7629compute_image_size (size_t width, size_t height, 7654compute_image_size (size_t width, size_t height,
7630 Lisp_Object spec, 7655 Lisp_Object spec,
@@ -7638,39 +7663,36 @@ compute_image_size (size_t width, size_t height,
7638 unspecified should be calculated from the specified to preserve 7663 unspecified should be calculated from the specified to preserve
7639 aspect ratio. */ 7664 aspect ratio. */
7640 value = image_spec_value (spec, QCwidth, NULL); 7665 value = image_spec_value (spec, QCwidth, NULL);
7641 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); 7666 desired_width = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1;
7642 value = image_spec_value (spec, QCheight, NULL); 7667 value = image_spec_value (spec, QCheight, NULL);
7643 desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); 7668 desired_height = NATNUMP (value) ? min (XFASTINT (value), INT_MAX) : -1;
7644 7669
7645 if (desired_width == -1) 7670 if (desired_width == -1)
7646 { 7671 {
7647 value = image_spec_value (spec, QCmax_width, NULL); 7672 value = image_spec_value (spec, QCmax_width, NULL);
7648 if (INTEGERP (value) && 7673 if (NATNUMP (value))
7649 width > XFASTINT (value))
7650 { 7674 {
7651 /* The image is wider than :max-width. */ 7675 int max_width = min (XFASTINT (value), INT_MAX);
7652 desired_width = XFASTINT (value); 7676 if (max_width < width)
7653 if (desired_height == -1)
7654 { 7677 {
7655 value = image_spec_value (spec, QCmax_height, NULL); 7678 /* The image is wider than :max-width. */
7656 if (INTEGERP (value)) 7679 desired_width = max_width;
7680 if (desired_height == -1)
7657 { 7681 {
7658 /* We have no specified height, but we have a 7682 desired_height = scale_image_size (desired_width,
7659 :max-height value, so check that we satisfy both 7683 width, height);
7660 conditions. */ 7684 value = image_spec_value (spec, QCmax_height, NULL);
7661 desired_height = (double) desired_width / width * height; 7685 if (NATNUMP (value))
7662 if (desired_height > XFASTINT (value))
7663 { 7686 {
7664 desired_height = XFASTINT (value); 7687 int max_height = min (XFASTINT (value), INT_MAX);
7665 desired_width = (double) desired_height / height * width; 7688 if (max_height < desired_height)
7689 {
7690 desired_height = max_height;
7691 desired_width = scale_image_size (desired_height,
7692 height, width);
7693 }
7666 } 7694 }
7667 } 7695 }
7668 else
7669 {
7670 /* We have no specified height and no specified
7671 max-height, so just compute the height. */
7672 desired_height = (double) desired_width / width * height;
7673 }
7674 } 7696 }
7675 } 7697 }
7676 } 7698 }
@@ -7678,28 +7700,26 @@ compute_image_size (size_t width, size_t height,
7678 if (desired_height == -1) 7700 if (desired_height == -1)
7679 { 7701 {
7680 value = image_spec_value (spec, QCmax_height, NULL); 7702 value = image_spec_value (spec, QCmax_height, NULL);
7681 if (INTEGERP (value) && 7703 if (NATNUMP (value))
7682 height > XFASTINT (value)) 7704 {
7683 desired_height = XFASTINT (value); 7705 int max_height = min (XFASTINT (value), INT_MAX);
7706 if (max_height < height)
7707 desired_height = max_height;
7708 }
7684 } 7709 }
7685 7710
7686 if (desired_width != -1 && desired_height == -1) 7711 if (desired_width != -1 && desired_height == -1)
7687 /* w known, calculate h. */ 7712 /* w known, calculate h. */
7688 desired_height = (double) desired_width / width * height; 7713 desired_height = scale_image_size (desired_width, width, height);
7689 7714
7690 if (desired_width == -1 && desired_height != -1) 7715 if (desired_width == -1 && desired_height != -1)
7691 /* h known, calculate w. */ 7716 /* h known, calculate w. */
7692 desired_width = (double) desired_height / height * width; 7717 desired_width = scale_image_size (desired_height, height, width);
7693 7718
7694 *d_width = desired_width; 7719 *d_width = desired_width;
7695 *d_height = desired_height; 7720 *d_height = desired_height;
7696} 7721}
7697 7722
7698/***********************************************************************
7699 ImageMagick
7700***********************************************************************/
7701#if defined (HAVE_IMAGEMAGICK)
7702
7703static Lisp_Object Qimagemagick; 7723static Lisp_Object Qimagemagick;
7704 7724
7705static bool imagemagick_image_p (Lisp_Object); 7725static bool imagemagick_image_p (Lisp_Object);