aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorPaul Eggert2015-08-18 16:17:30 -0700
committerPaul Eggert2015-08-18 16:24:56 -0700
commit636736861688abe73cc5dd4181fdb66de3fd8cfd (patch)
tree94e6780e22be312f57d32ef1b8768b4708c8cc45 /src/image.c
parent345284f5e9eebb07536d12c08c72f1bab02ea55e (diff)
downloademacs-636736861688abe73cc5dd4181fdb66de3fd8cfd.tar.gz
emacs-636736861688abe73cc5dd4181fdb66de3fd8cfd.zip
Fix file name encodings in diagnostics
Also, close some minor races when opening image files, by opening them once instead of multiple times. * src/gtkutil.c (xg_get_image_for_pixmap): * src/image.c (xpm_load, tiff_load, gif_load, imagemagick_load) (svg_load): * src/nsimage.m (allocInitFromFile:): * src/xfns.c (xg_set_icon): Encode file name, since x_find_image_file no longer does that. * src/image.c (x_find_image_fd): New function. (x_find_image_file): Use it. Do not encode resulting file name, since callers sometimes need it decoded. (slurp_file): File arg is now a fd, not a file name. All callers changed. This saves us having to open the file twice. (xbm_load, xpm_load, pbm_load, png_load_body, jpeg_load_body) (svg_load): Use x_find_image_fd and fdopen to save a file-open. Report file name that failed. * src/lread.c (openp): If PREDICATE is t, open the file in binary mode.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c133
1 files changed, 71 insertions, 62 deletions
diff --git a/src/image.c b/src/image.c
index fb8c6e79168..8f9b06cc284 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2270,11 +2270,13 @@ image_unget_x_image (struct image *img, bool mask_p, XImagePtr ximg)
2270 ***********************************************************************/ 2270 ***********************************************************************/
2271 2271
2272/* Find image file FILE. Look in data-directory/images, then 2272/* Find image file FILE. Look in data-directory/images, then
2273 x-bitmap-file-path. Value is the encoded full name of the file 2273 x-bitmap-file-path. Value is the full name of the file
2274 found, or nil if not found. */ 2274 found, or nil if not found. If PFD is nonnull store into *PFD a
2275 readable file descriptor for the file, opened in binary mode. If
2276 PFD is null, do not open the file. */
2275 2277
2276Lisp_Object 2278static Lisp_Object
2277x_find_image_file (Lisp_Object file) 2279x_find_image_fd (Lisp_Object file, int *pfd)
2278{ 2280{
2279 Lisp_Object file_found, search_path; 2281 Lisp_Object file_found, search_path;
2280 int fd; 2282 int fd;
@@ -2286,29 +2288,35 @@ x_find_image_file (Lisp_Object file)
2286 Vx_bitmap_file_path); 2288 Vx_bitmap_file_path);
2287 2289
2288 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */ 2290 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
2289 fd = openp (search_path, file, Qnil, &file_found, Qnil, false); 2291 fd = openp (search_path, file, Qnil, &file_found,
2290 2292 pfd ? Qt : make_number (R_OK), false);
2291 if (fd == -1) 2293 if (fd < 0)
2292 file_found = Qnil; 2294 return Qnil;
2293 else 2295 if (pfd)
2294 { 2296 *pfd = fd;
2295 file_found = ENCODE_FILE (file_found);
2296 if (fd != -2)
2297 emacs_close (fd);
2298 }
2299
2300 return file_found; 2297 return file_found;
2301} 2298}
2302 2299
2300/* Find image file FILE. Look in data-directory/images, then
2301 x-bitmap-file-path. Value is the encoded full name of the file
2302 found, or nil if not found. */
2303
2304Lisp_Object
2305x_find_image_file (Lisp_Object file)
2306{
2307 return x_find_image_fd (file, 0);
2308}
2303 2309
2304/* Read FILE into memory. Value is a pointer to a buffer allocated 2310/* Read FILE into memory. Value is a pointer to a buffer allocated
2305 with xmalloc holding FILE's contents. Value is null if an error 2311 with xmalloc holding FILE's contents. Value is null if an error
2306 occurred. *SIZE is set to the size of the file. */ 2312 occurred. FD is a file descriptor open for reading FILE. Set
2313 *SIZE to the size of the file. */
2307 2314
2308static unsigned char * 2315static unsigned char *
2309slurp_file (char *file, ptrdiff_t *size) 2316slurp_file (int fd, ptrdiff_t *size)
2310{ 2317{
2311 FILE *fp = emacs_fopen (file, "rb"); 2318 FILE *fp = fdopen (fd, "rb");
2319
2312 unsigned char *buf = NULL; 2320 unsigned char *buf = NULL;
2313 struct stat st; 2321 struct stat st;
2314 2322
@@ -2980,21 +2988,19 @@ xbm_load (struct frame *f, struct image *img)
2980 file_name = image_spec_value (img->spec, QCfile, NULL); 2988 file_name = image_spec_value (img->spec, QCfile, NULL);
2981 if (STRINGP (file_name)) 2989 if (STRINGP (file_name))
2982 { 2990 {
2983 Lisp_Object file; 2991 int fd;
2984 unsigned char *contents; 2992 Lisp_Object file = x_find_image_fd (file_name, &fd);
2985 ptrdiff_t size;
2986
2987 file = x_find_image_file (file_name);
2988 if (!STRINGP (file)) 2993 if (!STRINGP (file))
2989 { 2994 {
2990 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name); 2995 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
2991 return 0; 2996 return 0;
2992 } 2997 }
2993 2998
2994 contents = slurp_file (SSDATA (file), &size); 2999 ptrdiff_t size;
3000 unsigned char *contents = slurp_file (fd, &size);
2995 if (contents == NULL) 3001 if (contents == NULL)
2996 { 3002 {
2997 image_error ("Error loading XBM image "uLSQM"%s"uRSQM, img->spec); 3003 image_error ("Error loading XBM image "uLSQM"%s"uRSQM, file);
2998 return 0; 3004 return 0;
2999 } 3005 }
3000 3006
@@ -3640,6 +3646,7 @@ xpm_load (struct frame *f, struct image *img)
3640 return 0; 3646 return 0;
3641 } 3647 }
3642 3648
3649 file = ENCODE_FILE (file);
3643#ifdef HAVE_NTGUI 3650#ifdef HAVE_NTGUI
3644#ifdef WINDOWSNT 3651#ifdef WINDOWSNT
3645 /* FILE is encoded in UTF-8, but image libraries on Windows 3652 /* FILE is encoded in UTF-8, but image libraries on Windows
@@ -4290,21 +4297,19 @@ xpm_load (struct frame *f,
4290 file_name = image_spec_value (img->spec, QCfile, NULL); 4297 file_name = image_spec_value (img->spec, QCfile, NULL);
4291 if (STRINGP (file_name)) 4298 if (STRINGP (file_name))
4292 { 4299 {
4293 Lisp_Object file; 4300 int fd;
4294 unsigned char *contents; 4301 Lisp_Object file = x_find_image_fd (file_name, &fd);
4295 ptrdiff_t size;
4296
4297 file = x_find_image_file (file_name);
4298 if (!STRINGP (file)) 4302 if (!STRINGP (file))
4299 { 4303 {
4300 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name); 4304 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
4301 return 0; 4305 return 0;
4302 } 4306 }
4303 4307
4304 contents = slurp_file (SSDATA (file), &size); 4308 ptrdiff_t size;
4309 unsigned char *contents = slurp_file (fd, &size);
4305 if (contents == NULL) 4310 if (contents == NULL)
4306 { 4311 {
4307 image_error ("Error loading XPM image "uLSQM"%s"uRSQM, img->spec); 4312 image_error ("Error loading XPM image "uLSQM"%s"uRSQM, file);
4308 return 0; 4313 return 0;
4309 } 4314 }
4310 4315
@@ -5253,11 +5258,10 @@ pbm_load (struct frame *f, struct image *img)
5253 bool raw_p; 5258 bool raw_p;
5254 int x, y; 5259 int x, y;
5255 int width, height, max_color_idx = 0; 5260 int width, height, max_color_idx = 0;
5256 Lisp_Object file, specified_file; 5261 Lisp_Object specified_file;
5257 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; 5262 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5258 unsigned char *contents = NULL; 5263 unsigned char *contents = NULL;
5259 unsigned char *end, *p; 5264 unsigned char *end, *p;
5260 ptrdiff_t size;
5261#ifdef USE_CAIRO 5265#ifdef USE_CAIRO
5262 unsigned char *data = 0; 5266 unsigned char *data = 0;
5263 uint32_t *dataptr; 5267 uint32_t *dataptr;
@@ -5269,7 +5273,8 @@ pbm_load (struct frame *f, struct image *img)
5269 5273
5270 if (STRINGP (specified_file)) 5274 if (STRINGP (specified_file))
5271 { 5275 {
5272 file = x_find_image_file (specified_file); 5276 int fd;
5277 Lisp_Object file = x_find_image_fd (specified_file, &fd);
5273 if (!STRINGP (file)) 5278 if (!STRINGP (file))
5274 { 5279 {
5275 image_error ("Cannot find image file "uLSQM"%s"uRSQM, 5280 image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@@ -5277,7 +5282,8 @@ pbm_load (struct frame *f, struct image *img)
5277 return 0; 5282 return 0;
5278 } 5283 }
5279 5284
5280 contents = slurp_file (SSDATA (file), &size); 5285 ptrdiff_t size;
5286 contents = slurp_file (fd, &size);
5281 if (contents == NULL) 5287 if (contents == NULL)
5282 { 5288 {
5283 image_error ("Error reading "uLSQM"%s"uRSQM, file); 5289 image_error ("Error reading "uLSQM"%s"uRSQM, file);
@@ -5878,7 +5884,7 @@ struct png_load_context
5878static bool 5884static bool
5879png_load_body (struct frame *f, struct image *img, struct png_load_context *c) 5885png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5880{ 5886{
5881 Lisp_Object file, specified_file; 5887 Lisp_Object specified_file;
5882 Lisp_Object specified_data; 5888 Lisp_Object specified_data;
5883 int x, y; 5889 int x, y;
5884 ptrdiff_t i; 5890 ptrdiff_t i;
@@ -5909,7 +5915,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5909 5915
5910 if (NILP (specified_data)) 5916 if (NILP (specified_data))
5911 { 5917 {
5912 file = x_find_image_file (specified_file); 5918 int fd;
5919 Lisp_Object file = x_find_image_fd (specified_file, &fd);
5913 if (!STRINGP (file)) 5920 if (!STRINGP (file))
5914 { 5921 {
5915 image_error ("Cannot find image file "uLSQM"%s"uRSQM, 5922 image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@@ -5918,7 +5925,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5918 } 5925 }
5919 5926
5920 /* Open the image file. */ 5927 /* Open the image file. */
5921 fp = emacs_fopen (SSDATA (file), "rb"); 5928 fp = fdopen (fd, "rb");
5922 if (!fp) 5929 if (!fp)
5923 { 5930 {
5924 image_error ("Cannot open image file "uLSQM"%s"uRSQM, file); 5931 image_error ("Cannot open image file "uLSQM"%s"uRSQM, file);
@@ -6654,7 +6661,7 @@ static bool
6654jpeg_load_body (struct frame *f, struct image *img, 6661jpeg_load_body (struct frame *f, struct image *img,
6655 struct my_jpeg_error_mgr *mgr) 6662 struct my_jpeg_error_mgr *mgr)
6656{ 6663{
6657 Lisp_Object file, specified_file; 6664 Lisp_Object specified_file;
6658 Lisp_Object specified_data; 6665 Lisp_Object specified_data;
6659 /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */ 6666 /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */
6660 FILE * IF_LINT (volatile) fp = NULL; 6667 FILE * IF_LINT (volatile) fp = NULL;
@@ -6674,7 +6681,8 @@ jpeg_load_body (struct frame *f, struct image *img,
6674 6681
6675 if (NILP (specified_data)) 6682 if (NILP (specified_data))
6676 { 6683 {
6677 file = x_find_image_file (specified_file); 6684 int fd;
6685 Lisp_Object file = x_find_image_fd (specified_file, &fd);
6678 if (!STRINGP (file)) 6686 if (!STRINGP (file))
6679 { 6687 {
6680 image_error ("Cannot find image file "uLSQM"%s"uRSQM, 6688 image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@@ -6682,7 +6690,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6682 return 0; 6690 return 0;
6683 } 6691 }
6684 6692
6685 fp = emacs_fopen (SSDATA (file), "rb"); 6693 fp = fdopen (fd, "rb");
6686 if (fp == NULL) 6694 if (fp == NULL)
6687 { 6695 {
6688 image_error ("Cannot open "uLSQM"%s"uRSQM, file); 6696 image_error ("Cannot open "uLSQM"%s"uRSQM, file);
@@ -7172,7 +7180,7 @@ tiff_warning_handler (const char *title, const char *format, va_list ap)
7172static bool 7180static bool
7173tiff_load (struct frame *f, struct image *img) 7181tiff_load (struct frame *f, struct image *img)
7174{ 7182{
7175 Lisp_Object file, specified_file; 7183 Lisp_Object specified_file;
7176 Lisp_Object specified_data; 7184 Lisp_Object specified_data;
7177 TIFF *tiff; 7185 TIFF *tiff;
7178 int width, height, x, y, count; 7186 int width, height, x, y, count;
@@ -7191,19 +7199,21 @@ tiff_load (struct frame *f, struct image *img)
7191 if (NILP (specified_data)) 7199 if (NILP (specified_data))
7192 { 7200 {
7193 /* Read from a file */ 7201 /* Read from a file */
7194 file = x_find_image_file (specified_file); 7202 Lisp_Object file = x_find_image_file (specified_file);
7195 if (!STRINGP (file)) 7203 if (!STRINGP (file))
7196 { 7204 {
7197 image_error ("Cannot find image file "uLSQM"%s"uRSQM, 7205 image_error ("Cannot find image file "uLSQM"%s"uRSQM,
7198 specified_file); 7206 specified_file);
7199 return 0; 7207 return 0;
7200 } 7208 }
7209
7210 Lisp_Object encoded_file = ENCODE_FILE (file);
7201# ifdef WINDOWSNT 7211# ifdef WINDOWSNT
7202 file = ansi_encode_filename (file); 7212 encoded_file = ansi_encode_filename (encoded_file);
7203# endif 7213# endif
7204 7214
7205 /* Try to open the image file. */ 7215 /* Try to open the image file. */
7206 tiff = TIFFOpen (SSDATA (file), "r"); 7216 tiff = TIFFOpen (SSDATA (encoded_file), "r");
7207 if (tiff == NULL) 7217 if (tiff == NULL)
7208 { 7218 {
7209 image_error ("Cannot open "uLSQM"%s"uRSQM, file); 7219 image_error ("Cannot open "uLSQM"%s"uRSQM, file);
@@ -7605,7 +7615,6 @@ static const int interlace_increment[] = {8, 8, 4, 2};
7605static bool 7615static bool
7606gif_load (struct frame *f, struct image *img) 7616gif_load (struct frame *f, struct image *img)
7607{ 7617{
7608 Lisp_Object file;
7609 int rc, width, height, x, y, i, j; 7618 int rc, width, height, x, y, i, j;
7610 ColorMapObject *gif_color_map; 7619 ColorMapObject *gif_color_map;
7611 unsigned long pixel_colors[256]; 7620 unsigned long pixel_colors[256];
@@ -7626,27 +7635,29 @@ gif_load (struct frame *f, struct image *img)
7626 7635
7627 if (NILP (specified_data)) 7636 if (NILP (specified_data))
7628 { 7637 {
7629 file = x_find_image_file (specified_file); 7638 Lisp_Object file = x_find_image_file (specified_file);
7630 if (!STRINGP (file)) 7639 if (!STRINGP (file))
7631 { 7640 {
7632 image_error ("Cannot find image file "uLSQM"%s"uRSQM, 7641 image_error ("Cannot find image file "uLSQM"%s"uRSQM,
7633 specified_file); 7642 specified_file);
7634 return 0; 7643 return 0;
7635 } 7644 }
7645
7646 Lisp_Object encoded_file = ENCODE_FILE (file);
7636#ifdef WINDOWSNT 7647#ifdef WINDOWSNT
7637 file = ansi_encode_filename (file); 7648 encoded_file = ansi_encode_filename (encoded_file);
7638#endif 7649#endif
7639 7650
7640 /* Open the GIF file. */ 7651 /* Open the GIF file. */
7641#if GIFLIB_MAJOR < 5 7652#if GIFLIB_MAJOR < 5
7642 gif = DGifOpenFileName (SSDATA (file)); 7653 gif = DGifOpenFileName (SSDATA (encoded_file));
7643 if (gif == NULL) 7654 if (gif == NULL)
7644 { 7655 {
7645 image_error ("Cannot open "uLSQM"%s"uRSQM, file); 7656 image_error ("Cannot open "uLSQM"%s"uRSQM, file);
7646 return 0; 7657 return 0;
7647 } 7658 }
7648#else 7659#else
7649 gif = DGifOpenFileName (SSDATA (file), &gif_err); 7660 gif = DGifOpenFileName (SSDATA (encoded_file), &gif_err);
7650 if (gif == NULL) 7661 if (gif == NULL)
7651 { 7662 {
7652 image_error ("Cannot open "uLSQM"%s"uRSQM": %s", 7663 image_error ("Cannot open "uLSQM"%s"uRSQM": %s",
@@ -8818,14 +8829,13 @@ imagemagick_load (struct frame *f, struct image *img)
8818 file_name = image_spec_value (img->spec, QCfile, NULL); 8829 file_name = image_spec_value (img->spec, QCfile, NULL);
8819 if (STRINGP (file_name)) 8830 if (STRINGP (file_name))
8820 { 8831 {
8821 Lisp_Object file; 8832 Lisp_Object file = x_find_image_file (file_name);
8822
8823 file = x_find_image_file (file_name);
8824 if (!STRINGP (file)) 8833 if (!STRINGP (file))
8825 { 8834 {
8826 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name); 8835 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
8827 return 0; 8836 return 0;
8828 } 8837 }
8838 file = ENCODE_FILE (file);
8829#ifdef WINDOWSNT 8839#ifdef WINDOWSNT
8830 file = ansi_encode_filename (file); 8840 file = ansi_encode_filename (file);
8831#endif 8841#endif
@@ -9097,11 +9107,8 @@ svg_load (struct frame *f, struct image *img)
9097 file_name = image_spec_value (img->spec, QCfile, NULL); 9107 file_name = image_spec_value (img->spec, QCfile, NULL);
9098 if (STRINGP (file_name)) 9108 if (STRINGP (file_name))
9099 { 9109 {
9100 Lisp_Object file; 9110 int fd;
9101 unsigned char *contents; 9111 Lisp_Object file = x_find_image_fd (file_name, &fd);
9102 ptrdiff_t size;
9103
9104 file = x_find_image_file (file_name);
9105 if (!STRINGP (file)) 9112 if (!STRINGP (file))
9106 { 9113 {
9107 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name); 9114 image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
@@ -9109,14 +9116,16 @@ svg_load (struct frame *f, struct image *img)
9109 } 9116 }
9110 9117
9111 /* Read the entire file into memory. */ 9118 /* Read the entire file into memory. */
9112 contents = slurp_file (SSDATA (file), &size); 9119 ptrdiff_t size;
9120 unsigned char *contents = slurp_file (fd, &size);
9113 if (contents == NULL) 9121 if (contents == NULL)
9114 { 9122 {
9115 image_error ("Error loading SVG image "uLSQM"%s"uRSQM, img->spec); 9123 image_error ("Error loading SVG image "uLSQM"%s"uRSQM, file);
9116 return 0; 9124 return 0;
9117 } 9125 }
9118 /* If the file was slurped into memory properly, parse it. */ 9126 /* If the file was slurped into memory properly, parse it. */
9119 success_p = svg_load_image (f, img, contents, size, SSDATA (file)); 9127 success_p = svg_load_image (f, img, contents, size,
9128 SSDATA (ENCODE_FILE (file)));
9120 xfree (contents); 9129 xfree (contents);
9121 } 9130 }
9122 /* Else its not a file, its a lisp object. Load the image from a 9131 /* Else its not a file, its a lisp object. Load the image from a