X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/b7e0ef72d0ac61b5d3ef06a3f565695c75ec2540..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/image.c
diff --git a/src/image.c b/src/image.c
index 6691cfc8a1..7fa28840c1 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1,6 +1,6 @@
/* Functions for image support on window system.
-Copyright (C) 1989, 1992-2013 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -21,13 +21,11 @@ along with GNU Emacs. If not, see . */
#include "sysstdio.h"
#include
-#ifdef HAVE_PNG
-#if defined HAVE_LIBPNG_PNG_H
-# include
-#else
+/* Include this before including to work around bugs with
+ older libpng; see Bug#17429. */
+#if defined HAVE_PNG && !defined HAVE_NS
# include
#endif
-#endif
#include
#include
@@ -87,11 +85,12 @@ typedef struct w32_bitmap_record Bitmap_Record;
#define x_defined_color w32_defined_color
#define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits)
-/* Versions of libpng and libgif that we were compiled with, or -1 if
- no PNG/GIF support was compiled in. This is tested by w32-win.el
- to correctly set up the alist used to search for the respective
- image libraries. */
-Lisp_Object Qlibpng_version, Qlibgif_version;
+/* Versions of libpng, libgif, and libjpeg that we were compiled with,
+ or -1 if no PNG/GIF support was compiled in. This is tested by
+ w32-win.el to correctly set up the alist used to search for the
+ respective image libraries. */
+Lisp_Object Qlibpng_version, Qlibgif_version, Qlibjpeg_version;
+
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
@@ -159,6 +158,7 @@ XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
/* Functions to access the contents of a bitmap, given an id. */
+#ifdef HAVE_X_WINDOWS
static int
x_bitmap_height (struct frame *f, ptrdiff_t id)
{
@@ -170,6 +170,7 @@ x_bitmap_width (struct frame *f, ptrdiff_t id)
{
return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width;
}
+#endif
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
ptrdiff_t
@@ -263,7 +264,7 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi
#ifdef HAVE_X_WINDOWS
dpyinfo->bitmaps[id - 1].pixmap = bitmap;
- dpyinfo->bitmaps[id - 1].have_mask = 0;
+ dpyinfo->bitmaps[id - 1].have_mask = false;
dpyinfo->bitmaps[id - 1].depth = 1;
#endif /* HAVE_X_WINDOWS */
@@ -326,7 +327,9 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
}
/* Search bitmap-file-path for the file, if appropriate. */
- if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
+ if (openp (Vx_bitmap_file_path, file, Qnil, &found,
+ make_number (R_OK), false)
+ < 0)
return -1;
filename = SSDATA (found);
@@ -338,7 +341,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
id = x_allocate_bitmap_record (f);
dpyinfo->bitmaps[id - 1].pixmap = bitmap;
- dpyinfo->bitmaps[id - 1].have_mask = 0;
+ dpyinfo->bitmaps[id - 1].have_mask = false;
dpyinfo->bitmaps[id - 1].refcount = 1;
dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
dpyinfo->bitmaps[id - 1].depth = 1;
@@ -514,7 +517,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
width, height);
XFreeGC (FRAME_X_DISPLAY (f), gc);
- dpyinfo->bitmaps[id - 1].have_mask = 1;
+ dpyinfo->bitmaps[id - 1].have_mask = true;
dpyinfo->bitmaps[id - 1].mask = mask;
XDestroyImage (ximg);
@@ -995,6 +998,11 @@ free_image (struct frame *f, struct image *img)
c->images[img->id] = NULL;
+ /* Windows NT redefines 'free', but in this file, we need to
+ avoid the redefinition. */
+#ifdef WINDOWSNT
+#undef free
+#endif
/* Free resources, then free IMG. */
img->type->free (f, img);
xfree (img);
@@ -1228,7 +1236,23 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D
return img->background_transparent;
}
-
+#if defined (HAVE_PNG) || defined (HAVE_NS) \
+ || defined (HAVE_IMAGEMAGICK) || defined (HAVE_RSVG)
+
+/* Store F's background color into *BGCOLOR. */
+static void
+x_query_frame_background_color (struct frame *f, XColor *bgcolor)
+{
+#ifndef HAVE_NS
+ bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
+ x_query_color (f, bgcolor);
+#else
+ ns_query_color (FRAME_BACKGROUND_COLOR (f), bgcolor, 1);
+#endif
+}
+
+#endif /* HAVE_PNG || HAVE_NS || HAVE_IMAGEMAGICK || HAVE_RSVG */
+
/***********************************************************************
Helper functions for X image types
***********************************************************************/
@@ -1520,7 +1544,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
clear_current_matrices (fr);
}
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 19;
}
unblock_input ();
@@ -1798,37 +1822,6 @@ cache_image (struct frame *f, struct image *img)
img->prev = NULL;
c->buckets[i] = img;
}
-
-
-/* Call FN on every image in the image cache of frame F. Used to mark
- Lisp Objects in the image cache. */
-
-/* Mark Lisp objects in image IMG. */
-
-static void
-mark_image (struct image *img)
-{
- mark_object (img->spec);
- mark_object (img->dependencies);
-
- if (!NILP (img->lisp_data))
- mark_object (img->lisp_data);
-}
-
-
-void
-mark_image_cache (struct image_cache *c)
-{
- if (c)
- {
- ptrdiff_t i;
- for (i = 0; i < c->used; ++i)
- if (c->images[i])
- mark_image (c->images[i]);
- }
-}
-
-
/***********************************************************************
X / NS / W32 support code
@@ -1927,7 +1920,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
}
/* Allocate image raster. */
- (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
+ (*ximg)->data = xmalloc_atomic ((*ximg)->bytes_per_line * height);
/* Allocate a pixmap of the same size. */
*pixmap = XCreatePixmap (display, window, width, height, depth);
@@ -2016,6 +2009,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
XSETINT (errcode, err);
image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
x_destroy_x_image (*ximg);
+ *ximg = NULL;
return 0;
}
@@ -2241,7 +2235,7 @@ x_find_image_file (Lisp_Object file)
Vx_bitmap_file_path);
/* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
- fd = openp (search_path, file, Qnil, &file_found, Qnil);
+ fd = openp (search_path, file, Qnil, &file_found, Qnil, false);
if (fd == -1)
file_found = Qnil;
@@ -2269,7 +2263,7 @@ slurp_file (char *file, ptrdiff_t *size)
if (fp)
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
record_unwind_protect_ptr (fclose_unwind, fp);
if (fstat (fileno (fp), &st) == 0
@@ -2288,7 +2282,7 @@ slurp_file (char *file, ptrdiff_t *size)
}
}
- unbind_to (count, Qnil);
+ dynwind_end ();
}
return buf;
@@ -2794,7 +2788,7 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
}
bytes_per_line = (*width + 7) / 8 + padding_p;
nbytes = bytes_per_line * *height;
- p = *data = xmalloc (nbytes);
+ p = *data = xmalloc_atomic (nbytes);
if (v10)
{
@@ -3025,13 +3019,13 @@ xbm_load (struct frame *f, struct image *img)
if (STRINGP (line))
memcpy (p, SDATA (line), nbytes);
else
- memcpy (p, XBOOL_VECTOR (line)->data, nbytes);
+ memcpy (p, bool_vector_data (line), nbytes);
}
}
else if (STRINGP (data))
bits = SSDATA (data);
else
- bits = (char *) XBOOL_VECTOR (data)->data;
+ bits = (char *) bool_vector_data (data);
#ifdef HAVE_NTGUI
{
@@ -3445,7 +3439,7 @@ x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
id = x_allocate_bitmap_record (f);
dpyinfo->bitmaps[id - 1].pixmap = bitmap;
- dpyinfo->bitmaps[id - 1].have_mask = 1;
+ dpyinfo->bitmaps[id - 1].have_mask = true;
dpyinfo->bitmaps[id - 1].mask = mask;
dpyinfo->bitmaps[id - 1].file = NULL;
dpyinfo->bitmaps[id - 1].height = attrs.height;
@@ -3589,6 +3583,12 @@ xpm_load (struct frame *f, struct image *img)
}
#ifdef HAVE_NTGUI
+#ifdef WINDOWSNT
+ /* FILE is encoded in UTF-8, but image libraries on Windows
+ support neither UTF-8 nor UTF-16 encoded file names. So we
+ need to re-encode it in ANSI. */
+ file = ansi_encode_filename (file);
+#endif
/* XpmReadFileToPixmap is not available in the Windows port of
libxpm. But XpmReadFileToImage almost does what we want. */
rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
@@ -3687,7 +3687,8 @@ xpm_load (struct frame *f, struct image *img)
#endif /* HAVE_NTGUI */
/* Remember allocated colors. */
- img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
+ img->colors = xnmalloc_atomic (attrs.nalloc_pixels,
+ sizeof *img->colors);
img->ncolors = attrs.nalloc_pixels;
for (i = 0; i < attrs.nalloc_pixels; ++i)
{
@@ -3943,9 +3944,7 @@ xpm_str_to_color_key (const char *s)
{
int i;
- for (i = 0;
- i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0];
- i++)
+ for (i = 0; i < ARRAYELTS (xpm_color_key_strings); i++)
if (strcmp (xpm_color_key_strings[i], s) == 0)
return i;
return -1;
@@ -3967,7 +3966,7 @@ xpm_load_image (struct frame *f,
Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int);
Lisp_Object frame, color_symbols, color_table;
int best_key;
- bool have_mask = 0;
+ bool have_mask = false;
XImagePtr ximg = NULL, mask_img = NULL;
#define match() \
@@ -4139,7 +4138,7 @@ xpm_load_image (struct frame *f,
#ifndef HAVE_NS
XPutPixel (mask_img, x, y,
(!EQ (color_val, Qt) ? PIX_MASK_DRAW
- : (have_mask = 1, PIX_MASK_RETAIN)));
+ : (have_mask = true, PIX_MASK_RETAIN)));
#else
if (EQ (color_val, Qt))
ns_set_alpha (ximg, x, y, 0);
@@ -4484,7 +4483,7 @@ colors_in_color_table (int *n)
}
else
{
- colors = xmalloc (ct_colors_allocated * sizeof *colors);
+ colors = xmalloc_atomic (ct_colors_allocated * sizeof *colors);
*n = ct_colors_allocated;
for (i = j = 0; i < CT_SIZE; ++i)
@@ -5105,6 +5104,27 @@ pbm_image_p (Lisp_Object object)
}
+/* Get next char skipping comments in Netpbm header. Returns -1 at
+ end of input. */
+
+static int
+pbm_next_char (unsigned char **s, unsigned char *end)
+{
+ int c = -1;
+
+ while (*s < end && (c = *(*s)++, c == '#'))
+ {
+ /* Skip to the next line break. */
+ while (*s < end && (c = *(*s)++, c != '\n' && c != '\r'))
+ ;
+
+ c = -1;
+ }
+
+ return c;
+}
+
+
/* Scan a decimal number from *S and return it. Advance *S while
reading the number. END is the end of the string. Value is -1 at
end of input. */
@@ -5114,28 +5134,16 @@ pbm_scan_number (unsigned char **s, unsigned char *end)
{
int c = 0, val = -1;
- while (*s < end)
- {
- /* Skip white-space. */
- while (*s < end && (c = *(*s)++, c_isspace (c)))
- ;
+ /* Skip white-space. */
+ while ((c = pbm_next_char (s, end)) != -1 && c_isspace (c))
+ ;
- if (c == '#')
- {
- /* Skip comment to end of line. */
- while (*s < end && (c = *(*s)++, c != '\n'))
- ;
- }
- else if (c_isdigit (c))
- {
- /* Read decimal number. */
- val = c - '0';
- while (*s < end && (c = *(*s)++, c_isdigit (c)))
- val = 10 * val + c - '0';
- break;
- }
- else
- break;
+ if (c_isdigit (c))
+ {
+ /* Read decimal number. */
+ val = c - '0';
+ while ((c = pbm_next_char (s, end)) != -1 && c_isdigit (c))
+ val = 10 * val + c - '0';
}
return val;
@@ -5197,6 +5205,7 @@ pbm_load (struct frame *f, struct image *img)
image_error ("Not a PBM image: `%s'", img->spec, Qnil);
error:
xfree (contents);
+ img->pixmap = NO_PIXMAP;
return 0;
}
@@ -5486,7 +5495,7 @@ png_image_p (Lisp_Object object)
#endif /* HAVE_PNG || HAVE_NS */
-#ifdef HAVE_PNG
+#if defined HAVE_PNG && !defined HAVE_NS
#ifdef WINDOWSNT
/* PNG library details. */
@@ -5518,7 +5527,7 @@ DEF_IMGLIB_FN (void, png_read_end, (png_structp, png_infop));
DEF_IMGLIB_FN (void, png_error, (png_structp, png_const_charp));
#if (PNG_LIBPNG_VER >= 10500)
-DEF_IMGLIB_FN (void, png_longjmp, (png_structp, int));
+DEF_IMGLIB_FN (void, png_longjmp, (png_structp, int)) PNG_NORETURN;
DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn, (png_structp, png_longjmp_ptr, size_t));
#endif /* libpng version >= 1.5 */
@@ -5590,24 +5599,26 @@ init_png_functions (void)
#endif /* WINDOWSNT */
-/* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
- Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
- substitute may munge the signal mask, but that should be OK here.
- MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
- the system header setjmp.h; don't mess up that. */
-#ifndef HAVE__SETJMP
-# define _setjmp(j) setjmp (j)
-# define _longjmp longjmp
+/* Fast implementations of setjmp and longjmp. Although setjmp and longjmp
+ will do, POSIX _setjmp and _longjmp (if available) are often faster.
+ Do not use sys_setjmp, as PNG supports only jmp_buf.
+ It's OK if the longjmp substitute restores the signal mask. */
+#ifdef HAVE__SETJMP
+# define FAST_SETJMP(j) _setjmp (j)
+# define FAST_LONGJMP _longjmp
+#else
+# define FAST_SETJMP(j) setjmp (j)
+# define FAST_LONGJMP longjmp
#endif
-#if (PNG_LIBPNG_VER < 10500)
-#define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
+#if PNG_LIBPNG_VER < 10500
+#define PNG_LONGJMP(ptr) FAST_LONGJMP ((ptr)->jmpbuf, 1)
#define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
#else
/* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
-#define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
+#define PNG_LONGJMP(ptr) fn_png_longjmp (ptr, 1)
#define PNG_JMPBUF(ptr) \
- (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf)))
+ (*fn_png_set_longjmp_fn (ptr, FAST_LONGJMP, sizeof (jmp_buf)))
#endif
/* Error and warning handlers installed when the PNG library
@@ -5792,7 +5803,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
/* Set error jump-back. We come back here when the PNG library
detects an error. */
- if (_setjmp (PNG_JMPBUF (png_ptr)))
+ if (FAST_SETJMP (PNG_JMPBUF (png_ptr)))
{
error:
if (c->png_ptr)
@@ -5862,43 +5873,23 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
/* png_color_16 *image_bg; */
Lisp_Object specified_bg
= image_spec_value (img->spec, QCbackground, NULL);
- int shift = (bit_depth == 16) ? 0 : 8;
+ XColor color;
- if (STRINGP (specified_bg))
+ /* If the user specified a color, try to use it; if not, use the
+ current frame background, ignoring any default background
+ color set by the image. */
+ if (STRINGP (specified_bg)
+ ? x_defined_color (f, SSDATA (specified_bg), &color, false)
+ : (x_query_frame_background_color (f, &color), true))
/* The user specified `:background', use that. */
{
- XColor color;
- if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
- {
- png_color_16 user_bg;
-
- memset (&user_bg, 0, sizeof user_bg);
- user_bg.red = color.red >> shift;
- user_bg.green = color.green >> shift;
- user_bg.blue = color.blue >> shift;
-
- fn_png_set_background (png_ptr, &user_bg,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
- }
- }
- else
- {
- /* We use the current frame background, ignoring any default
- background color set by the image. */
-#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
- XColor color;
- png_color_16 frame_background;
-
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- x_query_color (f, &color);
+ int shift = bit_depth == 16 ? 0 : 8;
+ png_color_16 bg = { 0 };
+ bg.red = color.red >> shift;
+ bg.green = color.green >> shift;
+ bg.blue = color.blue >> shift;
- memset (&frame_background, 0, sizeof frame_background);
- frame_background.red = color.red >> shift;
- frame_background.green = color.green >> shift;
- frame_background.blue = color.blue >> shift;
-#endif /* HAVE_X_WINDOWS */
-
- fn_png_set_background (png_ptr, &frame_background,
+ fn_png_set_background (png_ptr, &bg,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
}
@@ -5921,8 +5912,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
|| min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
memory_full (SIZE_MAX);
- c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
- c->rows = rows = xmalloc (height * sizeof *rows);
+ c->pixels = pixels = xmalloc_atomic (sizeof *pixels * row_bytes * height);
+ c->rows = rows = xmalloc_atomic (height * sizeof *rows);
for (i = 0; i < height; ++i)
rows[i] = pixels + i * row_bytes;
@@ -6040,9 +6031,8 @@ png_load (struct frame *f, struct image *img)
return png_load_body (f, img, &c);
}
-#else /* HAVE_PNG */
+#elif defined HAVE_NS
-#ifdef HAVE_NS
static bool
png_load (struct frame *f, struct image *img)
{
@@ -6050,10 +6040,8 @@ png_load (struct frame *f, struct image *img)
image_spec_value (img->spec, QCfile, NULL),
image_spec_value (img->spec, QCdata, NULL));
}
-#endif /* HAVE_NS */
-
-#endif /* !HAVE_PNG */
+#endif /* HAVE_NS */
@@ -6240,9 +6228,6 @@ struct my_jpeg_error_mgr
MY_JPEG_INVALID_IMAGE_SIZE,
MY_JPEG_CANNOT_CREATE_X
} failure_code;
-#ifdef lint
- FILE *fp;
-#endif
};
@@ -6447,7 +6432,6 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
src->mgr.next_input_byte = NULL;
}
-
/* Load image IMG for use on frame F. Patterned after example.c
from the JPEG lib. */
@@ -6457,7 +6441,8 @@ jpeg_load_body (struct frame *f, struct image *img,
{
Lisp_Object file, specified_file;
Lisp_Object specified_data;
- FILE *fp = NULL;
+ /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */
+ FILE * IF_LINT (volatile) fp = NULL;
JSAMPARRAY buffer;
int row_stride, x, y;
XImagePtr ximg = NULL;
@@ -6490,8 +6475,6 @@ jpeg_load_body (struct frame *f, struct image *img,
return 0;
}
- IF_LINT (mgr->fp = fp);
-
/* Customize libjpeg's error handling to call my_error_exit when an
error is detected. This function will perform a longjmp. */
mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub);
@@ -6530,9 +6513,6 @@ jpeg_load_body (struct frame *f, struct image *img,
return 0;
}
- /* Silence a bogus diagnostic; see GCC bug 54561. */
- IF_LINT (fp = mgr->fp);
-
/* Create the JPEG decompression object. Let it read from fp.
Read the JPEG image header. */
fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
@@ -6958,6 +6938,9 @@ tiff_load (struct frame *f, struct image *img)
image_error ("Cannot find image file `%s'", specified_file, Qnil);
return 0;
}
+#ifdef WINDOWSNT
+ file = ansi_encode_filename (file);
+#endif
/* Try to open the image file. */
tiff = fn_TIFFOpen (SSDATA (file), "r");
@@ -7031,7 +7014,7 @@ tiff_load (struct frame *f, struct image *img)
return 0;
}
- buf = xmalloc (sizeof *buf * width * height);
+ buf = xmalloc_atomic (sizeof *buf * width * height);
rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
@@ -7237,7 +7220,11 @@ gif_image_p (Lisp_Object object)
#ifdef WINDOWSNT
/* GIF library details. */
+#if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
+DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *, int *));
+#else
DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
+#endif
DEF_IMGLIB_FN (int, DGifSlurp, (GifFileType *));
#if GIFLIB_MAJOR < 5
DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc));
@@ -7307,6 +7294,22 @@ gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
return len;
}
+static int
+gif_close (GifFileType *gif, int *err)
+{
+ int retval;
+
+#if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
+ retval = fn_DGifCloseFile (gif, err);
+#else
+ retval = fn_DGifCloseFile (gif);
+#if GIFLIB_MAJOR >= 5
+ if (err)
+ *err = gif->Error;
+#endif
+#endif
+ return retval;
+}
/* Load GIF image IMG for use on frame F. Value is true if
successful. */
@@ -7331,9 +7334,7 @@ gif_load (struct frame *f, struct image *img)
Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
unsigned long bgcolor = 0;
EMACS_INT idx;
-#if GIFLIB_MAJOR >= 5
int gif_err;
-#endif
if (NILP (specified_data))
{
@@ -7343,6 +7344,9 @@ gif_load (struct frame *f, struct image *img)
image_error ("Cannot find image file `%s'", specified_file, Qnil);
return 0;
}
+#ifdef WINDOWSNT
+ file = ansi_encode_filename (file);
+#endif
/* Open the GIF file. */
#if GIFLIB_MAJOR < 5
@@ -7398,7 +7402,7 @@ gif_load (struct frame *f, struct image *img)
if (!check_image_size (f, gif->SWidth, gif->SHeight))
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
- fn_DGifCloseFile (gif);
+ gif_close (gif, NULL);
return 0;
}
@@ -7407,7 +7411,7 @@ gif_load (struct frame *f, struct image *img)
if (rc == GIF_ERROR || gif->ImageCount <= 0)
{
image_error ("Error reading `%s'", img->spec, Qnil);
- fn_DGifCloseFile (gif);
+ gif_close (gif, NULL);
return 0;
}
@@ -7419,7 +7423,7 @@ gif_load (struct frame *f, struct image *img)
{
image_error ("Invalid image number `%s' in image `%s'",
image_number, img->spec);
- fn_DGifCloseFile (gif);
+ gif_close (gif, NULL);
return 0;
}
}
@@ -7437,7 +7441,7 @@ gif_load (struct frame *f, struct image *img)
if (!check_image_size (f, width, height))
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
- fn_DGifCloseFile (gif);
+ gif_close (gif, NULL);
return 0;
}
@@ -7455,7 +7459,7 @@ gif_load (struct frame *f, struct image *img)
&& 0 <= subimg_left && subimg_left <= width - subimg_width))
{
image_error ("Subimage does not fit in image", Qnil, Qnil);
- fn_DGifCloseFile (gif);
+ gif_close (gif, NULL);
return 0;
}
}
@@ -7463,7 +7467,7 @@ gif_load (struct frame *f, struct image *img)
/* Create the X image and pixmap. */
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
{
- fn_DGifCloseFile (gif);
+ gif_close (gif, NULL);
return 0;
}
@@ -7562,7 +7566,7 @@ gif_load (struct frame *f, struct image *img)
}
/* Apply the pixel values. */
- if (gif->SavedImages[j].ImageDesc.Interlace)
+ if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
{
int row, pass;
@@ -7634,7 +7638,18 @@ gif_load (struct frame *f, struct image *img)
Fcons (make_number (gif->ImageCount),
img->lisp_data));
- fn_DGifCloseFile (gif);
+ if (gif_close (gif, &gif_err) == GIF_ERROR)
+ {
+#if 5 <= GIFLIB_MAJOR
+ char *error_text = fn_GifErrorString (gif_err);
+
+ if (error_text)
+ image_error ("Error closing `%s': %s",
+ img->spec, build_string (error_text));
+#else
+ image_error ("Error closing `%s'", img->spec, Qnil);
+#endif
+ }
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
@@ -7882,7 +7897,7 @@ imagemagick_error (MagickWand *wand)
image_error ("ImageMagick error: %s",
build_string (description),
Qnil);
- description = (char *) MagickRelinquishMemory (description);
+ MagickRelinquishMemory (description);
}
/* Possibly give ImageMagick some extra help to determine the image
@@ -8083,7 +8098,7 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
{
/* Sanity check. This shouldn't happen, but apparently
also does in some pictures. */
- if (x + source_left > dest_width)
+ if (x + source_left > dest_width - 1)
break;
/* Normally we only copy over non-transparent pixels,
but if the disposal method is "Background", then we
@@ -8208,14 +8223,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
specified_bg = image_spec_value (img->spec, QCbackground, NULL);
if (!STRINGP (specified_bg)
|| !x_defined_color (f, SSDATA (specified_bg), &bgcolor, 0))
- {
-#ifndef HAVE_NS
- bgcolor.pixel = FRAME_BACKGROUND_PIXEL (f);
- x_query_color (f, &bgcolor);
-#else
- ns_query_color (FRAME_BACKGROUND_COLOR (f), &bgcolor, 1);
-#endif
- }
+ x_query_frame_background_color (f, &bgcolor);
bg_wand = NewPixelWand ();
PixelSetRed (bg_wand, (double) bgcolor.red / 65535);
@@ -8367,6 +8375,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
#endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
{
size_t image_height;
+ MagickRealType color_scale = 65535.0 / QuantumRange;
/* Try to create a x pixmap to hold the imagemagick pixmap. */
if (!image_create_x_image_and_pixmap (f, img, width, height, 0,
@@ -8407,9 +8416,9 @@ imagemagick_load_image (struct frame *f, struct image *img,
PixelGetMagickColor (pixels[x], &pixel);
XPutPixel (ximg, x, y,
lookup_rgb_color (f,
- pixel.red,
- pixel.green,
- pixel.blue));
+ color_scale * pixel.red,
+ color_scale * pixel.green,
+ color_scale * pixel.blue));
}
}
DestroyPixelIterator (iterator);
@@ -8469,6 +8478,9 @@ imagemagick_load (struct frame *f, struct image *img)
image_error ("Cannot find image file `%s'", file_name, Qnil);
return 0;
}
+#ifdef WINDOWSNT
+ file = ansi_encode_filename (file);
+#endif
success_p = imagemagick_load_image (f, img, 0, 0, SSDATA (file));
}
/* Else its not a file, its a lisp object. Load the image from a
@@ -8507,7 +8519,6 @@ and `imagemagick-types-inhibit'. */)
ExceptionInfo ex;
char **imtypes;
size_t i;
- Lisp_Object Qimagemagicktype;
GetExceptionInfo(&ex);
imtypes = GetMagickList ("*", &numf, &ex);
@@ -8515,9 +8526,12 @@ and `imagemagick-types-inhibit'. */)
for (i = 0; i < numf; i++)
{
- Qimagemagicktype = intern (imtypes[i]);
- typelist = Fcons (Qimagemagicktype, typelist);
+ Lisp_Object imagemagicktype = intern (imtypes[i]);
+ typelist = Fcons (imagemagicktype, typelist);
+ imtypes[i] = MagickRelinquishMemory (imtypes[i]);
}
+
+ MagickRelinquishMemory (imtypes);
return Fnreverse (typelist);
}
@@ -8625,7 +8639,6 @@ DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions, (RsvgHandle *, RsvgDimensionDat
DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **));
DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
-DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback, (RsvgHandle *, RsvgSizeFunc, gpointer, GDestroyNotify));
DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
@@ -8647,13 +8660,18 @@ Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
static bool
init_svg_functions (void)
{
- HMODULE library, gdklib, glib, gobject;
+ HMODULE library, gdklib = NULL, glib = NULL, gobject = NULL;
if (!(glib = w32_delayed_load (Qglib))
|| !(gobject = w32_delayed_load (Qgobject))
|| !(gdklib = w32_delayed_load (Qgdk_pixbuf))
|| !(library = w32_delayed_load (Qsvg)))
- return 0;
+ {
+ if (gdklib) FreeLibrary (gdklib);
+ if (gobject) FreeLibrary (gobject);
+ if (glib) FreeLibrary (glib);
+ return 0;
+ }
LOAD_IMGLIB_FN (library, rsvg_handle_new);
LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions);
@@ -8841,14 +8859,7 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
specified_bg = image_spec_value (img->spec, QCbackground, NULL);
if (!STRINGP (specified_bg)
|| !x_defined_color (f, SSDATA (specified_bg), &background, 0))
- {
-#ifndef HAVE_NS
- background.pixel = FRAME_BACKGROUND_PIXEL (f);
- x_query_color (f, &background);
-#else
- ns_query_color (FRAME_BACKGROUND_COLOR (f), &background, 1);
-#endif
- }
+ x_query_frame_background_color (f, &background);
/* SVG pixmaps specify transparency in the last byte, so right
shift 8 bits to get rid of it, since emacs doesn't support
@@ -9336,6 +9347,8 @@ reset_image_types (void)
void
syms_of_image (void)
{
+#include "image.x"
+
/* Initialize this only once; it will be reset before dumping. */
image_types = NULL;
@@ -9410,6 +9423,14 @@ non-numeric, there is no explicit limit on the size of images. */);
+ GIFLIB_RELEASE)
#else
make_number (-1)
+#endif
+ );
+ DEFSYM (Qlibjpeg_version, "libjpeg-version");
+ Fset (Qlibjpeg_version,
+#if HAVE_JPEG
+ make_number (JPEG_LIB_VERSION)
+#else
+ make_number (-1)
#endif
);
#endif
@@ -9461,21 +9482,6 @@ non-numeric, there is no explicit limit on the size of images. */);
#endif /* HAVE_NTGUI */
#endif /* HAVE_RSVG */
- defsubr (&Sinit_image_library);
-#ifdef HAVE_IMAGEMAGICK
- defsubr (&Simagemagick_types);
-#endif
- defsubr (&Sclear_image_cache);
- defsubr (&Simage_flush);
- defsubr (&Simage_size);
- defsubr (&Simage_mask_p);
- defsubr (&Simage_metadata);
-
-#ifdef GLYPH_DEBUG
- defsubr (&Simagep);
- defsubr (&Slookup_image);
-#endif
-
DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images,
doc: /* Non-nil means always draw a cross over disabled images.
Disabled images are those having a `:conversion disabled' property.
@@ -9484,7 +9490,7 @@ A cross is always drawn on black & white displays. */);
DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
doc: /* List of directories to search for window system bitmap files. */);
- Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS);
+ Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS, 0);
DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
doc: /* Maximum time after which images are removed from the cache.