#include <config.h>
#include <stdio.h>
-#include <math.h>
#include <unistd.h>
#ifdef HAVE_PNG
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NTGUI
+#include "w32.h"
/* W32_TODO : Color tables on W32. */
#undef COLOR_TABLE_SUPPORT
if (--bm->refcount == 0)
{
- BLOCK_INPUT;
+ block_input ();
free_bitmap_record (dpyinfo, bm);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
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;
+ unblock_input ();
return -1;
}
result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
- UNBLOCK_INPUT;
+ unblock_input ();
if (!result)
{
XDestroyImage (ximg);
}
}
- 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);
/* 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 struct image_type *define_image_type (struct image_type *);
+static struct image_type *lookup_image_type (Lisp_Object);
static void image_error (const char *format, Lisp_Object, 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
-extern Lisp_Object Vlibrary_cache, QCloaded_from;
#define CACHE_IMAGE_TYPE(type, status) \
do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
#else
/* 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;
+ int 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)
+ {
+#ifdef HAVE_NTGUI
+ /* 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;
}
break;
default:
- abort ();
+ emacs_abort ();
break;
}
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 ();
}
/* 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))
{
++windows_or_buffers_changed;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
/* 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;
postprocess_image (f, img);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* We're using IMG, so set its timestamp to `now'. */
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);
static void
x_destroy_x_image (XImagePtr ximg)
{
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
if (ximg)
{
#ifdef HAVE_X_WINDOWS
#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);
xbm_image_p,
xbm_load,
x_clear_image,
+ NULL,
NULL
};
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_xpm_functions (void);
+#else
+#define init_xpm_functions NULL
+#endif
+
/* Structure describing the image type XPM. */
static struct image_type xpm_type =
xpm_image_p,
xpm_load,
x_clear_image,
+ init_xpm_functions,
NULL
};
DEF_IMGLIB_FN (void, XImageFree, (xpm_XImage *));
static int
-init_xpm_functions (Lisp_Object libraries)
+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);
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)
pbm_image_p,
pbm_load,
x_clear_image,
+ NULL,
NULL
};
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_png_functions (void);
+#else
+#define init_png_functions NULL
+#endif
+
/* Structure describing the image type `png'. */
static struct image_type png_type =
png_image_p,
png_load,
x_clear_image,
+ init_png_functions,
NULL
};
#endif /* libpng version >= 1.5 */
static int
-init_png_functions (Lisp_Object libraries)
+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);
#endif /* HAVE_NTGUI */
+/* 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
/* Load PNG image IMG for use on frame F. Value is non-zero if
successful. */
+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 int
-png_load (struct frame *f, struct image *img)
+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_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);
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;
if (fp)
{
fclose (fp);
- fp = NULL;
+ c->fp = NULL;
}
/* Create an image and pixmap serving as mask if the PNG image
#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);
return 1;
}
+static int
+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
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_jpeg_functions (void);
+#else
+#define init_jpeg_functions NULL
+#endif
+
/* Structure describing the image type `jpeg'. */
static struct image_type jpeg_type =
jpeg_image_p,
jpeg_load,
x_clear_image,
+ init_jpeg_functions,
NULL
};
DEF_IMGLIB_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int));
static int
-init_jpeg_functions (Lisp_Object libraries)
+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);
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
};
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);
}
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;
from the JPEG lib. */
static int
-jpeg_load (struct frame *f, struct image *img)
+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;
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);
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;
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);
}
}
/* 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)))
return 1;
}
+static int
+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
{":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_tiff_functions (void);
+#else
+#define init_tiff_functions NULL
+#endif
+
/* Structure describing the image type `tiff'. */
static struct image_type tiff_type =
tiff_image_p,
tiff_load,
x_clear_image,
+ init_tiff_functions,
NULL
};
DEF_IMGLIB_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
static int
-init_tiff_functions (Lisp_Object libraries)
+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);
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_gif_functions (void);
+#else
+#define init_gif_functions NULL
+#endif
+
/* Structure describing the image type `gif'. */
static struct image_type gif_type =
gif_image_p,
gif_load,
gif_clear_image,
+ init_gif_functions,
NULL
};
DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *));
static int
-init_gif_functions (Lisp_Object libraries)
+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);
{":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_imagemagick_functions (void);
+#else
+#define init_imagemagick_functions NULL
+#endif
+
/* Structure describing the image type for any image handled via
ImageMagick. */
imagemagick_image_p,
imagemagick_load,
imagemagick_clear_image,
+ init_imagemagick_functions,
NULL
};
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int 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
};
Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
static int
-init_svg_functions (Lisp_Object libraries)
+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);
gs_image_p,
gs_load,
gs_clear_image,
+ NULL,
NULL
};
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)
{
XImagePtr ximg;
- BLOCK_INPUT;
+ block_input ();
/* Try to get an XImage for img->pixmep. */
ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
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 */
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;
}
void
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");
);
#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);