X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/6a0dd1d7e075ccb23ed08afafe9b251eacd931bd..bde3c6c0f79ab814e12ea0f04b06625f91f5cd52:/src/image.c diff --git a/src/image.c b/src/image.c index 8a318c2f6e..538ae2b777 100644 --- a/src/image.c +++ b/src/image.c @@ -19,8 +19,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include -#include #include #ifdef HAVE_PNG @@ -33,6 +31,8 @@ along with GNU Emacs. If not, see . */ #include +#include + /* This makes the fields of a Display accessible, in Xlib header files. */ #define XLIB_ILLEGAL_ACCESS @@ -49,11 +49,19 @@ along with GNU Emacs. If not, see . */ #include "termhooks.h" #include "font.h" -#ifdef HAVE_X_WINDOWS -#include "xterm.h" -#include +#ifdef HAVE_SYS_STAT_H #include +#endif /* HAVE_SYS_STAT_H */ + +#ifdef HAVE_SYS_TYPES_H +#include +#endif /* HAVE_SYS_TYPES_H */ +#ifdef HAVE_WINDOW_SYSTEM +#include TERM_HEADER +#endif /* HAVE_WINDOW_SYSTEM */ + +#ifdef HAVE_X_WINDOWS #define COLOR_TABLE_SUPPORT 1 typedef struct x_bitmap_record Bitmap_Record; @@ -66,10 +74,12 @@ typedef struct x_bitmap_record Bitmap_Record; #define PIX_MASK_DRAW 1 #endif /* HAVE_X_WINDOWS */ - #ifdef HAVE_NTGUI -#include "w32.h" -#include "w32term.h" + +/* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */ +#ifdef WINDOWSNT +# include "w32.h" +#endif /* W32_TODO : Color tables on W32. */ #undef COLOR_TABLE_SUPPORT @@ -83,15 +93,9 @@ typedef struct w32_bitmap_record Bitmap_Record; #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 -#define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual #define x_defined_color w32_defined_color #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits) -/* Functions from w32term.c that depend on XColor (so can't go in w32term.h - without modifying lots of files). */ -extern void x_query_colors (struct frame *f, XColor *colors, int ncolors); -extern void x_query_color (struct frame *f, XColor *color); - /* 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. */ @@ -99,10 +103,6 @@ Lisp_Object Qlibpng_version; #endif /* HAVE_NTGUI */ #ifdef HAVE_NS -#include "nsterm.h" -#include -#include - #undef COLOR_TABLE_SUPPORT typedef struct ns_bitmap_record Bitmap_Record; @@ -116,10 +116,8 @@ typedef struct ns_bitmap_record Bitmap_Record; #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 -#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO (f)->visual #define x_defined_color(f, name, color_def, alloc) \ ns_defined_color (f, name, color_def, alloc, 0) -#define FRAME_X_SCREEN(f) 0 #define DefaultDepthOfScreen(screen) x_display_list->n_planes #endif /* HAVE_NS */ @@ -193,11 +191,11 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id) } #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) -int +ptrdiff_t x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) { /* HAVE_NTGUI needs the explicit cast here. */ - return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; + return (ptrdiff_t) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; } #endif @@ -414,9 +412,9 @@ x_destroy_bitmap (FRAME_PTR f, ptrdiff_t id) if (--bm->refcount == 0) { - BLOCK_INPUT; + block_input (); free_bitmap_record (dpyinfo, bm); - UNBLOCK_INPUT; + unblock_input (); } } } @@ -436,6 +434,9 @@ x_destroy_all_bitmaps (Display_Info *dpyinfo) dpyinfo->bitmaps_last = 0; } +static bool x_create_x_image_and_pixmap (struct frame *, int, int, int, + XImagePtr *, Pixmap *); +static void x_destroy_x_image (XImagePtr ximg); #ifdef HAVE_X_WINDOWS @@ -447,23 +448,17 @@ static unsigned long four_corners_best (XImagePtr ximg, unsigned long width, unsigned long height); -static int x_create_x_image_and_pixmap (struct frame *f, int width, int height, - int depth, XImagePtr *ximg, - Pixmap *pixmap); - -static void x_destroy_x_image (XImagePtr ximg); - /* Create a mask of a bitmap. Note is this not a perfect mask. It's nicer with some borders in this context */ -int +void x_create_bitmap_mask (struct frame *f, ptrdiff_t id) { Pixmap pixmap, mask; XImagePtr ximg, mask_img; unsigned long width, height; - int result; + bool result; unsigned long bg; unsigned long x, y, xp, xm, yp, ym; GC gc; @@ -471,29 +466,29 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); if (!(id > 0)) - return -1; + return; pixmap = x_bitmap_pixmap (f, id); width = x_bitmap_width (f, id); height = x_bitmap_height (f, id); - BLOCK_INPUT; + block_input (); ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height, ~0, ZPixmap); if (!ximg) { - UNBLOCK_INPUT; - return -1; + unblock_input (); + return; } result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask); - UNBLOCK_INPUT; + unblock_input (); if (!result) { XDestroyImage (ximg); - return -1; + return; } bg = four_corners_best (ximg, NULL, width, height); @@ -521,7 +516,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) } } - eassert (interrupt_input_blocked); + eassert (input_blocked_p ()); gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL); XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0, width, height); @@ -532,8 +527,6 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) XDestroyImage (ximg); x_destroy_x_image (mask_img); - - return 0; } #endif /* HAVE_X_WINDOWS */ @@ -566,16 +559,15 @@ static Lisp_Object QCcrop, QCrotation; static Lisp_Object Qcount, Qextension_data, Qdelay; static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic; -/* Function prototypes. */ +/* Forward function prototypes. */ -static Lisp_Object define_image_type (struct image_type *type, int loaded); -static struct image_type *lookup_image_type (Lisp_Object symbol); -static void image_error (const char *format, Lisp_Object, Lisp_Object); +static struct image_type *lookup_image_type (Lisp_Object); static void x_laplace (struct frame *, struct image *); static void x_emboss (struct frame *, struct image *); -static int x_build_heuristic_mask (struct frame *, struct image *, - Lisp_Object); -#ifdef HAVE_NTGUI +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 @@ -588,60 +580,61 @@ static int x_build_heuristic_mask (struct frame *, struct image *, /* Define a new image type from TYPE. This adds a copy of TYPE to image_types and caches the loading status of TYPE. */ -static Lisp_Object -define_image_type (struct image_type *type, int loaded) +static struct image_type * +define_image_type (struct image_type *type) { - Lisp_Object success; + struct image_type *p = NULL; + Lisp_Object target_type = *type->type; + bool type_valid = 1; - if (!loaded) - success = Qnil; - else + block_input (); + + for (p = image_types; p; p = p->next) + if (EQ (*p->type, target_type)) + goto done; + + if (type->init) + { +#if defined HAVE_NTGUI && defined WINDOWSNT + /* If we failed to load the library before, don't try again. */ + Lisp_Object tested = Fassq (target_type, Vlibrary_cache); + if (CONSP (tested) && NILP (XCDR (tested))) + type_valid = 0; + else +#endif + { + type_valid = type->init (); + CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil); + } + } + + if (type_valid) { /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. The initialized data segment is read-only. */ - struct image_type *p = xmalloc (sizeof *p); - memcpy (p, type, sizeof *p); + p = xmalloc (sizeof *p); + *p = *type; p->next = image_types; image_types = p; - success = Qt; } - CACHE_IMAGE_TYPE (*type->type, success); - return success; -} - - -/* Look up image type SYMBOL, and return a pointer to its image_type - structure. Value is null if SYMBOL is not a known image type. */ - -static inline struct image_type * -lookup_image_type (Lisp_Object symbol) -{ - struct image_type *type; - - /* We must initialize the image-type if it hasn't been already. */ - if (NILP (Finit_image_library (symbol, Vdynamic_library_alist))) - return 0; /* unimplemented */ - - for (type = image_types; type; type = type->next) - if (EQ (symbol, *type->type)) - break; - - return type; + done: + unblock_input (); + return p; } -/* Value is non-zero if OBJECT is a valid Lisp image specification. A +/* Value is true if OBJECT is a valid Lisp image specification. A valid image specification is a list whose car is the symbol `image', and whose rest is a property list. The property list must contain a value for key `:type'. That value must be the name of a supported image type. The rest of the property list depends on the image type. */ -int +bool valid_image_p (Lisp_Object object) { - int valid_p = 0; + bool valid_p = 0; if (IMAGEP (object)) { @@ -711,8 +704,8 @@ struct image_keyword /* The type of value allowed. */ enum image_value_type type; - /* Non-zero means key must be present. */ - int mandatory_p; + /* True means key must be present. */ + bool mandatory_p; /* Used to recognize duplicate keywords in a property list. */ int count; @@ -722,18 +715,13 @@ struct image_keyword }; -static int parse_image_spec (Lisp_Object, struct image_keyword *, - int, Lisp_Object); -static Lisp_Object image_spec_value (Lisp_Object, Lisp_Object, int *); - - /* Parse image spec SPEC according to KEYWORDS. A valid image spec has the format (image KEYWORD VALUE ...). One of the keyword/ value pairs must be `:type TYPE'. KEYWORDS is a vector of image_keywords structures of size NKEYWORDS describing other - allowed keyword/value pairs. Value is non-zero if SPEC is valid. */ + allowed keyword/value pairs. Value is true if SPEC is valid. */ -static int +static bool parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, int nkeywords, Lisp_Object type) { @@ -847,7 +835,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, break; default: - abort (); + emacs_abort (); break; } @@ -865,11 +853,11 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, /* Return the value of KEY in image specification SPEC. Value is nil - if KEY is not present in SPEC. if FOUND is not null, set *FOUND - to 1 if KEY was found in SPEC, set it to 0 otherwise. */ + if KEY is not present in SPEC. Set *FOUND depending on whether KEY + was found in SPEC. */ static Lisp_Object -image_spec_value (Lisp_Object spec, Lisp_Object key, int *found) +image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found) { Lisp_Object tail; @@ -973,8 +961,6 @@ or omitted means use the selected frame. */) Image type independent image structures ***********************************************************************/ -static void free_image (struct frame *f, struct image *img); - #define MAX_IMAGE_SIZE 10.0 /* Allocate and return a new image structure for image specification SPEC. SPEC has a hash value of HASH. */ @@ -1024,10 +1010,9 @@ free_image (struct frame *f, struct image *img) } } -/* Return 1 if the given widths and heights are valid for display; - otherwise, return 0. */ +/* Return true if the given widths and heights are valid for display. */ -static int +static bool check_image_size (struct frame *f, int width, int height) { int w, h; @@ -1066,7 +1051,7 @@ prepare_image_for_display (struct frame *f, struct image *img) /* If IMG doesn't have a pixmap yet, load it now, using the image type dependent loader function. */ if (img->pixmap == NO_PIXMAP && !img->load_failed_p) - img->load_failed_p = img->type->load (f, img) == 0; + img->load_failed_p = ! img->type->load (f, img); } @@ -1199,7 +1184,7 @@ image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg) if (! img->background_valid) /* IMG doesn't have a background yet, try to guess a reasonable value. */ { - int free_ximg = !ximg; + bool free_ximg = !ximg; #ifdef HAVE_NTGUI HGDIOBJ prev; #endif /* HAVE_NTGUI */ @@ -1240,7 +1225,7 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D { if (img->mask) { - int free_mask = !mask; + bool free_mask = !mask; #ifdef HAVE_NTGUI HGDIOBJ prev; #endif /* HAVE_NTGUI */ @@ -1278,23 +1263,13 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D Helper functions for X image types ***********************************************************************/ -static void x_clear_image_1 (struct frame *, struct image *, int, - int, int); -static void x_clear_image (struct frame *f, struct image *img); -static unsigned long x_alloc_image_color (struct frame *f, - struct image *img, - Lisp_Object color_name, - unsigned long dflt); - - -/* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means - free the pixmap if any. MASK_P non-zero means clear the mask - pixmap if any. COLORS_P non-zero means free colors allocated for - the image, if any. */ +/* Clear X resources of image IMG on frame F. PIXMAP_P means free the + pixmap if any. MASK_P means clear the mask pixmap if any. + COLORS_P means free colors allocated for the image, if any. */ static void -x_clear_image_1 (struct frame *f, struct image *img, int pixmap_p, int mask_p, - int colors_p) +x_clear_image_1 (struct frame *f, struct image *img, bool pixmap_p, + bool mask_p, bool colors_p) { if (pixmap_p && img->pixmap) { @@ -1329,9 +1304,9 @@ x_clear_image_1 (struct frame *f, struct image *img, int pixmap_p, int mask_p, static void x_clear_image (struct frame *f, struct image *img) { - BLOCK_INPUT; + block_input (); x_clear_image_1 (f, img, 1, 1, 1); - UNBLOCK_INPUT; + unblock_input (); } @@ -1374,7 +1349,6 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name, ***********************************************************************/ static void cache_image (struct frame *f, struct image *img); -static void postprocess_image (struct frame *, struct image *); /* Return a new, initialized image cache that is allocated from the heap. Call free_image_cache to free an image cache. */ @@ -1486,7 +1460,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter) /* Block input so that we won't be interrupted by a SIGIO while being in an inconsistent state. */ - BLOCK_INPUT; + block_input (); if (!NILP (filter)) { @@ -1552,7 +1526,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter) ++windows_or_buffers_changed; } - UNBLOCK_INPUT; + unblock_input (); } } @@ -1647,7 +1621,7 @@ postprocess_image (struct frame *f, struct image *img) x_build_heuristic_mask (f, img, mask); else { - int found_p; + bool found_p; mask = image_spec_value (spec, QCmask, &found_p); @@ -1717,10 +1691,10 @@ lookup_image (struct frame *f, Lisp_Object spec) /* If not found, create a new image and cache it. */ if (img == NULL) { - BLOCK_INPUT; + block_input (); img = make_image (spec, hash); cache_image (f, img); - img->load_failed_p = img->type->load (f, img) == 0; + img->load_failed_p = ! img->type->load (f, img); img->frame_foreground = FRAME_FOREGROUND_PIXEL (f); img->frame_background = FRAME_BACKGROUND_PIXEL (f); @@ -1788,7 +1762,7 @@ lookup_image (struct frame *f, Lisp_Object spec) postprocess_image (f, img); } - UNBLOCK_INPUT; + unblock_input (); } /* We're using IMG, so set its timestamp to `now'. */ @@ -1866,7 +1840,7 @@ mark_image_cache (struct image_cache *c) X / NS / W32 support code ***********************************************************************/ -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* Macro for defining functions that will be loaded from image DLLs. */ #define DEF_IMGLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args @@ -1877,18 +1851,13 @@ mark_image_cache (struct image_cache *c) if (!fn_##func) return 0; \ } -#endif /* HAVE_NTGUI */ - -static int x_create_x_image_and_pixmap (struct frame *, int, int, int, - XImagePtr *, Pixmap *); -static void x_destroy_x_image (XImagePtr); -static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int); +#endif /* WINDOWSNT */ -/* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break the +/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the windowing system. WIDTH and HEIGHT must both be positive. If XIMG is null, assume it is a bitmap. */ -static int +static bool x_check_image_size (XImagePtr ximg, int width, int height) { #ifdef HAVE_X_WINDOWS @@ -1927,12 +1896,12 @@ x_check_image_size (XImagePtr ximg, int width, int height) frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created. Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated via xmalloc. Print error messages via image_error if an error - occurs. Value is non-zero if successful. + occurs. Value is true if successful. On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH should indicate the bit depth of the image. */ -static int +static bool x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, XImagePtr *ximg, Pixmap *pixmap) { @@ -1941,7 +1910,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, Window window = FRAME_X_WINDOW (f); Screen *screen = FRAME_X_SCREEN (f); - eassert (interrupt_input_blocked); + eassert (input_blocked_p ()); if (depth <= 0) depth = DefaultDepthOfScreen (screen); @@ -2079,7 +2048,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, static void x_destroy_x_image (XImagePtr ximg) { - eassert (interrupt_input_blocked); + eassert (input_blocked_p ()); if (ximg) { #ifdef HAVE_X_WINDOWS @@ -2108,7 +2077,7 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he #ifdef HAVE_X_WINDOWS GC gc; - eassert (interrupt_input_blocked); + eassert (input_blocked_p ()); gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL); XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height); XFreeGC (FRAME_X_DISPLAY (f), gc); @@ -2171,12 +2140,11 @@ x_find_image_file (Lisp_Object file) static unsigned char * slurp_file (char *file, ptrdiff_t *size) { - FILE *fp = NULL; + FILE *fp = fopen (file, "rb"); unsigned char *buf = NULL; struct stat st; - if (stat (file, &st) == 0 - && (fp = fopen (file, "rb")) != NULL + if (fp && fstat (fileno (fp), &st) == 0 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) && (buf = xmalloc (st.st_size), fread (buf, 1, st.st_size, fp) == st.st_size)) @@ -2204,15 +2172,9 @@ slurp_file (char *file, ptrdiff_t *size) XBM images ***********************************************************************/ -static int xbm_scan (unsigned char **, unsigned char *, char *, int *); -static int xbm_load (struct frame *f, struct image *img); -static int xbm_load_image (struct frame *f, struct image *img, - unsigned char *, unsigned char *); -static int xbm_image_p (Lisp_Object object); -static int xbm_read_bitmap_data (struct frame *f, - unsigned char *, unsigned char *, - int *, int *, char **, int); -static int xbm_file_p (Lisp_Object); +static bool xbm_load (struct frame *f, struct image *img); +static bool xbm_image_p (Lisp_Object object); +static bool xbm_file_p (Lisp_Object); /* Indices of image specification fields in xbm_format, below. */ @@ -2263,6 +2225,7 @@ static struct image_type xbm_type = xbm_image_p, xbm_load, x_clear_image, + NULL, NULL }; @@ -2275,10 +2238,10 @@ enum xbm_token }; -/* Return non-zero if OBJECT is a valid XBM-type image specification. +/* Return true if OBJECT is a valid XBM-type image specification. A valid specification is a list starting with the symbol `image' The rest of the list is a property list which must contain an - entry `:type xbm.. + entry `:type xbm'. If the specification specifies a file to load, it must contain an entry `:file FILENAME' where FILENAME is a string. @@ -2304,7 +2267,7 @@ enum xbm_token foreground and background of the frame on which the image is displayed is used. */ -static int +static bool xbm_image_p (Lisp_Object object) { struct image_keyword kw[XBM_LAST]; @@ -2405,12 +2368,12 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) loop: /* Skip white space. */ - while (*s < end && (c = *(*s)++, isspace (c))) + while (*s < end && (c = *(*s)++, c_isspace (c))) ; if (*s >= end) c = 0; - else if (isdigit (c)) + else if (c_isdigit (c)) { int value = 0, digit; @@ -2422,7 +2385,7 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) while (*s < end) { c = *(*s)++; - if (isdigit (c)) + if (c_isdigit (c)) digit = c - '0'; else if (c >= 'a' && c <= 'f') digit = c - 'a' + 10; @@ -2433,11 +2396,11 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) value = 16 * value + digit; } } - else if (isdigit (c)) + else if (c_isdigit (c)) { value = c - '0'; while (*s < end - && (c = *(*s)++, isdigit (c))) + && (c = *(*s)++, c_isdigit (c))) value = 8 * value + c - '0'; } } @@ -2445,7 +2408,7 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) { value = c - '0'; while (*s < end - && (c = *(*s)++, isdigit (c))) + && (c = *(*s)++, c_isdigit (c))) value = 10 * value + c - '0'; } @@ -2454,11 +2417,11 @@ xbm_scan (unsigned char **s, unsigned char *end, char *sval, int *ival) *ival = value; c = XBM_TK_NUMBER; } - else if (isalpha (c) || c == '_') + else if (c_isalpha (c) || c == '_') { *sval++ = c; while (*s < end - && (c = *(*s)++, (isalnum (c) || c == '_'))) + && (c = *(*s)++, (c_isalnum (c) || c == '_'))) *sval++ = c; *sval = 0; if (*s < end) @@ -2562,7 +2525,7 @@ convert_mono_to_color_image (struct frame *f, struct image *img, static void Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data, RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg, - int non_default_colors) + bool non_default_colors) { #ifdef HAVE_NTGUI img->pixmap @@ -2594,20 +2557,20 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data, X versions. CONTENTS is a pointer to a buffer to parse; END is the buffer's end. Set *WIDTH and *HEIGHT to the width and height of the image. Return in *DATA the bitmap data allocated with xmalloc. - Value is non-zero if successful. DATA null means just test if - CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR - is non-zero, inhibit the call to image_error when the image size is - invalid (the bitmap remains unread). */ + Value is true if successful. DATA null means just test if + CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR, + inhibit the call to image_error when the image size is invalid (the + bitmap remains unread). */ -static int +static bool xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end, int *width, int *height, char **data, - int inhibit_image_error) + bool inhibit_image_error) { unsigned char *s = contents; char buffer[BUFSIZ]; - int padding_p = 0; - int v10 = 0; + bool padding_p = 0; + bool v10 = 0; int bytes_per_line, i, nbytes; char *p; int value; @@ -2754,16 +2717,16 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e /* Load XBM image IMG which will be displayed on frame F from buffer - CONTENTS. END is the end of the buffer. Value is non-zero if + CONTENTS. END is the end of the buffer. Value is true if successful. */ -static int +static bool xbm_load_image (struct frame *f, struct image *img, unsigned char *contents, unsigned char *end) { - int rc; + bool rc; char *data; - int success_p = 0; + bool success_p = 0; rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data, 0); @@ -2771,7 +2734,7 @@ xbm_load_image (struct frame *f, struct image *img, unsigned char *contents, { unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); unsigned long background = FRAME_BACKGROUND_PIXEL (f); - int non_default_colors = 0; + bool non_default_colors = 0; Lisp_Object value; eassert (img->width > 0 && img->height > 0); @@ -2812,9 +2775,9 @@ xbm_load_image (struct frame *f, struct image *img, unsigned char *contents, } -/* Value is non-zero if DATA looks like an in-memory XBM file. */ +/* Value is true if DATA looks like an in-memory XBM file. */ -static int +static bool xbm_file_p (Lisp_Object data) { int w, h; @@ -2826,12 +2789,12 @@ xbm_file_p (Lisp_Object data) /* Fill image IMG which is used on frame F with pixmap data. Value is - non-zero if successful. */ + true if successful. */ -static int +static bool xbm_load (struct frame *f, struct image *img) { - int success_p = 0; + bool success_p = 0; Lisp_Object file_name; eassert (xbm_image_p (img->spec)); @@ -2867,10 +2830,10 @@ xbm_load (struct frame *f, struct image *img) Lisp_Object data; unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); unsigned long background = FRAME_BACKGROUND_PIXEL (f); - int non_default_colors = 0; + bool non_default_colors = 0; char *bits; - int parsed_p; - int in_memory_file_p = 0; + bool parsed_p; + bool in_memory_file_p = 0; /* See if data looks like an in-memory XBM file. */ data = image_spec_value (img->spec, QCdata, NULL); @@ -2879,7 +2842,6 @@ xbm_load (struct frame *f, struct image *img) /* Parse the image specification. */ memcpy (fmt, xbm_format, sizeof fmt); parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm); - (void) parsed_p; eassert (parsed_p); /* Get specified width, and height. */ @@ -2940,7 +2902,7 @@ xbm_load (struct frame *f, struct image *img) else bits = (char *) XBOOL_VECTOR (data)->data; -#ifdef WINDOWSNT +#ifdef HAVE_NTGUI { char *invertedBits; int nbytes, i; @@ -2984,9 +2946,8 @@ xbm_load (struct frame *f, struct image *img) #if defined (HAVE_XPM) || defined (HAVE_NS) -static int xpm_image_p (Lisp_Object object); -static int xpm_load (struct frame *f, struct image *img); -static int xpm_valid_color_symbols_p (Lisp_Object); +static bool xpm_image_p (Lisp_Object object); +static bool xpm_load (struct frame *f, struct image *img); #endif /* HAVE_XPM || HAVE_NS */ @@ -3052,6 +3013,12 @@ static const struct image_keyword xpm_format[XPM_LAST] = {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; +#if defined HAVE_NTGUI && defined WINDOWSNT +static bool init_xpm_functions (void); +#else +#define init_xpm_functions NULL +#endif + /* Structure describing the image type XPM. */ static struct image_type xpm_type = @@ -3060,6 +3027,7 @@ static struct image_type xpm_type = xpm_image_p, xpm_load, x_clear_image, + init_xpm_functions, NULL }; @@ -3077,10 +3045,6 @@ static struct image_type xpm_type = #ifdef ALLOC_XPM_COLORS -static void xpm_init_color_cache (struct frame *, XpmAttributes *); -static void xpm_free_color_cache (void); -static int xpm_lookup_color (struct frame *, char *, XColor *); -static int xpm_color_bucket (char *); static struct xpm_cached_color *xpm_cache_color (struct frame *, char *, XColor *, int); @@ -3187,10 +3151,10 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket) /* Look up color COLOR_NAME for frame F in the color cache. If found, return the cached definition in *COLOR. Otherwise, make a new - entry in the cache and allocate the color. Value is zero if color + entry in the cache and allocate the color. Value is false if color allocation failed. */ -static int +static bool xpm_lookup_color (struct frame *f, char *color_name, XColor *color) { struct xpm_cached_color *p; @@ -3248,7 +3212,7 @@ xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void * #endif /* ALLOC_XPM_COLORS */ -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* XPM library details. */ @@ -3259,12 +3223,12 @@ DEF_IMGLIB_FN (int, XpmReadFileToImage, (Display *, char *, xpm_XImage **, xpm_XImage **, XpmAttributes *)); DEF_IMGLIB_FN (void, XImageFree, (xpm_XImage *)); -static int -init_xpm_functions (Lisp_Object libraries) +static bool +init_xpm_functions (void) { HMODULE library; - if (!(library = w32_delayed_load (libraries, Qxpm))) + if (!(library = w32_delayed_load (Qxpm))) return 0; LOAD_IMGLIB_FN (library, XpmFreeAttributes); @@ -3274,14 +3238,21 @@ init_xpm_functions (Lisp_Object libraries) return 1; } -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ +#if defined HAVE_NTGUI && !defined WINDOWSNT +/* Glue for code below */ +#define fn_XpmReadFileToImage XpmReadFileToImage +#define fn_XpmCreateImageFromBuffer XpmCreateImageFromBuffer +#define fn_XImageFree XImageFree +#define fn_XpmFreeAttributes XpmFreeAttributes +#endif /* HAVE_NTGUI && !WINDOWSNT */ -/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list +/* Value is true if COLOR_SYMBOLS is a valid color symbols list for XPM images. Such a list must consist of conses whose car and cdr are strings. */ -static int +static bool xpm_valid_color_symbols_p (Lisp_Object color_symbols) { while (CONSP (color_symbols)) @@ -3298,9 +3269,9 @@ xpm_valid_color_symbols_p (Lisp_Object color_symbols) } -/* Value is non-zero if OBJECT is a valid XPM image specification. */ +/* Value is true if OBJECT is a valid XPM image specification. */ -static int +static bool xpm_image_p (Lisp_Object object) { struct image_keyword fmt[XPM_LAST]; @@ -3357,11 +3328,11 @@ x_create_bitmap_from_xpm_data (struct frame *f, const char **bits) #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */ /* Load image IMG which will be displayed on frame F. Value is - non-zero if successful. */ + true if successful. */ #ifdef HAVE_XPM -static int +static bool xpm_load (struct frame *f, struct image *img) { int rc; @@ -3661,16 +3632,17 @@ xpm_scan (const unsigned char **s, while (*s < end) { /* Skip white-space. */ - while (*s < end && (c = *(*s)++, isspace (c))) + while (*s < end && (c = *(*s)++, c_isspace (c))) ; /* gnus-pointer.xpm uses '-' in its identifier. sb-dir-plus.xpm uses '+' in its identifier. */ - if (isalpha (c) || c == '_' || c == '-' || c == '+') + if (c_isalpha (c) || c == '_' || c == '-' || c == '+') { *beg = *s - 1; while (*s < end - && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) + && (c = **s, c_isalnum (c) + || c == '_' || c == '-' || c == '+')) ++*s; *len = *s - *beg; return XPM_TK_IDENT; @@ -3814,7 +3786,7 @@ xpm_str_to_color_key (const char *s) return -1; } -static int +static bool xpm_load_image (struct frame *f, struct image *img, const unsigned char *contents, @@ -3829,7 +3801,8 @@ xpm_load_image (struct frame *f, void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object); Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int); Lisp_Object frame, color_symbols, color_table; - int best_key, have_mask = 0; + int best_key; + bool have_mask = 0; XImagePtr ximg = NULL, mask_img = NULL; #define match() \ @@ -4049,11 +4022,11 @@ xpm_load_image (struct frame *f, #undef expect_ident } -static int +static bool xpm_load (struct frame *f, struct image *img) { - int success_p = 0; + bool success_p = 0; Lisp_Object file_name; /* If IMG->spec specifies a file name, create a non-file spec from it. */ @@ -4224,7 +4197,7 @@ lookup_rgb_color (struct frame *f, int r, int g, int b) #ifdef HAVE_X_WINDOWS XColor color; Colormap cmap; - int rc; + bool rc; #else COLORREF color; #endif @@ -4292,7 +4265,7 @@ lookup_pixel_color (struct frame *f, unsigned long pixel) { XColor color; Colormap cmap; - int rc; + bool rc; if (ct_colors_allocated_max <= ct_colors_allocated) return FRAME_FOREGROUND_PIXEL (f); @@ -4303,12 +4276,12 @@ lookup_pixel_color (struct frame *f, unsigned long pixel) x_query_color (f, &color); rc = x_alloc_nearest_color (f, cmap, &color); #else - BLOCK_INPUT; + block_input (); cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); color.pixel = pixel; XQueryColor (NULL, cmap, &color); rc = x_alloc_nearest_color (f, cmap, &color); - UNBLOCK_INPUT; + unblock_input (); #endif /* HAVE_X_WINDOWS */ if (rc) @@ -4386,14 +4359,6 @@ init_color_table (void) Algorithms ***********************************************************************/ -static XColor *x_to_xcolors (struct frame *, struct image *, int); -static void x_from_xcolors (struct frame *, struct image *, XColor *); -static void x_detect_edges (struct frame *, struct image *, int[9], int); - -#ifdef HAVE_NTGUI -static void XPutPixel (XImagePtr , int, int, COLORREF); -#endif /* HAVE_NTGUI */ - /* Edge detection matrices for different edge-detection strategies. */ @@ -4419,12 +4384,12 @@ static int laplace_matrix[9] = { /* On frame F, return an array of XColor structures describing image IMG->pixmap. Each XColor structure has its pixel color set. RGB_P - non-zero means also fill the red/green/blue members of the XColor + means also fill the red/green/blue members of the XColor structures. Value is a pointer to the array of XColors structures, allocated with xmalloc; it must be freed by the caller. */ static XColor * -x_to_xcolors (struct frame *f, struct image *img, int rgb_p) +x_to_xcolors (struct frame *f, struct image *img, bool rgb_p) { int x, y; XColor *colors, *p; @@ -4800,9 +4765,9 @@ x_disable_image (struct frame *f, struct image *img) determine the background color of IMG. If it is a list '(R G B)', with R, G, and B being integers >= 0, take that as the color of the background. Otherwise, determine the background color of IMG - heuristically. Value is non-zero if successful. */ + heuristically. */ -static int +static void x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) { XImagePtr_or_DC ximg; @@ -4814,7 +4779,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) char *mask_img; int row_width; #endif /* HAVE_NTGUI */ - int x, y, rc, use_img_background; + int x, y; + bool rc, use_img_background; unsigned long bg = 0; if (img->mask) @@ -4830,7 +4796,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1, &mask_img, &img->mask); if (!rc) - return 0; + return; #endif /* !HAVE_NS */ /* Get the X image of IMG->pixmap. */ @@ -4920,8 +4886,6 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) #endif /* HAVE_NTGUI */ Destroy_Image (ximg, prev); - - return 1; } @@ -4929,9 +4893,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) PBM (mono, gray, color) ***********************************************************************/ -static int pbm_image_p (Lisp_Object object); -static int pbm_load (struct frame *f, struct image *img); -static int pbm_scan_number (unsigned char **, unsigned char *); +static bool pbm_image_p (Lisp_Object object); +static bool pbm_load (struct frame *f, struct image *img); /* The symbol `pbm' identifying images of this type. */ @@ -4981,13 +4944,14 @@ static struct image_type pbm_type = pbm_image_p, pbm_load, x_clear_image, + NULL, NULL }; -/* Return non-zero if OBJECT is a valid PBM image specification. */ +/* Return true if OBJECT is a valid PBM image specification. */ -static int +static bool pbm_image_p (Lisp_Object object) { struct image_keyword fmt[PBM_LAST]; @@ -5014,7 +4978,7 @@ pbm_scan_number (unsigned char **s, unsigned char *end) while (*s < end) { /* Skip white-space. */ - while (*s < end && (c = *(*s)++, isspace (c))) + while (*s < end && (c = *(*s)++, c_isspace (c))) ; if (c == '#') @@ -5023,11 +4987,11 @@ pbm_scan_number (unsigned char **s, unsigned char *end) while (*s < end && (c = *(*s)++, c != '\n')) ; } - else if (isdigit (c)) + else if (c_isdigit (c)) { /* Read decimal number. */ val = c - '0'; - while (*s < end && (c = *(*s)++, isdigit (c))) + while (*s < end && (c = *(*s)++, c_isdigit (c))) val = 10 * val + c - '0'; break; } @@ -5039,51 +5003,13 @@ pbm_scan_number (unsigned char **s, unsigned char *end) } -#ifdef HAVE_NTGUI -#if 0 /* Unused. ++kfs */ - -/* Read FILE into memory. Value is a pointer to a buffer allocated - with xmalloc holding FILE's contents. Value is null if an error - occurred. *SIZE is set to the size of the file. */ - -static char * -pbm_read_file (Lisp_Object file, int *size) -{ - FILE *fp = NULL; - char *buf = NULL; - struct stat st; - - if (stat (SDATA (file), &st) == 0 - && (fp = fopen (SDATA (file), "rb")) != NULL - && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) - && (buf = xmalloc (st.st_size), - fread (buf, 1, st.st_size, fp) == st.st_size)) - { - *size = st.st_size; - fclose (fp); - } - else - { - if (fp) - fclose (fp); - if (buf) - { - xfree (buf); - buf = NULL; - } - } - - return buf; -} -#endif -#endif /* HAVE_NTGUI */ - /* Load PBM image IMG for use on frame F. */ -static int +static bool pbm_load (struct frame *f, struct image *img) { - int raw_p, x, y; + bool raw_p; + int x, y; int width, height, max_color_idx = 0; XImagePtr ximg; Lisp_Object file, specified_file; @@ -5346,8 +5272,8 @@ pbm_load (struct frame *f, struct image *img) /* Function prototypes. */ -static int png_image_p (Lisp_Object object); -static int png_load (struct frame *f, struct image *img); +static bool png_image_p (Lisp_Object object); +static bool png_load (struct frame *f, struct image *img); /* The symbol `png' identifying images of this type. */ @@ -5387,6 +5313,12 @@ static const struct image_keyword png_format[PNG_LAST] = {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; +#if defined HAVE_NTGUI && defined WINDOWSNT +static bool init_png_functions (void); +#else +#define init_png_functions NULL +#endif + /* Structure describing the image type `png'. */ static struct image_type png_type = @@ -5395,12 +5327,13 @@ static struct image_type png_type = png_image_p, png_load, x_clear_image, + init_png_functions, NULL }; -/* Return non-zero if OBJECT is a valid PNG image specification. */ +/* Return true if OBJECT is a valid PNG image specification. */ -static int +static bool png_image_p (Lisp_Object object) { struct image_keyword fmt[PNG_LAST]; @@ -5418,7 +5351,7 @@ png_image_p (Lisp_Object object) #ifdef HAVE_PNG -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* PNG library details. */ DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp)); @@ -5452,12 +5385,12 @@ DEF_IMGLIB_FN (void, png_longjmp, (png_structp, int)); DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn, (png_structp, png_longjmp_ptr, size_t)); #endif /* libpng version >= 1.5 */ -static int -init_png_functions (Lisp_Object libraries) +static bool +init_png_functions (void) { HMODULE library; - if (!(library = w32_delayed_load (libraries, Qpng))) + if (!(library = w32_delayed_load (Qpng))) return 0; LOAD_IMGLIB_FN (library, png_get_io_ptr); @@ -5518,17 +5451,26 @@ init_png_functions (Lisp_Object libraries) #define fn_png_set_longjmp_fn png_set_longjmp_fn #endif /* libpng version >= 1.5 */ -#endif /* HAVE_NTGUI */ +#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 +#endif #if (PNG_LIBPNG_VER < 10500) -#define PNG_LONGJMP(ptr) (longjmp ((ptr)->jmpbuf, 1)) +#define PNG_LONGJMP(ptr) (_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_JMPBUF(ptr) \ - (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf))) + (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf))) #endif /* Error and warning handlers installed when the PNG library @@ -5594,28 +5536,39 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) } -/* Load PNG image IMG for use on frame F. Value is non-zero if +/* Load PNG image IMG for use on frame F. Value is true if successful. */ -static int -png_load (struct frame *f, struct image *img) +struct png_load_context +{ + /* These are members so that longjmp doesn't munge local variables. */ + png_struct *png_ptr; + png_info *info_ptr; + png_info *end_info; + FILE *fp; + png_byte *pixels; + png_byte **rows; +}; + +static bool +png_load_body (struct frame *f, struct image *img, struct png_load_context *c) { Lisp_Object file, specified_file; Lisp_Object specified_data; int x, y; ptrdiff_t i; XImagePtr ximg, mask_img = NULL; - png_struct *png_ptr = NULL; + png_struct *png_ptr; png_info *info_ptr = NULL, *end_info = NULL; - FILE *volatile fp = NULL; + FILE *fp = NULL; png_byte sig[8]; - png_byte * volatile pixels = NULL; - png_byte ** volatile rows = NULL; + png_byte *pixels = NULL; + png_byte **rows = NULL; png_uint_32 width, height; int bit_depth, color_type, interlace_type; png_byte channels; png_uint_32 row_bytes; - int transparent_p; + bool transparent_p; struct png_memory_storage tbr; /* Data to be read */ /* Find out what file to load. */ @@ -5677,41 +5630,47 @@ png_load (struct frame *f, struct image *img) png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, my_png_error, my_png_warning); - if (!png_ptr) + if (png_ptr) { - if (fp) fclose (fp); - return 0; + info_ptr = fn_png_create_info_struct (png_ptr); + end_info = fn_png_create_info_struct (png_ptr); } - info_ptr = fn_png_create_info_struct (png_ptr); - if (!info_ptr) + c->png_ptr = png_ptr; + c->info_ptr = info_ptr; + c->end_info = end_info; + c->fp = fp; + c->pixels = pixels; + c->rows = rows; + + if (! (info_ptr && end_info)) { - fn_png_destroy_read_struct (&png_ptr, NULL, NULL); - if (fp) fclose (fp); - return 0; + fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info); + png_ptr = 0; } - - end_info = fn_png_create_info_struct (png_ptr); - if (!end_info) + if (! png_ptr) { - fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); if (fp) fclose (fp); return 0; } /* Set error jump-back. We come back here when the PNG library detects an error. */ - if (setjmp (PNG_JMPBUF (png_ptr))) + if (_setjmp (PNG_JMPBUF (png_ptr))) { error: - if (png_ptr) - fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); - xfree (pixels); - xfree (rows); - if (fp) fclose (fp); + if (c->png_ptr) + fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info); + xfree (c->pixels); + xfree (c->rows); + if (c->fp) + fclose (c->fp); return 0; } + /* Silence a bogus diagnostic; see GCC bug 54561. */ + IF_LINT (fp = c->fp); + /* Read image info. */ if (!NILP (specified_data)) fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); @@ -5827,8 +5786,8 @@ png_load (struct frame *f, struct image *img) if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes) memory_full (SIZE_MAX); - pixels = xmalloc (sizeof *pixels * row_bytes * height); - rows = xmalloc (height * sizeof *rows); + c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height); + c->rows = rows = xmalloc (height * sizeof *rows); for (i = 0; i < height; ++i) rows[i] = pixels + i * row_bytes; @@ -5838,7 +5797,7 @@ png_load (struct frame *f, struct image *img) if (fp) { fclose (fp); - fp = NULL; + c->fp = NULL; } /* Create an image and pixmap serving as mask if the PNG image @@ -5913,7 +5872,7 @@ png_load (struct frame *f, struct image *img) #endif /* COLOR_TABLE_SUPPORT */ /* Clean up. */ - fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); + fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info); xfree (rows); xfree (pixels); @@ -5942,10 +5901,17 @@ png_load (struct frame *f, struct image *img) return 1; } +static bool +png_load (struct frame *f, struct image *img) +{ + struct png_load_context c; + return png_load_body (f, img, &c); +} + #else /* HAVE_PNG */ #ifdef HAVE_NS -static int +static bool png_load (struct frame *f, struct image *img) { return ns_load_image (f, img, @@ -5965,8 +5931,8 @@ png_load (struct frame *f, struct image *img) #if defined (HAVE_JPEG) || defined (HAVE_NS) -static int jpeg_image_p (Lisp_Object object); -static int jpeg_load (struct frame *f, struct image *img); +static bool jpeg_image_p (Lisp_Object object); +static bool jpeg_load (struct frame *f, struct image *img); /* The symbol `jpeg' identifying images of this type. */ @@ -6006,6 +5972,12 @@ static const struct image_keyword jpeg_format[JPEG_LAST] = {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; +#if defined HAVE_NTGUI && defined WINDOWSNT +static bool init_jpeg_functions (void); +#else +#define init_jpeg_functions NULL +#endif + /* Structure describing the image type `jpeg'. */ static struct image_type jpeg_type = @@ -6014,12 +5986,13 @@ static struct image_type jpeg_type = jpeg_image_p, jpeg_load, x_clear_image, + init_jpeg_functions, NULL }; -/* Return non-zero if OBJECT is a valid JPEG image specification. */ +/* Return true if OBJECT is a valid JPEG image specification. */ -static int +static bool jpeg_image_p (Lisp_Object object) { struct image_keyword fmt[JPEG_LAST]; @@ -6049,14 +6022,27 @@ jpeg_image_p (Lisp_Object object) #define __WIN32__ 1 #endif +/* rpcndr.h (via windows.h) and jpeglib.h both define boolean types. + Some versions of jpeglib try to detect whether rpcndr.h is loaded, + using the Windows boolean type instead of the jpeglib boolean type + if so. Cygwin jpeglib, however, doesn't try to detect whether its + headers are included along with windows.h, so under Cygwin, jpeglib + attempts to define a conflicting boolean type. Worse, forcing + Cygwin jpeglib headers to use the Windows boolean type doesn't work + because it created an ABI incompatibility between the + already-compiled jpeg library and the header interface definition. + + The best we can do is to define jpeglib's boolean type to a + different name. This name, jpeg_boolean, remains in effect through + the rest of image.c. +*/ +#if defined CYGWIN && defined HAVE_NTGUI +#define boolean jpeg_boolean +#endif #include #include -#ifdef HAVE_STLIB_H_1 -#define HAVE_STDLIB_H 1 -#endif - -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* JPEG library details. */ DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t)); @@ -6068,12 +6054,12 @@ DEF_IMGLIB_FN (JDIMENSION, jpeg_read_scanlines, (j_decompress_ptr, JSAMPARRAY, J DEF_IMGLIB_FN (struct jpeg_error_mgr *, jpeg_std_error, (struct jpeg_error_mgr *)); DEF_IMGLIB_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int)); -static int -init_jpeg_functions (Lisp_Object libraries) +static bool +init_jpeg_functions (void) { HMODULE library; - if (!(library = w32_delayed_load (libraries, Qjpeg))) + if (!(library = w32_delayed_load (Qjpeg))) return 0; LOAD_IMGLIB_FN (library, jpeg_finish_decompress); @@ -6106,12 +6092,25 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired) #define fn_jpeg_std_error jpeg_std_error #define jpeg_resync_to_restart_wrapper jpeg_resync_to_restart -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ struct my_jpeg_error_mgr { struct jpeg_error_mgr pub; - jmp_buf setjmp_buffer; + sys_jmp_buf setjmp_buffer; + + /* The remaining members are so that longjmp doesn't munge local + variables. */ + struct jpeg_decompress_struct cinfo; + enum + { + MY_JPEG_ERROR_EXIT, + MY_JPEG_INVALID_IMAGE_SIZE, + MY_JPEG_CANNOT_CREATE_X + } failure_code; +#ifdef lint + FILE *fp; +#endif }; @@ -6119,7 +6118,8 @@ static _Noreturn void my_error_exit (j_common_ptr cinfo) { struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err; - longjmp (mgr->setjmp_buffer, 1); + mgr->failure_code = MY_JPEG_ERROR_EXIT; + sys_longjmp (mgr->setjmp_buffer, 1); } @@ -6187,7 +6187,7 @@ our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) reading the image. */ static void -jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len) +jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len) { struct jpeg_source_mgr *src; @@ -6324,18 +6324,16 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp) /* Load image IMG for use on frame F. Patterned after example.c from the JPEG lib. */ -static int -jpeg_load (struct frame *f, struct image *img) +static bool +jpeg_load_body (struct frame *f, struct image *img, + struct my_jpeg_error_mgr *mgr) { - struct jpeg_decompress_struct cinfo; - struct my_jpeg_error_mgr mgr; Lisp_Object file, specified_file; Lisp_Object specified_data; - FILE * volatile fp = NULL; + FILE *fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; XImagePtr ximg = NULL; - int rc; unsigned long *colors; int width, height; @@ -6365,26 +6363,37 @@ jpeg_load (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. */ - cinfo.err = fn_jpeg_std_error (&mgr.pub); - mgr.pub.error_exit = my_error_exit; - - if ((rc = setjmp (mgr.setjmp_buffer)) != 0) + mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub); + mgr->pub.error_exit = my_error_exit; + if (sys_setjmp (mgr->setjmp_buffer)) { - if (rc == 1) + switch (mgr->failure_code) { - /* Called from my_error_exit. Display a JPEG error. */ - char buf[JMSG_LENGTH_MAX]; - cinfo.err->format_message ((j_common_ptr) &cinfo, buf); - image_error ("Error reading JPEG image `%s': %s", img->spec, - build_string (buf)); + case MY_JPEG_ERROR_EXIT: + { + char buf[JMSG_LENGTH_MAX]; + mgr->cinfo.err->format_message ((j_common_ptr) &mgr->cinfo, buf); + image_error ("Error reading JPEG image `%s': %s", img->spec, + build_string (buf)); + break; + } + + case MY_JPEG_INVALID_IMAGE_SIZE: + image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); + break; + + case MY_JPEG_CANNOT_CREATE_X: + break; } /* Close the input file and destroy the JPEG object. */ if (fp) - fclose ((FILE *) fp); - fn_jpeg_destroy_decompress (&cinfo); + fclose (fp); + fn_jpeg_destroy_decompress (&mgr->cinfo); /* If we already have an XImage, free that. */ x_destroy_x_image (ximg); @@ -6394,46 +6403,52 @@ jpeg_load (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 (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo)); + fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo); if (NILP (specified_data)) - jpeg_file_src (&cinfo, (FILE *) fp); + jpeg_file_src (&mgr->cinfo, fp); else - jpeg_memory_src (&cinfo, SDATA (specified_data), + jpeg_memory_src (&mgr->cinfo, SDATA (specified_data), SBYTES (specified_data)); - fn_jpeg_read_header (&cinfo, 1); + fn_jpeg_read_header (&mgr->cinfo, 1); /* Customize decompression so that color quantization will be used. Start decompression. */ - cinfo.quantize_colors = 1; - fn_jpeg_start_decompress (&cinfo); - width = img->width = cinfo.output_width; - height = img->height = cinfo.output_height; + mgr->cinfo.quantize_colors = 1; + fn_jpeg_start_decompress (&mgr->cinfo); + width = img->width = mgr->cinfo.output_width; + height = img->height = mgr->cinfo.output_height; if (!check_image_size (f, width, height)) { - image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); - longjmp (mgr.setjmp_buffer, 2); + mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE; + sys_longjmp (mgr->setjmp_buffer, 1); } /* Create X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) - longjmp (mgr.setjmp_buffer, 2); + { + mgr->failure_code = MY_JPEG_CANNOT_CREATE_X; + sys_longjmp (mgr->setjmp_buffer, 1); + } /* Allocate colors. When color quantization is used, - cinfo.actual_number_of_colors has been set with the number of - colors generated, and cinfo.colormap is a two-dimensional array - of color indices in the range 0..cinfo.actual_number_of_colors. + mgr->cinfo.actual_number_of_colors has been set with the number of + colors generated, and mgr->cinfo.colormap is a two-dimensional array + of color indices in the range 0..mgr->cinfo.actual_number_of_colors. No more than 255 colors will be generated. */ { int i, ir, ig, ib; - if (cinfo.out_color_components > 2) + if (mgr->cinfo.out_color_components > 2) ir = 0, ig = 1, ib = 2; - else if (cinfo.out_color_components > 1) + else if (mgr->cinfo.out_color_components > 1) ir = 0, ig = 1, ib = 0; else ir = 0, ig = 0, ib = 0; @@ -6443,15 +6458,15 @@ jpeg_load (struct frame *f, struct image *img) a default color, and we don't have to care about which colors can be freed safely, and which can't. */ init_color_table (); - colors = alloca (cinfo.actual_number_of_colors * sizeof *colors); + colors = alloca (mgr->cinfo.actual_number_of_colors * sizeof *colors); - for (i = 0; i < cinfo.actual_number_of_colors; ++i) + for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i) { /* Multiply RGB values with 255 because X expects RGB values in the range 0..0xffff. */ - int r = cinfo.colormap[ir][i] << 8; - int g = cinfo.colormap[ig][i] << 8; - int b = cinfo.colormap[ib][i] << 8; + int r = mgr->cinfo.colormap[ir][i] << 8; + int g = mgr->cinfo.colormap[ig][i] << 8; + int b = mgr->cinfo.colormap[ib][i] << 8; colors[i] = lookup_rgb_color (f, r, g, b); } @@ -6463,21 +6478,21 @@ jpeg_load (struct frame *f, struct image *img) } /* Read pixels. */ - row_stride = width * cinfo.output_components; - buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, - row_stride, 1); + row_stride = width * mgr->cinfo.output_components; + buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo, + JPOOL_IMAGE, row_stride, 1); for (y = 0; y < height; ++y) { - fn_jpeg_read_scanlines (&cinfo, buffer, 1); - for (x = 0; x < cinfo.output_width; ++x) + fn_jpeg_read_scanlines (&mgr->cinfo, buffer, 1); + for (x = 0; x < mgr->cinfo.output_width; ++x) XPutPixel (ximg, x, y, colors[buffer[0][x]]); } /* Clean up. */ - fn_jpeg_finish_decompress (&cinfo); - fn_jpeg_destroy_decompress (&cinfo); + fn_jpeg_finish_decompress (&mgr->cinfo); + fn_jpeg_destroy_decompress (&mgr->cinfo); if (fp) - fclose ((FILE *) fp); + fclose (fp); /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) @@ -6490,10 +6505,17 @@ jpeg_load (struct frame *f, struct image *img) return 1; } +static bool +jpeg_load (struct frame *f, struct image *img) +{ + struct my_jpeg_error_mgr mgr; + return jpeg_load_body (f, img, &mgr); +} + #else /* HAVE_JPEG */ #ifdef HAVE_NS -static int +static bool jpeg_load (struct frame *f, struct image *img) { return ns_load_image (f, img, @@ -6512,8 +6534,8 @@ jpeg_load (struct frame *f, struct image *img) #if defined (HAVE_TIFF) || defined (HAVE_NS) -static int tiff_image_p (Lisp_Object object); -static int tiff_load (struct frame *f, struct image *img); +static bool tiff_image_p (Lisp_Object object); +static bool tiff_load (struct frame *f, struct image *img); /* The symbol `tiff' identifying images of this type. */ @@ -6555,6 +6577,12 @@ static const struct image_keyword tiff_format[TIFF_LAST] = {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0} }; +#if defined HAVE_NTGUI && defined WINDOWSNT +static bool init_tiff_functions (void); +#else +#define init_tiff_functions NULL +#endif + /* Structure describing the image type `tiff'. */ static struct image_type tiff_type = @@ -6563,12 +6591,13 @@ static struct image_type tiff_type = tiff_image_p, tiff_load, x_clear_image, + init_tiff_functions, NULL }; -/* Return non-zero if OBJECT is a valid TIFF image specification. */ +/* Return true if OBJECT is a valid TIFF image specification. */ -static int +static bool tiff_image_p (Lisp_Object object) { struct image_keyword fmt[TIFF_LAST]; @@ -6587,7 +6616,7 @@ tiff_image_p (Lisp_Object object) #include -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* TIFF library details. */ DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler)); @@ -6602,12 +6631,12 @@ DEF_IMGLIB_FN (int, TIFFReadRGBAImage, (TIFF *, uint32, uint32, uint32 *, int)); DEF_IMGLIB_FN (void, TIFFClose, (TIFF *)); DEF_IMGLIB_FN (int, TIFFSetDirectory, (TIFF *, tdir_t)); -static int -init_tiff_functions (Lisp_Object libraries) +static bool +init_tiff_functions (void) { HMODULE library; - if (!(library = w32_delayed_load (libraries, Qtiff))) + if (!(library = w32_delayed_load (Qtiff))) return 0; LOAD_IMGLIB_FN (library, TIFFSetErrorHandler); @@ -6631,7 +6660,7 @@ init_tiff_functions (Lisp_Object libraries) #define fn_TIFFReadRGBAImage TIFFReadRGBAImage #define fn_TIFFClose TIFFClose #define fn_TIFFSetDirectory TIFFSetDirectory -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ /* Reading from a memory buffer for TIFF images Based on the PNG @@ -6772,10 +6801,10 @@ tiff_warning_handler (const char *title, const char *format, va_list ap) } -/* Load TIFF image IMG for use on frame F. Value is non-zero if +/* Load TIFF image IMG for use on frame F. Value is true if successful. */ -static int +static bool tiff_load (struct frame *f, struct image *img) { Lisp_Object file, specified_file; @@ -6940,7 +6969,7 @@ tiff_load (struct frame *f, struct image *img) #else /* HAVE_TIFF */ #ifdef HAVE_NS -static int +static bool tiff_load (struct frame *f, struct image *img) { return ns_load_image (f, img, @@ -6959,8 +6988,8 @@ tiff_load (struct frame *f, struct image *img) #if defined (HAVE_GIF) || defined (HAVE_NS) -static int gif_image_p (Lisp_Object object); -static int gif_load (struct frame *f, struct image *img); +static bool gif_image_p (Lisp_Object object); +static bool gif_load (struct frame *f, struct image *img); static void gif_clear_image (struct frame *f, struct image *img); /* The symbol `gif' identifying images of this type. */ @@ -7003,6 +7032,12 @@ static const struct image_keyword gif_format[GIF_LAST] = {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; +#if defined HAVE_NTGUI && defined WINDOWSNT +static bool init_gif_functions (void); +#else +#define init_gif_functions NULL +#endif + /* Structure describing the image type `gif'. */ static struct image_type gif_type = @@ -7011,6 +7046,7 @@ static struct image_type gif_type = gif_image_p, gif_load, gif_clear_image, + init_gif_functions, NULL }; @@ -7023,9 +7059,9 @@ gif_clear_image (struct frame *f, struct image *img) x_clear_image (f, img); } -/* Return non-zero if OBJECT is a valid GIF image specification. */ +/* Return true if OBJECT is a valid GIF image specification. */ -static int +static bool gif_image_p (Lisp_Object object) { struct image_keyword fmt[GIF_LAST]; @@ -7060,7 +7096,7 @@ gif_image_p (Lisp_Object object) #endif /* HAVE_NTGUI */ -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* GIF library details. */ DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *)); @@ -7068,12 +7104,12 @@ DEF_IMGLIB_FN (int, DGifSlurp, (GifFileType *)); DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc)); DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *)); -static int -init_gif_functions (Lisp_Object libraries) +static bool +init_gif_functions (void) { HMODULE library; - if (!(library = w32_delayed_load (libraries, Qgif))) + if (!(library = w32_delayed_load (Qgif))) return 0; LOAD_IMGLIB_FN (library, DGifCloseFile); @@ -7090,7 +7126,7 @@ init_gif_functions (Lisp_Object libraries) #define fn_DGifOpen DGifOpen #define fn_DGifOpenFileName DGifOpenFileName -#endif /* HAVE_NTGUI */ +#endif /* WINDOWSNT */ /* Reading a GIF image from memory Based on the PNG memory stuff to a certain extent. */ @@ -7122,7 +7158,7 @@ gif_read_from_memory (GifFileType *file, GifByteType *buf, int len) } -/* Load GIF image IMG for use on frame F. Value is non-zero if +/* Load GIF image IMG for use on frame F. Value is true if successful. */ static const int interlace_start[] = {0, 4, 2, 1}; @@ -7130,7 +7166,7 @@ static const int interlace_increment[] = {8, 8, 4, 2}; #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249 -static int +static bool gif_load (struct frame *f, struct image *img) { Lisp_Object file; @@ -7428,7 +7464,7 @@ gif_load (struct frame *f, struct image *img) #else /* !HAVE_GIF */ #ifdef HAVE_NS -static int +static bool gif_load (struct frame *f, struct image *img) { return ns_load_image (f, img, @@ -7447,8 +7483,8 @@ gif_load (struct frame *f, struct image *img) static Lisp_Object Qimagemagick; -static int imagemagick_image_p (Lisp_Object); -static int imagemagick_load (struct frame *, struct image *); +static bool imagemagick_image_p (Lisp_Object); +static bool imagemagick_load (struct frame *, struct image *); static void imagemagick_clear_image (struct frame *, struct image *); /* Indices of image specification fields in imagemagick_format. */ @@ -7493,6 +7529,12 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; +#if defined HAVE_NTGUI && defined WINDOWSNT +static bool init_imagemagick_functions (void); +#else +#define init_imagemagick_functions NULL +#endif + /* Structure describing the image type for any image handled via ImageMagick. */ @@ -7502,6 +7544,7 @@ static struct image_type imagemagick_type = imagemagick_image_p, imagemagick_load, imagemagick_clear_image, + init_imagemagick_functions, NULL }; @@ -7514,11 +7557,11 @@ imagemagick_clear_image (struct frame *f, x_clear_image (f, img); } -/* Return non-zero if OBJECT is a valid IMAGEMAGICK image specification. Do +/* Return true if OBJECT is a valid IMAGEMAGICK image specification. Do this by calling parse_image_spec and supplying the keywords that identify the IMAGEMAGICK format. */ -static int +static bool imagemagick_image_p (Lisp_Object object) { struct image_keyword fmt[IMAGEMAGICK_LAST]; @@ -7570,9 +7613,9 @@ imagemagick_error (MagickWand *wand) be parsed; SIZE is the number of bytes of data; and FILENAME is either the file name or the image data. - Return non-zero if successful. */ + Return true if successful. */ -static int +static bool imagemagick_load_image (struct frame *f, struct image *img, unsigned char *contents, unsigned int size, char *filename) @@ -7910,14 +7953,14 @@ imagemagick_load_image (struct frame *f, struct image *img, } -/* Load IMAGEMAGICK image IMG for use on frame F. Value is non-zero if +/* Load IMAGEMAGICK image IMG for use on frame F. Value is true if successful. this function will go into the imagemagick_type structure, and the prototype thus needs to be compatible with that structure. */ -static int +static bool imagemagick_load (struct frame *f, struct image *img) { - int success_p = 0; + bool success_p = 0; Lisp_Object file_name; /* If IMG->spec specifies a file name, create a non-file spec from it. */ @@ -7996,11 +8039,11 @@ and `imagemagick-types-inhibit'. */) /* Function prototypes. */ -static int svg_image_p (Lisp_Object object); -static int svg_load (struct frame *f, struct image *img); +static bool svg_image_p (Lisp_Object object); +static bool svg_load (struct frame *f, struct image *img); -static int svg_load_image (struct frame *, struct image *, - unsigned char *, ptrdiff_t); +static bool svg_load_image (struct frame *, struct image *, + unsigned char *, ptrdiff_t); /* The symbol `svg' identifying images of this type. */ @@ -8040,31 +8083,32 @@ static const struct image_keyword svg_format[SVG_LAST] = {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; +#if defined HAVE_NTGUI && defined WINDOWSNT +static bool init_svg_functions (void); +#else +#define init_svg_functions NULL +#endif + /* Structure describing the image type `svg'. Its the same type of structure defined for all image formats, handled by emacs image functions. See struct image_type in dispextern.h. */ static struct image_type svg_type = { - /* An identifier showing that this is an image structure for the SVG format. */ &Qsvg, - /* Handle to a function that can be used to identify a SVG file. */ svg_image_p, - /* Handle to function used to load a SVG file. */ svg_load, - /* Handle to function to free sresources for SVG. */ x_clear_image, - /* An internal field to link to the next image type in a list of - image types, will be filled in when registering the format. */ + init_svg_functions, NULL }; -/* Return non-zero if OBJECT is a valid SVG image specification. Do +/* Return true if OBJECT is a valid SVG image specification. Do this by calling parse_image_spec and supplying the keywords that identify the SVG format. */ -static int +static bool svg_image_p (Lisp_Object object) { struct image_keyword fmt[SVG_LAST]; @@ -8079,7 +8123,7 @@ svg_image_p (Lisp_Object object) #include -#ifdef HAVE_NTGUI +#ifdef WINDOWSNT /* SVG library functions. */ DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new); @@ -8103,15 +8147,15 @@ DEF_IMGLIB_FN (void, g_error_free); Lisp_Object Qgdk_pixbuf, Qglib, Qgobject; -static int -init_svg_functions (Lisp_Object libraries) +static bool +init_svg_functions (void) { HMODULE library, gdklib, glib, gobject; - if (!(glib = w32_delayed_load (libraries, Qglib)) - || !(gobject = w32_delayed_load (libraries, Qgobject)) - || !(gdklib = w32_delayed_load (libraries, Qgdk_pixbuf)) - || !(library = w32_delayed_load (libraries, Qsvg))) + if (!(glib = w32_delayed_load (Qglib)) + || !(gobject = w32_delayed_load (Qgobject)) + || !(gdklib = w32_delayed_load (Qgdk_pixbuf)) + || !(library = w32_delayed_load (Qsvg))) return 0; LOAD_IMGLIB_FN (library, rsvg_handle_new); @@ -8157,16 +8201,15 @@ init_svg_functions (Lisp_Object libraries) #define fn_g_type_init g_type_init #define fn_g_object_unref g_object_unref #define fn_g_error_free g_error_free -#endif /* !HAVE_NTGUI */ +#endif /* !WINDOWSNT */ -/* Load SVG image IMG for use on frame F. Value is non-zero if - successful. this function will go into the svg_type structure, and - the prototype thus needs to be compatible with that structure. */ +/* Load SVG image IMG for use on frame F. Value is true if + successful. */ -static int +static bool svg_load (struct frame *f, struct image *img) { - int success_p = 0; + bool success_p = 0; Lisp_Object file_name; /* If IMG->spec specifies a file name, create a non-file spec from it. */ @@ -8219,8 +8262,8 @@ svg_load (struct frame *f, struct image *img) Uses librsvg to do most of the image processing. - Returns non-zero when successful. */ -static int + Returns true when successful. */ +static bool svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */ struct image *img, /* Pointer to emacs image structure. */ unsigned char *contents, /* String containing the SVG XML data to be parsed. */ @@ -8387,8 +8430,8 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * #ifdef HAVE_GHOSTSCRIPT -static int gs_image_p (Lisp_Object object); -static int gs_load (struct frame *f, struct image *img); +static bool gs_image_p (Lisp_Object object); +static bool gs_load (struct frame *f, struct image *img); static void gs_clear_image (struct frame *f, struct image *img); /* Keyword symbols. */ @@ -8443,6 +8486,7 @@ static struct image_type gs_type = gs_image_p, gs_load, gs_clear_image, + NULL, NULL }; @@ -8456,10 +8500,10 @@ gs_clear_image (struct frame *f, struct image *img) } -/* Return non-zero if OBJECT is a valid Ghostscript image +/* Return true if OBJECT is a valid Ghostscript image specification. */ -static int +static bool gs_image_p (Lisp_Object object) { struct image_keyword fmt[GS_LAST]; @@ -8496,10 +8540,10 @@ gs_image_p (Lisp_Object object) } -/* Load Ghostscript image IMG for use on frame F. Value is non-zero +/* Load Ghostscript image IMG for use on frame F. Value is true if successful. */ -static int +static bool gs_load (struct frame *f, struct image *img) { uprintmax_t printnum1, printnum2; @@ -8535,11 +8579,11 @@ gs_load (struct frame *f, struct image *img) if (x_check_image_size (0, img->width, img->height)) { /* Only W32 version did BLOCK_INPUT here. ++kfs */ - BLOCK_INPUT; + block_input (); img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), img->width, img->height, DefaultDepthOfScreen (FRAME_X_SCREEN (f))); - UNBLOCK_INPUT; + unblock_input (); } if (!img->pixmap) @@ -8554,7 +8598,7 @@ gs_load (struct frame *f, struct image *img) don't either. Let the Lisp loader use `unwind-protect' instead. */ printnum1 = FRAME_X_WINDOW (f); printnum2 = img->pixmap; - window_and_pixmap_id + window_and_pixmap_id = make_formatted_string (buffer, "%"pMu" %"pMu, printnum1, printnum2); printnum1 = FRAME_FOREGROUND_PIXEL (f); @@ -8615,7 +8659,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f) { XImagePtr ximg; - BLOCK_INPUT; + block_input (); /* Try to get an XImage for img->pixmep. */ ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, @@ -8658,15 +8702,15 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f) image_error ("Cannot get X image of `%s'; colors will not be freed", img->spec, Qnil); - UNBLOCK_INPUT; + unblock_input (); } #endif /* HAVE_X_WINDOWS */ /* Now that we have the pixmap, compute mask and transform the image if requested. */ - BLOCK_INPUT; + block_input (); postprocess_image (f, img); - UNBLOCK_INPUT; + unblock_input (); } #endif /* HAVE_GHOSTSCRIPT */ @@ -8705,88 +8749,92 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") Initialization ***********************************************************************/ -#ifdef HAVE_NTGUI -/* Image types that rely on external libraries are loaded dynamically - if the library is available. */ -#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ - define_image_type (image_type, init_lib_fn (libraries)) -#else -#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ - define_image_type (image_type, 1) -#endif /* HAVE_NTGUI */ - -DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0, +DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0, doc: /* Initialize image library implementing image type TYPE. Return non-nil if TYPE is a supported image type. -Image types pbm and xbm are prebuilt; other types are loaded here. -Libraries to load are specified in alist LIBRARIES (usually, the value -of `dynamic-library-alist', which see). */) - (Lisp_Object type, Lisp_Object libraries) +If image libraries are loaded dynamically (currently only the case on +MS-Windows), load the library for TYPE if it is not yet loaded, using +the library file(s) specified by `dynamic-library-alist'. */) + (Lisp_Object type) { -#ifdef HAVE_NTGUI - /* Don't try to reload the library. */ - Lisp_Object tested = Fassq (type, Vlibrary_cache); - if (CONSP (tested)) - return XCDR (tested); -#endif + return lookup_image_type (type) ? Qt : Qnil; +} + +/* Look up image type TYPE, and return a pointer to its image_type + structure. Return 0 if TYPE is not a known image type. */ +static struct image_type * +lookup_image_type (Lisp_Object type) +{ /* Types pbm and xbm are built-in and always available. */ - if (EQ (type, Qpbm) || EQ (type, Qxbm)) - return Qt; + if (EQ (type, Qpbm)) + return define_image_type (&pbm_type); + + if (EQ (type, Qxbm)) + return define_image_type (&xbm_type); #if defined (HAVE_XPM) || defined (HAVE_NS) if (EQ (type, Qxpm)) - return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries); + return define_image_type (&xpm_type); #endif #if defined (HAVE_JPEG) || defined (HAVE_NS) if (EQ (type, Qjpeg)) - return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries); + return define_image_type (&jpeg_type); #endif #if defined (HAVE_TIFF) || defined (HAVE_NS) if (EQ (type, Qtiff)) - return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries); + return define_image_type (&tiff_type); #endif #if defined (HAVE_GIF) || defined (HAVE_NS) if (EQ (type, Qgif)) - return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries); + return define_image_type (&gif_type); #endif #if defined (HAVE_PNG) || defined (HAVE_NS) if (EQ (type, Qpng)) - return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries); + return define_image_type (&png_type); #endif #if defined (HAVE_RSVG) if (EQ (type, Qsvg)) - return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); + return define_image_type (&svg_type); #endif #if defined (HAVE_IMAGEMAGICK) if (EQ (type, Qimagemagick)) - return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, - libraries); + return define_image_type (&imagemagick_type); #endif #ifdef HAVE_GHOSTSCRIPT if (EQ (type, Qpostscript)) - return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); + return define_image_type (&gs_type); #endif - /* If the type is not recognized, avoid testing it ever again. */ - CACHE_IMAGE_TYPE (type, Qnil); - return Qnil; + return NULL; +} + +/* Reset image_types before dumping. + Called from Fdump_emacs. */ + +void +reset_image_types (void) +{ + while (image_types) + { + struct image_type *next = image_types->next; + xfree (image_types); + image_types = next; + } } void syms_of_image (void) { - /* Initialize this only once, since that's what we do with Vimage_types - and they are supposed to be in sync. Initializing here gives correct - operation on GNU/Linux of calling dump-emacs after loading some images. */ + /* Initialize this only once; it will be reset before dumping. */ image_types = NULL; /* Must be defined now because we're going to update it below, while @@ -8809,15 +8857,6 @@ as a ratio to the frame height and width. If the value is non-numeric, there is no explicit limit on the size of images. */); Vmax_image_size = make_float (MAX_IMAGE_SIZE); - DEFSYM (Qpbm, "pbm"); - ADD_IMAGE_TYPE (Qpbm); - - DEFSYM (Qxbm, "xbm"); - ADD_IMAGE_TYPE (Qxbm); - - define_image_type (&xbm_type, 1); - define_image_type (&pbm_type, 1); - DEFSYM (Qcount, "count"); DEFSYM (Qextension_data, "extension-data"); DEFSYM (Qdelay, "delay"); @@ -8861,6 +8900,12 @@ non-numeric, there is no explicit limit on the size of images. */); ); #endif + DEFSYM (Qpbm, "pbm"); + ADD_IMAGE_TYPE (Qpbm); + + DEFSYM (Qxbm, "xbm"); + ADD_IMAGE_TYPE (Qxbm); + #if defined (HAVE_XPM) || defined (HAVE_NS) DEFSYM (Qxpm, "xpm"); ADD_IMAGE_TYPE (Qxpm);