aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorChong Yidong2005-10-19 03:54:56 +0000
committerChong Yidong2005-10-19 03:54:56 +0000
commitf1f25b99665ac3e5cd4c6cf70be8fdf637f10b52 (patch)
tree66f91ab3a7adf9a3ed66938d90a3da4674d916d0 /src/image.c
parentf42d19a283c2888320519c78093de6a788374634 (diff)
downloademacs-f1f25b99665ac3e5cd4c6cf70be8fdf637f10b52.tar.gz
emacs-f1f25b99665ac3e5cd4c6cf70be8fdf637f10b52.zip
* image.c (Vmax_image_size): New variable.
(check_image_size): New function. (xbm_read_bitmap_data, pbm_load, png_load, jpeg_load, tiff_load) (gif_load, gs_load): Use it. (lookup_image): Try loading again if previous load failed. (xbm_read_bitmap_data): Add a new argument, a pointer to the frame to display in, NULL if none. (xbm_load_image, xbm_file_p): Pass xbm_read_bitmap_data the new argument.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c94
1 files changed, 87 insertions, 7 deletions
diff --git a/src/image.c b/src/image.c
index 2463c24a33a..c0702c5ea8c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1099,7 +1099,10 @@ or omitted means use the selected frame. */)
1099 1099
1100static struct image *make_image P_ ((Lisp_Object spec, unsigned hash)); 1100static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
1101static void free_image P_ ((struct frame *f, struct image *img)); 1101static void free_image P_ ((struct frame *f, struct image *img));
1102static int check_image_size P_ ((struct frame *f, int width, int height));
1102 1103
1104#define MAX_IMAGE_SIZE 6.0
1105Lisp_Object Vmax_image_size;
1103 1106
1104/* Allocate and return a new image structure for image specification 1107/* Allocate and return a new image structure for image specification
1105 SPEC. SPEC has a hash value of HASH. */ 1108 SPEC. SPEC has a hash value of HASH. */
@@ -1151,6 +1154,27 @@ free_image (f, img)
1151 } 1154 }
1152} 1155}
1153 1156
1157/* Return 1 if the given widths and heights are valid for display;
1158 otherwise, return 0. */
1159
1160int
1161check_image_size (f, width, height)
1162 struct frame *f;
1163 int width;
1164 int height;
1165{
1166 if (width <= 0 || height <=0)
1167 return 0;
1168
1169 if (FLOATP (Vmax_image_size) && f
1170 && ((width > (int)(XFLOAT_DATA (Vmax_image_size)
1171 * FRAME_PIXEL_WIDTH (f)))
1172 || (height > (int)(XFLOAT_DATA (Vmax_image_size)
1173 * FRAME_PIXEL_HEIGHT (f)))))
1174 return 0;
1175
1176 return 1;
1177}
1154 1178
1155/* Prepare image IMG for display on frame F. Must be called before 1179/* Prepare image IMG for display on frame F. Must be called before
1156 drawing an image. */ 1180 drawing an image. */
@@ -1708,6 +1732,12 @@ lookup_image (f, spec)
1708 if (img->hash == hash && !NILP (Fequal (img->spec, spec))) 1732 if (img->hash == hash && !NILP (Fequal (img->spec, spec)))
1709 break; 1733 break;
1710 1734
1735 if (img && img->load_failed_p)
1736 {
1737 free_image (f, img);
1738 img = NULL;
1739 }
1740
1711 /* If not found, create a new image and cache it. */ 1741 /* If not found, create a new image and cache it. */
1712 if (img == NULL) 1742 if (img == NULL)
1713 { 1743 {
@@ -2551,7 +2581,8 @@ static int xbm_load P_ ((struct frame *f, struct image *img));
2551static int xbm_load_image P_ ((struct frame *f, struct image *img, 2581static int xbm_load_image P_ ((struct frame *f, struct image *img,
2552 unsigned char *, unsigned char *)); 2582 unsigned char *, unsigned char *));
2553static int xbm_image_p P_ ((Lisp_Object object)); 2583static int xbm_image_p P_ ((Lisp_Object object));
2554static int xbm_read_bitmap_data P_ ((unsigned char *, unsigned char *, 2584static int xbm_read_bitmap_data P_ ((struct frame *f,
2585 unsigned char *, unsigned char *,
2555 int *, int *, unsigned char **)); 2586 int *, int *, unsigned char **));
2556static int xbm_file_p P_ ((Lisp_Object)); 2587static int xbm_file_p P_ ((Lisp_Object));
2557 2588
@@ -2939,7 +2970,8 @@ Create_Pixmap_From_Bitmap_Data(f, img, data, fg, bg, non_default_colors)
2939 CONTENTS looks like an in-memory XBM file. */ 2970 CONTENTS looks like an in-memory XBM file. */
2940 2971
2941static int 2972static int
2942xbm_read_bitmap_data (contents, end, width, height, data) 2973xbm_read_bitmap_data (f, contents, end, width, height, data)
2974 struct frame *f;
2943 unsigned char *contents, *end; 2975 unsigned char *contents, *end;
2944 int *width, *height; 2976 int *width, *height;
2945 unsigned char **data; 2977 unsigned char **data;
@@ -2992,7 +3024,7 @@ xbm_read_bitmap_data (contents, end, width, height, data)
2992 expect (XBM_TK_NUMBER); 3024 expect (XBM_TK_NUMBER);
2993 } 3025 }
2994 3026
2995 if (*width < 0 || *height < 0) 3027 if (!check_image_size (f, *width, *height))
2996 goto failure; 3028 goto failure;
2997 else if (data == NULL) 3029 else if (data == NULL)
2998 goto success; 3030 goto success;
@@ -3096,7 +3128,7 @@ xbm_load_image (f, img, contents, end)
3096 unsigned char *data; 3128 unsigned char *data;
3097 int success_p = 0; 3129 int success_p = 0;
3098 3130
3099 rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); 3131 rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data);
3100 if (rc) 3132 if (rc)
3101 { 3133 {
3102 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); 3134 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
@@ -3150,7 +3182,7 @@ xbm_file_p (data)
3150{ 3182{
3151 int w, h; 3183 int w, h;
3152 return (STRINGP (data) 3184 return (STRINGP (data)
3153 && xbm_read_bitmap_data (SDATA (data), 3185 && xbm_read_bitmap_data (NULL, SDATA (data),
3154 (SDATA (data) 3186 (SDATA (data)
3155 + SBYTES (data)), 3187 + SBYTES (data)),
3156 &w, &h, NULL)); 3188 &w, &h, NULL));
@@ -5465,8 +5497,7 @@ pbm_load (f, img)
5465 max_color_idx = 255; 5497 max_color_idx = 255;
5466 } 5498 }
5467 5499
5468 if (width < 0 5500 if (!check_image_size (f, width, height)
5469 || height < 0
5470 || (type != PBM_MONO && max_color_idx < 0)) 5501 || (type != PBM_MONO && max_color_idx < 0))
5471 goto error; 5502 goto error;
5472 5503
@@ -5966,6 +5997,9 @@ png_load (f, img)
5966 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 5997 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
5967 &interlace_type, NULL, NULL); 5998 &interlace_type, NULL, NULL);
5968 5999
6000 if (!check_image_size (f, width, height))
6001 goto error;
6002
5969 /* If image contains simply transparency data, we prefer to 6003 /* If image contains simply transparency data, we prefer to
5970 construct a clipping mask. */ 6004 construct a clipping mask. */
5971 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) 6005 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
@@ -6726,6 +6760,12 @@ jpeg_load (f, img)
6726 width = img->width = cinfo.output_width; 6760 width = img->width = cinfo.output_width;
6727 height = img->height = cinfo.output_height; 6761 height = img->height = cinfo.output_height;
6728 6762
6763 if (!check_image_size (f, width, height))
6764 {
6765 image_error ("Invalid image size", Qnil, Qnil);
6766 longjmp (mgr.setjmp_buffer, 2);
6767 }
6768
6729 /* Create X image and pixmap. */ 6769 /* Create X image and pixmap. */
6730 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 6770 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6731 longjmp (mgr.setjmp_buffer, 2); 6771 longjmp (mgr.setjmp_buffer, 2);
@@ -7155,6 +7195,14 @@ tiff_load (f, img)
7155 of width x height 32-bit values. */ 7195 of width x height 32-bit values. */
7156 fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width); 7196 fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
7157 fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height); 7197 fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
7198
7199 if (!check_image_size (f, width, height))
7200 {
7201 image_error ("Invalid image size", Qnil, Qnil);
7202 UNGCPRO;
7203 return 0;
7204 }
7205
7158 buf = (uint32 *) xmalloc (width * height * sizeof *buf); 7206 buf = (uint32 *) xmalloc (width * height * sizeof *buf);
7159 7207
7160 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0); 7208 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
@@ -7459,6 +7507,15 @@ gif_load (f, img)
7459 } 7507 }
7460 } 7508 }
7461 7509
7510 /* Before reading entire contents, check the declared image size. */
7511 if (!check_image_size (f, gif->SWidth, gif->SHeight))
7512 {
7513 image_error ("Invalid image size", Qnil, Qnil);
7514 fn_DGifCloseFile (gif);
7515 UNGCPRO;
7516 return 0;
7517 }
7518
7462 /* Read entire contents. */ 7519 /* Read entire contents. */
7463 rc = fn_DGifSlurp (gif); 7520 rc = fn_DGifSlurp (gif);
7464 if (rc == GIF_ERROR) 7521 if (rc == GIF_ERROR)
@@ -7492,6 +7549,14 @@ gif_load (f, img)
7492 max (gif->Image.Top + gif->Image.Height, 7549 max (gif->Image.Top + gif->Image.Height,
7493 image_top + image_height)); 7550 image_top + image_height));
7494 7551
7552 if (!check_image_size (f, width, height))
7553 {
7554 image_error ("Invalid image size", Qnil, Qnil);
7555 fn_DGifCloseFile (gif);
7556 UNGCPRO;
7557 return 0;
7558 }
7559
7495 /* Create the X image and pixmap. */ 7560 /* Create the X image and pixmap. */
7496 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 7561 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7497 { 7562 {
@@ -7944,6 +8009,12 @@ gs_load (f, img)
7944 in_height = XFASTINT (pt_height) / 72.0; 8009 in_height = XFASTINT (pt_height) / 72.0;
7945 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; 8010 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
7946 8011
8012 if (!check_image_size (f, img->width, img->height))
8013 {
8014 image_error ("Invalid image size", Qnil, Qnil);
8015 return 0;
8016 }
8017
7947 /* Create the pixmap. */ 8018 /* Create the pixmap. */
7948 xassert (img->pixmap == NO_PIXMAP); 8019 xassert (img->pixmap == NO_PIXMAP);
7949 8020
@@ -8217,6 +8288,15 @@ listed; they're always supported. */);
8217 Vimage_library_alist = Qnil; 8288 Vimage_library_alist = Qnil;
8218 Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt); 8289 Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt);
8219 8290
8291 DEFVAR_LISP ("max-image-size", &Vmax_image_size,
8292 doc: /* Maximum size of an image, relative to the selected frame.
8293
8294This is a floating point number that is multiplied by the width and
8295height of the selected frame, to give the maximum width and height for
8296images. Emacs will not load an image into memory if its width or
8297height exceeds this limit. */);
8298 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
8299
8220 Vimage_type_cache = Qnil; 8300 Vimage_type_cache = Qnil;
8221 staticpro (&Vimage_type_cache); 8301 staticpro (&Vimage_type_cache);
8222 8302