X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8c2f38aaab7a7a2f0605416fc2ee38701e41ab61..e9be0a138c07b93576c07c7fe7c94defee9adfc6:/src/image.c diff --git a/src/image.c b/src/image.c index 2db44d07c8..7d6445527a 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. @@ -30,13 +30,8 @@ along with GNU Emacs. If not, see . */ #endif #include - #include -/* This makes the fields of a Display accessible, in Xlib header files. */ - -#define XLIB_ILLEGAL_ACCESS - #include "lisp.h" #include "frame.h" #include "window.h" @@ -92,10 +87,12 @@ typedef struct w32_bitmap_record Bitmap_Record; #define x_defined_color w32_defined_color #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits) -/* Version of libpng that we were compiled with, or -1 if no PNG - support was compiled in. This is tested by w32-win.el to correctly - set up the alist used to search for PNG libraries. */ -Lisp_Object Qlibpng_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 @@ -145,7 +142,7 @@ static Lisp_Object QCmax_width, QCmax_height; #ifdef HAVE_NS /* Use with images created by ns_image_for_XPM. */ -unsigned long +static unsigned long XGetPixel (XImagePtr ximage, int x, int y) { return ns_get_pixel (ximage, x, y); @@ -153,7 +150,7 @@ XGetPixel (XImagePtr ximage, int x, int y) /* Use with images created by ns_image_for_XPM; alpha set to 1; pixel is assumed to be in RGB form. */ -void +static void XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) { ns_put_pixel (ximage, x, y, pixel); @@ -163,16 +160,16 @@ XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) /* Functions to access the contents of a bitmap, given an id. */ -int +static int x_bitmap_height (struct frame *f, ptrdiff_t id) { - return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height; + return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].height; } -int +static int x_bitmap_width (struct frame *f, ptrdiff_t id) { - return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width; + return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width; } #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) @@ -180,7 +177,7 @@ ptrdiff_t x_bitmap_pixmap (struct frame *f, ptrdiff_t id) { /* HAVE_NTGUI needs the explicit cast here. */ - return (ptrdiff_t) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; + return (ptrdiff_t) FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; } #endif @@ -188,7 +185,7 @@ x_bitmap_pixmap (struct frame *f, ptrdiff_t id) int x_bitmap_mask (struct frame *f, ptrdiff_t id) { - return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask; + return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].mask; } #endif @@ -197,7 +194,7 @@ x_bitmap_mask (struct frame *f, ptrdiff_t id) static ptrdiff_t x_allocate_bitmap_record (struct frame *f) { - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); ptrdiff_t i; if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size) @@ -218,7 +215,7 @@ x_allocate_bitmap_record (struct frame *f) void x_reference_bitmap (struct frame *f, ptrdiff_t id) { - ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; + ++FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; } /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */ @@ -226,7 +223,7 @@ x_reference_bitmap (struct frame *f, ptrdiff_t id) ptrdiff_t x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsigned int height) { - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); ptrdiff_t id; #ifdef HAVE_X_WINDOWS @@ -240,8 +237,8 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi #ifdef HAVE_NTGUI Pixmap bitmap; bitmap = CreateBitmap (width, height, - FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_planes, - FRAME_X_DISPLAY_INFO (XFRAME (frame))->n_cbits, + FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, + FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, bits); if (! bitmap) return -1; @@ -267,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 */ @@ -285,7 +282,7 @@ x_create_bitmap_from_data (struct frame *f, char *bits, unsigned int width, unsi ptrdiff_t x_create_bitmap_from_file (struct frame *f, Lisp_Object file) { - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); #ifdef HAVE_NTGUI return -1; /* W32_TODO : bitmap support */ @@ -330,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); @@ -342,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; @@ -384,7 +383,7 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm) void x_destroy_bitmap (struct frame *f, ptrdiff_t id) { - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); if (id > 0) { @@ -459,7 +458,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) unsigned long x, y, xp, xm, yp, ym; GC gc; - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); if (!(id > 0)) return; @@ -518,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); @@ -563,7 +562,6 @@ static void x_emboss (struct frame *, struct image *); static void x_build_heuristic_mask (struct frame *, struct image *, Lisp_Object); #ifdef WINDOWSNT -extern Lisp_Object Vlibrary_cache; #define CACHE_IMAGE_TYPE(type, status) \ do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) #else @@ -1042,7 +1040,7 @@ void prepare_image_for_display (struct frame *f, struct image *img) { /* We're about to display IMG, so set its timestamp to `now'. */ - img->timestamp = current_emacs_time (); + img->timestamp = current_timespec (); /* If IMG doesn't have a pixmap yet, load it now, using the image type dependent loader function. */ @@ -1481,7 +1479,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter) else if (INTEGERP (Vimage_cache_eviction_delay)) { /* Free cache based on timestamp. */ - EMACS_TIME old, t; + struct timespec old, t; double delay; ptrdiff_t nimages = 0; @@ -1496,13 +1494,13 @@ clear_image_cache (struct frame *f, Lisp_Object filter) delay = 1600 * delay / nimages / nimages; delay = max (delay, 1); - t = current_emacs_time (); - old = sub_emacs_time (t, EMACS_TIME_FROM_DOUBLE (delay)); + t = current_timespec (); + old = timespec_sub (t, dtotimespec (delay)); for (i = 0; i < c->used; ++i) { struct image *img = c->images[i]; - if (img && EMACS_TIME_LT (img->timestamp, old)) + if (img && timespec_cmp (img->timestamp, old) < 0) { free_image (f, img); ++nfreed; @@ -1525,7 +1523,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 (); @@ -1765,7 +1763,7 @@ lookup_image (struct frame *f, Lisp_Object spec) } /* We're using IMG, so set its timestamp to `now'. */ - img->timestamp = current_emacs_time (); + img->timestamp = current_timespec (); /* Value is the image id. */ return img->id; @@ -2246,7 +2244,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; @@ -2461,7 +2459,7 @@ xbm_image_p (Lisp_Object object) } else if (BOOL_VECTOR_P (elt)) { - if (XBOOL_VECTOR (elt)->size < width) + if (bool_vector_size (elt) < width) return 0; } else @@ -2476,7 +2474,7 @@ xbm_image_p (Lisp_Object object) } else if (BOOL_VECTOR_P (data)) { - if (XBOOL_VECTOR (data)->size / height < width) + if (bool_vector_size (data) / height < width) return 0; } else @@ -2713,10 +2711,13 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e LA1 = xbm_scan (&s, end, buffer, &value) #define expect(TOKEN) \ - if (LA1 != (TOKEN)) \ - goto failure; \ - else \ - match () + do \ + { \ + if (LA1 != (TOKEN)) \ + goto failure; \ + match (); \ + } \ + while (0) #define expect_ident(IDENT) \ if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ @@ -3027,13 +3028,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 { @@ -3424,7 +3425,7 @@ xpm_image_p (Lisp_Object object) ptrdiff_t x_create_bitmap_from_xpm_data (struct frame *f, const char **bits) { - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); ptrdiff_t id; int rc; XpmAttributes attrs; @@ -3447,7 +3448,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; @@ -3591,6 +3592,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), @@ -3969,17 +3976,20 @@ 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() \ LA1 = xpm_scan (&s, end, &beg, &len) #define expect(TOKEN) \ - if (LA1 != (TOKEN)) \ - goto failure; \ - else \ - match () + do \ + { \ + if (LA1 != (TOKEN)) \ + goto failure; \ + match (); \ + } \ + while (0) #define expect_ident(IDENT) \ if (LA1 == XPM_TK_IDENT \ @@ -4138,7 +4148,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); @@ -4325,7 +4335,7 @@ lookup_rgb_color (struct frame *f, int r, int g, int b) two orders of magnitude. Freeing colors on TrueColor visuals is a nop, and pixel colors specify RGB values directly. See also the Xlib spec, chapter 3.1. */ - dpyinfo = FRAME_X_DISPLAY_INFO (f); + dpyinfo = FRAME_DISPLAY_INFO (f); if (dpyinfo->red_bits > 0) { unsigned long pr, pg, pb; @@ -4820,7 +4830,7 @@ x_edge_detection (struct frame *f, struct image *img, Lisp_Object matrix, static void x_disable_image (struct frame *f, struct image *img) { - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); #ifdef HAVE_NTGUI int n_planes = dpyinfo->n_planes * dpyinfo->n_cbits; #else @@ -4932,7 +4942,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) int row_width; #endif /* HAVE_NTGUI */ int x, y; - bool rc, use_img_background; + bool use_img_background; unsigned long bg = 0; if (img->mask) @@ -4941,9 +4951,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) #ifndef HAVE_NTGUI #ifndef HAVE_NS /* Create an image and pixmap serving as mask. */ - rc = image_create_x_image_and_pixmap (f, img, img->width, img->height, 1, - &mask_img, 1); - if (!rc) + if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1, + &mask_img, 1)) return; #endif /* !HAVE_NS */ #else @@ -5105,6 +5114,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 +5144,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; @@ -5518,7 +5536,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 */ @@ -6958,6 +6976,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"); @@ -7204,6 +7225,7 @@ gif_image_p (Lisp_Object object) #ifdef HAVE_GIF #if defined (HAVE_NTGUI) + /* winuser.h might define DrawText to DrawTextA or DrawTextW. Undefine before redefining to avoid a preprocessor warning. */ #ifdef DrawText @@ -7214,20 +7236,38 @@ gif_image_p (Lisp_Object object) #include #undef DrawText +/* Giflib before 5.0 didn't define these macros (used only if HAVE_NTGUI). */ +#ifndef GIFLIB_MINOR +#define GIFLIB_MINOR 0 +#endif +#ifndef GIFLIB_RELEASE +#define GIFLIB_RELEASE 0 +#endif + #else /* HAVE_NTGUI */ #include #endif /* HAVE_NTGUI */ +/* Giflib before 5.0 didn't define these macros. */ +#ifndef GIFLIB_MAJOR +#define GIFLIB_MAJOR 4 +#endif #ifdef WINDOWSNT /* GIF library details. */ DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *)); DEF_IMGLIB_FN (int, DGifSlurp, (GifFileType *)); +#if GIFLIB_MAJOR < 5 DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc)); DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *)); +#else +DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc, int *)); +DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *, int *)); +DEF_IMGLIB_FN (char *, GifErrorString, (int)); +#endif static bool init_gif_functions (void) @@ -7241,6 +7281,9 @@ init_gif_functions (void) LOAD_IMGLIB_FN (library, DGifSlurp); LOAD_IMGLIB_FN (library, DGifOpen); LOAD_IMGLIB_FN (library, DGifOpenFileName); +#if GIFLIB_MAJOR >= 5 + LOAD_IMGLIB_FN (library, GifErrorString); +#endif return 1; } @@ -7250,6 +7293,9 @@ init_gif_functions (void) #define fn_DGifSlurp DGifSlurp #define fn_DGifOpen DGifOpen #define fn_DGifOpenFileName DGifOpenFileName +#if 5 <= GIFLIB_MAJOR +# define fn_GifErrorString GifErrorString +#endif #endif /* WINDOWSNT */ @@ -7306,6 +7352,9 @@ 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)) { @@ -7315,14 +7364,27 @@ 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 gif = fn_DGifOpenFileName (SSDATA (file)); if (gif == NULL) { image_error ("Cannot open `%s'", file, Qnil); return 0; } +#else + gif = fn_DGifOpenFileName (SSDATA (file), &gif_err); + if (gif == NULL) + { + image_error ("Cannot open `%s': %s", + file, build_string (fn_GifErrorString (gif_err))); + return 0; + } +#endif } else { @@ -7338,12 +7400,22 @@ gif_load (struct frame *f, struct image *img) memsrc.len = SBYTES (specified_data); memsrc.index = 0; +#if GIFLIB_MAJOR < 5 gif = fn_DGifOpen (&memsrc, gif_read_from_memory); if (!gif) { image_error ("Cannot open memory source `%s'", img->spec, Qnil); return 0; } +#else + gif = fn_DGifOpen (&memsrc, gif_read_from_memory, &gif_err); + if (!gif) + { + image_error ("Cannot open memory source `%s': %s", + img->spec, build_string (fn_GifErrorString (gif_err))); + return 0; + } +#endif } /* Before reading entire contents, check the declared image size. */ @@ -7523,10 +7595,7 @@ gif_load (struct frame *f, struct image *img) y++, row += interlace_increment[pass]) { while (subimg_height <= row) - { - lint_assume (pass < 3); - row = interlace_start[++pass]; - } + row = interlace_start[++pass]; for (x = 0; x < subimg_width; x++) { @@ -7880,7 +7949,7 @@ struct animation_cache { MagickWand *wand; int index; - EMACS_TIME update_time; + struct timespec update_time; struct animation_cache *next; char signature[FLEXIBLE_ARRAY_MEMBER]; }; @@ -7905,13 +7974,13 @@ static void imagemagick_prune_animation_cache (void) { struct animation_cache **pcache = &animation_cache; - EMACS_TIME old = sub_emacs_time (current_emacs_time (), - make_emacs_time (60, 0)); + struct timespec old = timespec_sub (current_timespec (), + make_timespec (60, 0)); while (*pcache) { struct animation_cache *cache = *pcache; - if (EMACS_TIME_LE (old, cache->update_time)) + if (timespec_cmp (old, cache->update_time) <= 0) pcache = &cache->next; else { @@ -7946,7 +8015,7 @@ imagemagick_get_animation_cache (MagickWand *wand) } DestroyString (signature); - cache->update_time = current_emacs_time (); + cache->update_time = current_timespec (); return cache; } @@ -8038,7 +8107,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 @@ -8424,6 +8493,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 @@ -8591,7 +8663,9 @@ DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *)); DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *)); DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *)); +#if ! GLIB_CHECK_VERSION (2, 36, 0) DEF_IMGLIB_FN (void, g_type_init, (void)); +#endif DEF_IMGLIB_FN (void, g_object_unref, (gpointer)); DEF_IMGLIB_FN (void, g_error_free, (GError *)); @@ -8623,7 +8697,9 @@ init_svg_functions (void) LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_has_alpha); LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_bits_per_sample); +#if ! GLIB_CHECK_VERSION (2, 36, 0) LOAD_IMGLIB_FN (gobject, g_type_init); +#endif LOAD_IMGLIB_FN (gobject, g_object_unref); LOAD_IMGLIB_FN (glib, g_error_free); @@ -8648,7 +8724,9 @@ init_svg_functions (void) #define fn_gdk_pixbuf_get_has_alpha gdk_pixbuf_get_has_alpha #define fn_gdk_pixbuf_get_bits_per_sample gdk_pixbuf_get_bits_per_sample +#if ! GLIB_CHECK_VERSION (2, 36, 0) #define fn_g_type_init g_type_init +#endif #define fn_g_object_unref g_object_unref #define fn_g_error_free g_error_free #endif /* !WINDOWSNT */ @@ -8733,9 +8811,12 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * int x; int y; - /* g_type_init is a glib function that must be called prior to using - gnome type library functions. */ +#if ! GLIB_CHECK_VERSION (2, 36, 0) + /* g_type_init is a glib function that must be called prior to + using gnome type library functions (obsolete since 2.36.0). */ fn_g_type_init (); +#endif + /* Make a handle to a new rsvg object. */ rsvg_handle = fn_rsvg_handle_new (); @@ -9346,6 +9427,24 @@ non-numeric, there is no explicit limit on the size of images. */); make_number (PNG_LIBPNG_VER) #else make_number (-1) +#endif + ); + DEFSYM (Qlibgif_version, "libgif-version"); + Fset (Qlibgif_version, +#ifdef HAVE_GIF + make_number (GIFLIB_MAJOR * 10000 + + GIFLIB_MINOR * 100 + + 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 @@ -9420,7 +9519,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.