X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b0da69a77b64c420c6e6157ee1ca0baac29fcd8d..80d0edae927b550944eb54eb49a70cb7f5353b68:/src/image.c diff --git a/src/image.c b/src/image.c index 3c53903b4b..3e8a62801b 100644 --- a/src/image.c +++ b/src/image.c @@ -1,6 +1,6 @@ /* Functions for image support on window system. - Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000,01,02,03,04 - Free Software Foundation. + Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -16,13 +16,13 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ #include -#include #include #include +#include #ifdef HAVE_UNISTD_H #include @@ -82,17 +82,24 @@ typedef struct w32_bitmap_record Bitmap_Record; #ifdef MAC_OS #include "macterm.h" +#include #ifndef MAC_OSX #include +#include #endif +#if TARGET_API_MAC_CARBON #ifdef MAC_OSX -#include #include -#else /* not MAC_OSX */ +#else /* not MAC_OSX */ +#include +#endif /* not MAC_OSX */ +#else /* not TARGET_API_MAC_CARBON */ #include #include #include -#endif /* not MAC_OSX */ +#include +#include +#endif /* not TARGET_API_MAC_CARBON */ /* MAC_TODO : Color tables on Mac. */ #undef COLOR_TABLE_SUPPORT @@ -605,6 +612,18 @@ x_create_bitmap_mask (f, id) static struct image_type *image_types; +/* A list of symbols, one for each supported image type. */ + +Lisp_Object Vimage_types; + +/* An alist of image types and libraries that implement the type. */ + +Lisp_Object Vimage_library_alist; + +/* Cache for delayed-loading image types. */ + +static Lisp_Object Vimage_type_cache; + /* The symbol `xbm' which is used as the type symbol for XBM images. */ Lisp_Object Qxbm; @@ -629,7 +648,7 @@ Lisp_Object Vimage_cache_eviction_delay; /* Function prototypes. */ -static void define_image_type P_ ((struct image_type *type)); +static Lisp_Object define_image_type P_ ((struct image_type *type, int loaded)); static struct image_type *lookup_image_type P_ ((Lisp_Object symbol)); static void image_error P_ ((char *format, Lisp_Object, Lisp_Object)); static void x_laplace P_ ((struct frame *, struct image *)); @@ -637,21 +656,37 @@ static void x_emboss P_ ((struct frame *, struct image *)); static int x_build_heuristic_mask P_ ((struct frame *, struct image *, Lisp_Object)); +#define CACHE_IMAGE_TYPE(type, status) \ + do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0) + +#define ADD_IMAGE_TYPE(type) \ + do { Vimage_types = Fcons (type, Vimage_types); } while (0) /* Define a new image type from TYPE. This adds a copy of TYPE to - image_types and adds the symbol *TYPE->type to Vimage_types. */ + image_types and caches the loading status of TYPE. */ -static void -define_image_type (type) +static Lisp_Object +define_image_type (type, loaded) struct image_type *type; + int loaded; { - /* 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 = (struct image_type *) xmalloc (sizeof *p); - bcopy (type, p, sizeof *p); - p->next = image_types; - image_types = p; - Vimage_types = Fcons (*p->type, Vimage_types); + Lisp_Object success; + + if (!loaded) + success = Qnil; + else + { + /* 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 = (struct image_type *) xmalloc (sizeof *p); + bcopy (type, p, sizeof *p); + p->next = image_types; + image_types = p; + success = Qt; + } + + CACHE_IMAGE_TYPE (*type->type, success); + return success; } @@ -664,6 +699,10 @@ lookup_image_type (symbol) { struct image_type *type; + /* We must initialize the image-type if it hasn't been already. */ + if (NILP (Finit_image_library (symbol, Vimage_library_alist))) + return 0; /* unimplemented */ + for (type = image_types; type; type = type->next) if (EQ (symbol, *type->type)) break; @@ -1596,11 +1635,6 @@ lookup_image (f, spec) Lisp_Object spec; { struct image_cache *c = FRAME_X_IMAGE_CACHE (f); -#ifdef _MSC_VER - /* Work around a problem with MinGW builds of graphics libraries - not honoring calling conventions. */ - static -#endif struct image *img; int i; unsigned hash; @@ -1780,7 +1814,7 @@ forall_images_in_image_cache (f, fn) #ifdef HAVE_NTGUI /* Macro for defining functions that will be loaded from image DLLs. */ -#define DEF_IMGLIB_FN(func) FARPROC fn_##func +#define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)() /* Macro for loading those image functions from the library. */ #define LOAD_IMGLIB_FN(lib,func) { \ @@ -1788,6 +1822,33 @@ forall_images_in_image_cache (f, fn) if (!fn_##func) return 0; \ } +/* Load a DLL implementing an image type. + The `image-library-alist' variable associates a symbol, + identifying an image type, to a list of possible filenames. + The function returns NULL if no library could be loaded for + the given image type, or if the library was previously loaded; + else the handle of the DLL. */ +static HMODULE +w32_delayed_load (Lisp_Object libraries, Lisp_Object type) +{ + HMODULE library = NULL; + + if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache))) + { + Lisp_Object dlls = Fassq (type, libraries); + + if (CONSP (dlls)) + for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls)) + { + CHECK_STRING_CAR (dlls); + if (library = LoadLibrary (SDATA (XCAR (dlls)))) + break; + } + } + + return library; +} + #endif /* HAVE_NTGUI */ static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, @@ -1911,7 +1972,8 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap) and store its handle in *pixmap. */ *pixmap = CreateDIBSection (hdc, &((*ximg)->info), (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS, - &((*ximg)->data), NULL, 0); + /* casting avoids a GCC warning */ + (void **)&((*ximg)->data), NULL, 0); /* Realize display palette and garbage all frames. */ release_frame_dc (f, hdc); @@ -2360,8 +2422,7 @@ image_load_quartz2d (f, img, png_p) UNGCPRO; return 0; } - path = CFStringCreateWithCString (NULL, SDATA (file), - kCFStringEncodingUTF8); + path = cfstring_create_with_string (file); url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0); CFRelease (path); @@ -3488,13 +3549,12 @@ DEF_IMGLIB_FN (XpmCreateImageFromBuffer); DEF_IMGLIB_FN (XpmReadFileToImage); DEF_IMGLIB_FN (XImageFree); - static int -init_xpm_functions (void) +init_xpm_functions (Lisp_Object libraries) { HMODULE library; - if (!(library = LoadLibrary ("libXpm.dll"))) + if (!(library = w32_delayed_load (libraries, Qxpm))) return 0; LOAD_IMGLIB_FN (library, XpmFreeAttributes); @@ -5458,7 +5518,8 @@ pbm_load (f, img) /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) - IMAGE_BACKGROUND (img, f, ximg); + /* Casting avoids a GCC warning. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); /* Put the image into a pixmap. */ x_put_x_image (f, ximg, img->pixmap, width, height); @@ -5570,7 +5631,6 @@ DEF_IMGLIB_FN (png_create_read_struct); DEF_IMGLIB_FN (png_create_info_struct); DEF_IMGLIB_FN (png_destroy_read_struct); DEF_IMGLIB_FN (png_set_read_fn); -DEF_IMGLIB_FN (png_init_io); DEF_IMGLIB_FN (png_set_sig_bytes); DEF_IMGLIB_FN (png_read_info); DEF_IMGLIB_FN (png_get_IHDR); @@ -5588,21 +5648,12 @@ DEF_IMGLIB_FN (png_read_end); DEF_IMGLIB_FN (png_error); static int -init_png_functions (void) +init_png_functions (Lisp_Object libraries) { HMODULE library; - /* Ensure zlib is loaded. Try debug version first. */ - if (!LoadLibrary ("zlibd.dll") - && !LoadLibrary ("zlib.dll")) - return 0; - /* Try loading libpng under probable names. */ - if (!(library = LoadLibrary ("libpng13d.dll")) - && !(library = LoadLibrary ("libpng13.dll")) - && !(library = LoadLibrary ("libpng12d.dll")) - && !(library = LoadLibrary ("libpng12.dll")) - && !(library = LoadLibrary ("libpng.dll"))) + if (!(library = w32_delayed_load (libraries, Qpng))) return 0; LOAD_IMGLIB_FN (library, png_get_io_ptr); @@ -5611,7 +5662,6 @@ init_png_functions (void) LOAD_IMGLIB_FN (library, png_create_info_struct); LOAD_IMGLIB_FN (library, png_destroy_read_struct); LOAD_IMGLIB_FN (library, png_set_read_fn); - LOAD_IMGLIB_FN (library, png_init_io); LOAD_IMGLIB_FN (library, png_set_sig_bytes); LOAD_IMGLIB_FN (library, png_read_info); LOAD_IMGLIB_FN (library, png_get_IHDR); @@ -5637,7 +5687,6 @@ init_png_functions (void) #define fn_png_create_info_struct png_create_info_struct #define fn_png_destroy_read_struct png_destroy_read_struct #define fn_png_set_read_fn png_set_read_fn -#define fn_png_init_io png_init_io #define fn_png_set_sig_bytes png_set_sig_bytes #define fn_png_read_info png_read_info #define fn_png_get_IHDR png_get_IHDR @@ -5693,12 +5742,6 @@ struct png_memory_storage PNG_PTR is a pointer to the PNG control structure. Copy LENGTH bytes from the input to DATA. */ -#ifdef _MSC_VER - /* Work around a problem with MinGW builds of graphics libraries - not honoring calling conventions. */ -#pragma optimize("g", off) -#endif - static void png_read_from_memory (png_ptr, data, length) png_structp png_ptr; @@ -5715,10 +5758,23 @@ png_read_from_memory (png_ptr, data, length) tbr->index = tbr->index + length; } -#ifdef _MSC_VER -/* Restore normal optimization, as specified on the command line. */ -#pragma optimize("", on) -#endif + +/* Function set as reader function when reading PNG image from a file. + PNG_PTR is a pointer to the PNG control structure. Copy LENGTH + bytes from the input to DATA. */ + +static void +png_read_from_file (png_ptr, data, length) + png_structp png_ptr; + png_bytep data; + png_size_t length; +{ + FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr); + + if (fread (data, 1, length, fp) < length) + fn_png_error (png_ptr, "Read error"); +} + /* Load PNG image IMG for use on frame F. Value is non-zero if successful. */ @@ -5803,9 +5859,11 @@ png_load (f, img) tbr.bytes += sizeof (sig); } - /* Initialize read and info structs for PNG lib. */ - png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, - my_png_error, my_png_warning); + /* Initialize read and info structs for PNG lib. Casting return + value avoids a GCC warning on W32. */ + png_ptr = (png_structp)fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, + NULL, my_png_error, + my_png_warning); if (!png_ptr) { if (fp) fclose (fp); @@ -5813,7 +5871,8 @@ png_load (f, img) return 0; } - info_ptr = fn_png_create_info_struct (png_ptr); + /* Casting return value avoids a GCC warning on W32. */ + info_ptr = (png_infop)fn_png_create_info_struct (png_ptr); if (!info_ptr) { fn_png_destroy_read_struct (&png_ptr, NULL, NULL); @@ -5822,7 +5881,8 @@ png_load (f, img) return 0; } - end_info = fn_png_create_info_struct (png_ptr); + /* Casting return value avoids a GCC warning on W32. */ + end_info = (png_infop)fn_png_create_info_struct (png_ptr); if (!end_info) { fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); @@ -5849,7 +5909,7 @@ png_load (f, img) if (!NILP (specified_data)) fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); else - fn_png_init_io (png_ptr, fp); + fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file); fn_png_set_sig_bytes (png_ptr, sizeof sig); fn_png_read_info (png_ptr, info_ptr); @@ -6095,8 +6155,9 @@ png_load (f, img) img->width = width; img->height = height; - /* Maybe fill in the background field while we have ximg handy. */ - IMAGE_BACKGROUND (img, f, ximg); + /* Maybe fill in the background field while we have ximg handy. + Casting avoids a GCC warning. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); @@ -6105,9 +6166,9 @@ png_load (f, img) /* Same for the mask. */ if (mask_img) { - /* Fill in the background_transparent field while we have the mask - handy. */ - image_background_transparent (img, f, mask_img); + /* Fill in the background_transparent field while we have the + mask handy. Casting avoids a GCC warning. */ + image_background_transparent (img, f, (XImagePtr_or_DC)mask_img); x_put_x_image (f, mask_img, img->mask, img->width, img->height); x_destroy_x_image (mask_img); @@ -6224,6 +6285,12 @@ jpeg_image_p (object) #undef HAVE_STDLIB_H #endif /* HAVE_STLIB_H */ +#if defined (HAVE_NTGUI) && !defined (__WIN32__) +/* In older releases of the jpeg library, jpeglib.h will define boolean + differently depending on __WIN32__, so make sure it is defined. */ +#define __WIN32__ 1 +#endif + #include #include #include @@ -6246,13 +6313,11 @@ DEF_IMGLIB_FN (jpeg_std_error); DEF_IMGLIB_FN (jpeg_resync_to_restart); static int -init_jpeg_functions (void) +init_jpeg_functions (Lisp_Object libraries) { HMODULE library; - if (!(library = LoadLibrary ("libjpeg.dll")) - && !(library = LoadLibrary ("jpeg-62.dll")) - && !(library = LoadLibrary ("jpeg.dll"))) + if (!(library = w32_delayed_load (libraries, Qjpeg))) return 0; LOAD_IMGLIB_FN (library, jpeg_finish_decompress); @@ -6335,7 +6400,7 @@ our_fill_input_buffer (cinfo) src->next_input_byte = buffer; src->bytes_in_buffer = 2; - return TRUE; + return 1; } @@ -6450,8 +6515,9 @@ jpeg_load (f, img) } /* 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); + error is detected. This function will perform a longjmp. + Casting return value avoids a GCC warning on W32. */ + cinfo.err = (struct jpeg_error_mgr *)fn_jpeg_std_error (&mgr.pub); mgr.pub.error_exit = my_error_exit; if ((rc = setjmp (mgr.setjmp_buffer)) != 0) @@ -6490,11 +6556,11 @@ jpeg_load (f, img) jpeg_memory_src (&cinfo, SDATA (specified_data), SBYTES (specified_data)); - fn_jpeg_read_header (&cinfo, TRUE); + fn_jpeg_read_header (&cinfo, 1); /* Customize decompression so that color quantization will be used. Start decompression. */ - cinfo.quantize_colors = TRUE; + cinfo.quantize_colors = 1; fn_jpeg_start_decompress (&cinfo); width = img->width = cinfo.output_width; height = img->height = cinfo.output_height; @@ -6562,7 +6628,8 @@ jpeg_load (f, img) /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) - IMAGE_BACKGROUND (img, f, ximg); + /* Casting avoids a GCC warning. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); /* Put the image into the pixmap. */ x_put_x_image (f, ximg, img->pixmap, width, height); @@ -6683,11 +6750,11 @@ DEF_IMGLIB_FN (TIFFReadRGBAImage); DEF_IMGLIB_FN (TIFFClose); static int -init_tiff_functions (void) +init_tiff_functions (Lisp_Object libraries) { HMODULE library; - if (!(library = LoadLibrary ("libtiff.dll"))) + if (!(library = w32_delayed_load (libraries, Qtiff))) return 0; LOAD_IMGLIB_FN (library, TIFFSetErrorHandler); @@ -6888,8 +6955,9 @@ tiff_load (f, img) return 0; } - /* Try to open the image file. */ - tiff = fn_TIFFOpen (SDATA (file), "r"); + /* Try to open the image file. Casting return value avoids a + GCC warning on W32. */ + tiff = (TIFF *)fn_TIFFOpen (SDATA (file), "r"); if (tiff == NULL) { image_error ("Cannot open `%s'", file, Qnil); @@ -6904,14 +6972,15 @@ tiff_load (f, img) memsrc.len = SBYTES (specified_data); memsrc.index = 0; - tiff = fn_TIFFClientOpen ("memory_source", "r", &memsrc, - (TIFFReadWriteProc) tiff_read_from_memory, - (TIFFReadWriteProc) tiff_write_from_memory, - tiff_seek_in_memory, - tiff_close_memory, - tiff_size_of_memory, - tiff_mmap_memory, - tiff_unmap_memory); + /* Casting return value avoids a GCC warning on W32. */ + tiff = (TIFF *)fn_TIFFClientOpen ("memory_source", "r", &memsrc, + (TIFFReadWriteProc) tiff_read_from_memory, + (TIFFReadWriteProc) tiff_write_from_memory, + tiff_seek_in_memory, + tiff_close_memory, + tiff_size_of_memory, + tiff_mmap_memory, + tiff_unmap_memory); if (!tiff) { @@ -6974,7 +7043,8 @@ tiff_load (f, img) /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) - IMAGE_BACKGROUND (img, f, ximg); + /* Casting avoids a GCC warning on W32. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); @@ -7082,6 +7152,11 @@ gif_image_p (object) #ifdef HAVE_GIF #if defined (HAVE_NTGUI) || defined (MAC_OS) +/* winuser.h might define DrawText to DrawTextA or DrawTextW. + Undefine before redefining to avoid a preprocessor warning. */ +#ifdef DrawText +#undef DrawText +#endif /* avoid conflict with QuickdrawText.h */ #define DrawText gif_DrawText #include @@ -7103,11 +7178,11 @@ DEF_IMGLIB_FN (DGifOpen); DEF_IMGLIB_FN (DGifOpenFileName); static int -init_gif_functions (void) +init_gif_functions (Lisp_Object libraries) { HMODULE library; - if (!(library = LoadLibrary ("libungif.dll"))) + if (!(library = w32_delayed_load (libraries, Qgif))) return 0; LOAD_IMGLIB_FN (library, DGifCloseFile); @@ -7195,8 +7270,9 @@ gif_load (f, img) return 0; } - /* Open the GIF file. */ - gif = fn_DGifOpenFileName (SDATA (file)); + /* Open the GIF file. Casting return value avoids a GCC warning + on W32. */ + gif = (GifFileType *)fn_DGifOpenFileName (SDATA (file)); if (gif == NULL) { image_error ("Cannot open `%s'", file, Qnil); @@ -7212,7 +7288,8 @@ gif_load (f, img) memsrc.len = SBYTES (specified_data); memsrc.index = 0; - gif = fn_DGifOpen(&memsrc, gif_read_from_memory); + /* Casting return value avoids a GCC warning on W32. */ + gif = (GifFileType *)fn_DGifOpen(&memsrc, gif_read_from_memory); if (!gif) { image_error ("Cannot open memory source `%s'", img->spec, Qnil); @@ -7346,7 +7423,8 @@ gif_load (f, img) /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) - IMAGE_BACKGROUND (img, f, ximg); + /* Casting avoids a GCC warning. */ + IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); /* Put the image into the pixmap, then free the X image and its buffer. */ x_put_x_image (f, ximg, img->pixmap, width, height); @@ -7356,7 +7434,7 @@ gif_load (f, img) return 1; } -#else +#else /* !HAVE_GIF */ #ifdef MAC_OS static int @@ -7509,7 +7587,7 @@ gif_load (f, img) bg_color.blue = color.blue; RGBBackColor (&bg_color); SetGWorld (old_port, old_gdh); - SetMovieActive (movie, TRUE); + SetMovieActive (movie, 1); SetMovieGWorld (movie, ximg, NULL); SampleNumToMediaTime (media, ino + 1, &time, NULL); SetMovieTimeValue (movie, time); @@ -7880,9 +7958,114 @@ 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, + 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 `image-library-alist', which see). */) + (type, libraries) + Lisp_Object type, libraries; +{ + Lisp_Object tested; + + /* Don't try to reload the library. */ + tested = Fassq (type, Vimage_type_cache); + if (CONSP (tested)) + return XCDR (tested); + +#if defined (HAVE_XPM) || defined (MAC_OS) + if (EQ (type, Qxpm)) + return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries); +#endif + +#if defined (HAVE_JPEG) || defined (MAC_OS) + if (EQ (type, Qjpeg)) + return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries); +#endif + +#if defined (HAVE_TIFF) || defined (MAC_OS) + if (EQ (type, Qtiff)) + return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries); +#endif + +#if defined (HAVE_GIF) || defined (MAC_OS) + if (EQ (type, Qgif)) + return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries); +#endif + +#if defined (HAVE_PNG) || defined (MAC_OS) + if (EQ (type, Qpng)) + return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries); +#endif + +#ifdef HAVE_GHOSTSCRIPT + if (EQ (type, Qpostscript)) + return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); +#endif + + /* If the type is not recognized, avoid testing it ever again. */ + CACHE_IMAGE_TYPE (type, Qnil); + return Qnil; +} + void syms_of_image () { + extern Lisp_Object Qrisky_local_variable; /* Syms_of_xdisp has already run. */ + + /* 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. */ + image_types = NULL; + + /* Must be defined now becase we're going to update it below, while + defining the supported image types. */ + DEFVAR_LISP ("image-types", &Vimage_types, + doc: /* List of potentially supported image types. +Each element of the list is a symbol for a image type, like 'jpeg or 'png. +To check whether it is really supported, use `image-type-available-p'. */); + Vimage_types = Qnil; + + DEFVAR_LISP ("image-library-alist", &Vimage_library_alist, + doc: /* Alist of image types vs external libraries needed to display them. + +Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol +representing a supported image type, and the rest are strings giving +alternate filenames for the corresponding external libraries. + +Emacs tries to load the libraries in the order they appear on the +list; if none is loaded, the running session of Emacs won't +support the image type. Types 'pbm and 'xbm don't need to be +listed; they're always supported. */); + Vimage_library_alist = Qnil; + Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt); + + Vimage_type_cache = Qnil; + staticpro (&Vimage_type_cache); + + Qpbm = intern ("pbm"); + staticpro (&Qpbm); + ADD_IMAGE_TYPE(Qpbm); + + Qxbm = intern ("xbm"); + staticpro (&Qxbm); + ADD_IMAGE_TYPE(Qxbm); + + define_image_type (&xbm_type, 1); + define_image_type (&pbm_type, 1); + QCascent = intern (":ascent"); staticpro (&QCascent); QCmargin = intern (":margin"); @@ -7916,6 +8099,7 @@ syms_of_image () Qpostscript = intern ("postscript"); staticpro (&Qpostscript); #ifdef HAVE_GHOSTSCRIPT + ADD_IMAGE_TYPE(Qpostscript); QCloader = intern (":loader"); staticpro (&QCloader); QCbounding_box = intern (":bounding-box"); @@ -7926,37 +8110,37 @@ syms_of_image () staticpro (&QCpt_height); #endif /* HAVE_GHOSTSCRIPT */ - Qpbm = intern ("pbm"); - staticpro (&Qpbm); - - Qxbm = intern ("xbm"); - staticpro (&Qxbm); - #if defined (HAVE_XPM) || defined (MAC_OS) Qxpm = intern ("xpm"); staticpro (&Qxpm); + ADD_IMAGE_TYPE(Qxpm); #endif #if defined (HAVE_JPEG) || defined (MAC_OS) Qjpeg = intern ("jpeg"); staticpro (&Qjpeg); + ADD_IMAGE_TYPE(Qjpeg); #endif #if defined (HAVE_TIFF) || defined (MAC_OS) Qtiff = intern ("tiff"); staticpro (&Qtiff); + ADD_IMAGE_TYPE(Qtiff); #endif #if defined (HAVE_GIF) || defined (MAC_OS) Qgif = intern ("gif"); staticpro (&Qgif); + ADD_IMAGE_TYPE(Qgif); #endif #if defined (HAVE_PNG) || defined (MAC_OS) Qpng = intern ("png"); staticpro (&Qpng); + ADD_IMAGE_TYPE(Qpng); #endif + defsubr (&Sinit_image_library); defsubr (&Sclear_image_cache); defsubr (&Simage_size); defsubr (&Simage_mask_p); @@ -7984,53 +8168,9 @@ meaning don't clear the cache. */); Vimage_cache_eviction_delay = make_number (30 * 60); } - -#ifdef HAVE_NTGUI -/* Image types that rely on external libraries are loaded dynamically - if the library is available. */ -#define IF_LIB_AVAILABLE(init_lib_fn) if (init_lib_fn()) -#else -#define IF_LIB_AVAILABLE(init_func) /* Load unconditionally */ -#endif /* HAVE_NTGUI */ - void init_image () { - image_types = NULL; - Vimage_types = Qnil; - - define_image_type (&xbm_type); - define_image_type (&pbm_type); - -#if defined (HAVE_XPM) || defined (MAC_OS) - IF_LIB_AVAILABLE(init_xpm_functions) - define_image_type (&xpm_type); -#endif - -#if defined (HAVE_JPEG) || defined (MAC_OS) - IF_LIB_AVAILABLE(init_jpeg_functions) - define_image_type (&jpeg_type); -#endif - -#if defined (HAVE_TIFF) || defined (MAC_OS) - IF_LIB_AVAILABLE(init_tiff_functions) - define_image_type (&tiff_type); -#endif - -#if defined (HAVE_GIF) || defined (MAC_OS) - IF_LIB_AVAILABLE(init_gif_functions) - define_image_type (&gif_type); -#endif - -#if defined (HAVE_PNG) || defined (MAC_OS) - IF_LIB_AVAILABLE(init_png_functions) - define_image_type (&png_type); -#endif - -#ifdef HAVE_GHOSTSCRIPT - define_image_type (&gs_type); -#endif - #ifdef MAC_OS /* Animated gifs use QuickTime Movie Toolbox. So initialize it here. */ EnterMovies ();