diff options
| author | Lars Magne Ingebrigtsen | 2013-06-23 21:24:27 +0200 |
|---|---|---|
| committer | Lars Magne Ingebrigtsen | 2013-06-23 21:24:27 +0200 |
| commit | f3f9606c7acb4b3248dbe6f9fe16db6d5e46c3af (patch) | |
| tree | c96757e2023bc5b30e6ba77f58478cefcabd9ac7 /src | |
| parent | e854cfc719363ccee23beaa7d0f79aab65d82a98 (diff) | |
| download | emacs-f3f9606c7acb4b3248dbe6f9fe16db6d5e46c3af.tar.gz emacs-f3f9606c7acb4b3248dbe6f9fe16db6d5e46c3af.zip | |
Implement :max-width/:max-height for (ImageMagic) images
* doc/lispref/display.texi (ImageMagick Images): Mention :max-width and
:max-height.
* lisp/net/shr.el (shr-rescale-image): Use the new
:max-width/:max-height functionality.
* src/image.c (compute_image_size): New function to implement
:max-width and :max-height.
(imagemagick_load_image): Use it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/image.c | 98 |
2 files changed, 87 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b2773ddbf50..f9451711f32 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2013-06-23 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * image.c (compute_image_size): New function to implement | ||
| 4 | :max-width and :max-height. | ||
| 5 | (imagemagick_load_image): Use it. | ||
| 6 | |||
| 1 | 2013-06-23 Paul Eggert <eggert@cs.ucla.edu> | 7 | 2013-06-23 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 8 | ||
| 3 | Try to avoid malloc SEGVs on Cygwin (Bug#14569). | 9 | Try to avoid malloc SEGVs on Cygwin (Bug#14569). |
diff --git a/src/image.c b/src/image.c index ffb3cd15e93..b65ee7df789 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -132,6 +132,8 @@ static void free_color_table (void); | |||
| 132 | static unsigned long *colors_in_color_table (int *n); | 132 | static unsigned long *colors_in_color_table (int *n); |
| 133 | #endif | 133 | #endif |
| 134 | 134 | ||
| 135 | Lisp_Object QCmax_width, QCmax_height; | ||
| 136 | |||
| 135 | /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap | 137 | /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap |
| 136 | id, which is just an int that this section returns. Bitmaps are | 138 | id, which is just an int that this section returns. Bitmaps are |
| 137 | reference counted so they can be shared among frames. | 139 | reference counted so they can be shared among frames. |
| @@ -7489,6 +7491,76 @@ gif_load (struct frame *f, struct image *img) | |||
| 7489 | #endif /* HAVE_GIF */ | 7491 | #endif /* HAVE_GIF */ |
| 7490 | 7492 | ||
| 7491 | 7493 | ||
| 7494 | static void | ||
| 7495 | compute_image_size (size_t width, size_t height, | ||
| 7496 | Lisp_Object spec, | ||
| 7497 | int *d_width, int *d_height) | ||
| 7498 | { | ||
| 7499 | Lisp_Object value; | ||
| 7500 | int desired_width, desired_height; | ||
| 7501 | |||
| 7502 | /* If width and/or height is set in the display spec assume we want | ||
| 7503 | to scale to those values. If either h or w is unspecified, the | ||
| 7504 | unspecified should be calculated from the specified to preserve | ||
| 7505 | aspect ratio. */ | ||
| 7506 | value = image_spec_value (spec, QCwidth, NULL); | ||
| 7507 | desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7508 | value = image_spec_value (spec, QCheight, NULL); | ||
| 7509 | desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7510 | |||
| 7511 | if (desired_width == -1) | ||
| 7512 | { | ||
| 7513 | value = image_spec_value (spec, QCmax_width, NULL); | ||
| 7514 | if (INTEGERP (value) && | ||
| 7515 | width > XFASTINT (value)) | ||
| 7516 | { | ||
| 7517 | /* The image is wider than :max-width. */ | ||
| 7518 | desired_width = XFASTINT (value); | ||
| 7519 | if (desired_height == -1) | ||
| 7520 | { | ||
| 7521 | value = image_spec_value (spec, QCmax_height, NULL); | ||
| 7522 | if (INTEGERP (value)) | ||
| 7523 | { | ||
| 7524 | /* We have no specified height, but we have a | ||
| 7525 | :max-height value, so check that we satisfy both | ||
| 7526 | conditions. */ | ||
| 7527 | desired_height = (double) desired_width / width * height; | ||
| 7528 | if (desired_height > XFASTINT (value)) | ||
| 7529 | { | ||
| 7530 | desired_height = XFASTINT (value); | ||
| 7531 | desired_width = (double) desired_height / height * width; | ||
| 7532 | } | ||
| 7533 | } | ||
| 7534 | else | ||
| 7535 | { | ||
| 7536 | /* We have no specified height and no specified | ||
| 7537 | max-height, so just compute the height. */ | ||
| 7538 | desired_height = (double) desired_width / width * height; | ||
| 7539 | } | ||
| 7540 | } | ||
| 7541 | } | ||
| 7542 | } | ||
| 7543 | |||
| 7544 | if (desired_height == -1) | ||
| 7545 | { | ||
| 7546 | value = image_spec_value (spec, QCmax_height, NULL); | ||
| 7547 | if (INTEGERP (value) && | ||
| 7548 | height > XFASTINT (value)) | ||
| 7549 | desired_height = XFASTINT (value); | ||
| 7550 | } | ||
| 7551 | |||
| 7552 | if (desired_width != -1 && desired_height == -1) | ||
| 7553 | /* w known, calculate h. */ | ||
| 7554 | desired_height = (double) desired_width / width * height; | ||
| 7555 | |||
| 7556 | if (desired_width == -1 && desired_height != -1) | ||
| 7557 | /* h known, calculate w. */ | ||
| 7558 | desired_width = (double) desired_height / height * width; | ||
| 7559 | |||
| 7560 | *d_width = desired_width; | ||
| 7561 | *d_height = desired_height; | ||
| 7562 | } | ||
| 7563 | |||
| 7492 | /*********************************************************************** | 7564 | /*********************************************************************** |
| 7493 | ImageMagick | 7565 | ImageMagick |
| 7494 | ***********************************************************************/ | 7566 | ***********************************************************************/ |
| @@ -7516,6 +7588,8 @@ enum imagemagick_keyword_index | |||
| 7516 | IMAGEMAGICK_BACKGROUND, | 7588 | IMAGEMAGICK_BACKGROUND, |
| 7517 | IMAGEMAGICK_HEIGHT, | 7589 | IMAGEMAGICK_HEIGHT, |
| 7518 | IMAGEMAGICK_WIDTH, | 7590 | IMAGEMAGICK_WIDTH, |
| 7591 | IMAGEMAGICK_MAX_HEIGHT, | ||
| 7592 | IMAGEMAGICK_MAX_WIDTH, | ||
| 7519 | IMAGEMAGICK_ROTATION, | 7593 | IMAGEMAGICK_ROTATION, |
| 7520 | IMAGEMAGICK_CROP, | 7594 | IMAGEMAGICK_CROP, |
| 7521 | IMAGEMAGICK_LAST | 7595 | IMAGEMAGICK_LAST |
| @@ -7538,6 +7612,8 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = | |||
| 7538 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, | 7612 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, |
| 7539 | {":height", IMAGE_INTEGER_VALUE, 0}, | 7613 | {":height", IMAGE_INTEGER_VALUE, 0}, |
| 7540 | {":width", IMAGE_INTEGER_VALUE, 0}, | 7614 | {":width", IMAGE_INTEGER_VALUE, 0}, |
| 7615 | {":max-height", IMAGE_INTEGER_VALUE, 0}, | ||
| 7616 | {":max-width", IMAGE_INTEGER_VALUE, 0}, | ||
| 7541 | {":rotation", IMAGE_NUMBER_VALUE, 0}, | 7617 | {":rotation", IMAGE_NUMBER_VALUE, 0}, |
| 7542 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} | 7618 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} |
| 7543 | }; | 7619 | }; |
| @@ -7726,24 +7802,10 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7726 | PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535); | 7802 | PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535); |
| 7727 | } | 7803 | } |
| 7728 | 7804 | ||
| 7729 | /* If width and/or height is set in the display spec assume we want | 7805 | compute_image_size (MagickGetImageWidth (image_wand), |
| 7730 | to scale to those values. If either h or w is unspecified, the | 7806 | MagickGetImageHeight (image_wand), |
| 7731 | unspecified should be calculated from the specified to preserve | 7807 | img->spec, &desired_width, &desired_height); |
| 7732 | aspect ratio. */ | ||
| 7733 | value = image_spec_value (img->spec, QCwidth, NULL); | ||
| 7734 | desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7735 | value = image_spec_value (img->spec, QCheight, NULL); | ||
| 7736 | desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7737 | |||
| 7738 | height = MagickGetImageHeight (image_wand); | ||
| 7739 | width = MagickGetImageWidth (image_wand); | ||
| 7740 | 7808 | ||
| 7741 | if (desired_width != -1 && desired_height == -1) | ||
| 7742 | /* w known, calculate h. */ | ||
| 7743 | desired_height = (double) desired_width / width * height; | ||
| 7744 | if (desired_width == -1 && desired_height != -1) | ||
| 7745 | /* h known, calculate w. */ | ||
| 7746 | desired_width = (double) desired_height / height * width; | ||
| 7747 | if (desired_width != -1 && desired_height != -1) | 7809 | if (desired_width != -1 && desired_height != -1) |
| 7748 | { | 7810 | { |
| 7749 | status = MagickScaleImage (image_wand, desired_width, desired_height); | 7811 | status = MagickScaleImage (image_wand, desired_width, desired_height); |
| @@ -8895,6 +8957,8 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 8895 | DEFSYM (Qheuristic, "heuristic"); | 8957 | DEFSYM (Qheuristic, "heuristic"); |
| 8896 | 8958 | ||
| 8897 | DEFSYM (Qpostscript, "postscript"); | 8959 | DEFSYM (Qpostscript, "postscript"); |
| 8960 | DEFSYM (QCmax_width, ":max-width"); | ||
| 8961 | DEFSYM (QCmax_height, ":max-height"); | ||
| 8898 | #ifdef HAVE_GHOSTSCRIPT | 8962 | #ifdef HAVE_GHOSTSCRIPT |
| 8899 | ADD_IMAGE_TYPE (Qpostscript); | 8963 | ADD_IMAGE_TYPE (Qpostscript); |
| 8900 | DEFSYM (QCloader, ":loader"); | 8964 | DEFSYM (QCloader, ":loader"); |