/* Functions for image support on window system.
- Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc.
- This file is part of GNU Emacs.
+This file is part of GNU Emacs.
- GNU Emacs is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- GNU Emacs is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
#include <math.h>
#include <ctype.h>
-
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#ifdef HAVE_PNG
#if defined HAVE_LIBPNG_PNG_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. */
+Lisp_Object Qlibpng_version;
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
#define PIX_MASK_DRAW 1
#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
-#define x_defined_color(f, name, color_def, alloc) \
+#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 */
-/* Search path for bitmap files. */
-
-Lisp_Object Vx_bitmap_file_path;
-
/* The symbol `postscript' identifying images of this type. */
Lisp_Object Qpostscript;
#ifdef HAVE_NS
void *bitmap = ns_image_from_XBM (bits, width, height);
if (!bitmap)
- return -1;
+ return -1;
#endif
id = x_allocate_bitmap_record (f);
void *bitmap = ns_image_from_file (file);
if (!bitmap)
- return -1;
+ return -1;
id = x_allocate_bitmap_record (f);
{
if (dpyinfo->bitmaps[id].refcount
&& dpyinfo->bitmaps[id].file
- && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
+ && !strcmp (dpyinfo->bitmaps[id].file, SSDATA (file)))
{
++dpyinfo->bitmaps[id].refcount;
return id + 1;
return -1;
emacs_close (fd);
- filename = (char *) SDATA (found);
+ filename = SSDATA (found);
result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
filename, &width, &height, &bitmap, &xhot, &yhot);
dpyinfo->bitmaps[id - 1].depth = 1;
dpyinfo->bitmaps[id - 1].height = height;
dpyinfo->bitmaps[id - 1].width = width;
- strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
+ strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file));
return id;
#endif /* HAVE_X_WINDOWS */
/***********************************************************************
Image types
-***********************************************************************/
+ ***********************************************************************/
/* Value is the number of elements of vector VECTOR. */
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;
Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic;
-/* Time in seconds after which images should be removed from the cache
- if not displayed. */
-
-Lisp_Object Vimage_cache_eviction_delay;
-
/* Function prototypes. */
static Lisp_Object define_image_type (struct image_type *type, int loaded);
static int x_build_heuristic_mask (struct frame *, struct image *,
Lisp_Object);
-#define CACHE_IMAGE_TYPE(type, status) \
+#define CACHE_IMAGE_TYPE(type, status) \
do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
-#define ADD_IMAGE_TYPE(type) \
+#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
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)))
+ if (NILP (Finit_image_library (symbol, Vdynamic_library_alist)))
return 0; /* unimplemented */
for (type = image_types; type; type = type->next)
\f
/***********************************************************************
Image specifications
-***********************************************************************/
+ ***********************************************************************/
enum image_value_type
- {
- IMAGE_DONT_CHECK_VALUE_TYPE,
- IMAGE_STRING_VALUE,
- IMAGE_STRING_OR_NIL_VALUE,
- IMAGE_SYMBOL_VALUE,
- IMAGE_POSITIVE_INTEGER_VALUE,
- IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
- IMAGE_NON_NEGATIVE_INTEGER_VALUE,
- IMAGE_ASCENT_VALUE,
- IMAGE_INTEGER_VALUE,
- IMAGE_FUNCTION_VALUE,
- IMAGE_NUMBER_VALUE,
- IMAGE_BOOL_VALUE
- };
+{
+ IMAGE_DONT_CHECK_VALUE_TYPE,
+ IMAGE_STRING_VALUE,
+ IMAGE_STRING_OR_NIL_VALUE,
+ IMAGE_SYMBOL_VALUE,
+ IMAGE_POSITIVE_INTEGER_VALUE,
+ IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
+ IMAGE_NON_NEGATIVE_INTEGER_VALUE,
+ IMAGE_ASCENT_VALUE,
+ IMAGE_INTEGER_VALUE,
+ IMAGE_FUNCTION_VALUE,
+ IMAGE_NUMBER_VALUE,
+ IMAGE_BOOL_VALUE
+};
/* Structure used when parsing image specifications. */
/* Find key in KEYWORDS. Error if not found. */
for (i = 0; i < nkeywords; ++i)
- if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0)
+ if (strcmp (keywords[i].name, SSDATA (SYMBOL_NAME (key))) == 0)
break;
if (i == nkeywords)
\f
/***********************************************************************
Image type independent image structures
-***********************************************************************/
+ ***********************************************************************/
static struct image *make_image (Lisp_Object spec, unsigned hash);
static void free_image (struct frame *f, struct image *img);
static int check_image_size (struct frame *f, int width, int height);
#define MAX_IMAGE_SIZE 6.0
-Lisp_Object Vmax_image_size;
-
/* Allocate and return a new image structure for image specification
SPEC. SPEC has a hash value of HASH. */
/* Free resources, then free IMG. */
img->type->free (f, img);
xfree (img);
-
- /* As display glyphs may still be referring to the image ID, we
- must garbage the frame (Bug#6426). */
- SET_FRAME_GARBAGED (f);
}
}
#ifdef HAVE_NTGUI
-#define Destroy_Image(img_dc, prev) \
+#define Destroy_Image(img_dc, prev) \
do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0)
-#define Free_Pixmap(display, pixmap) \
+#define Free_Pixmap(display, pixmap) \
DeleteObject (pixmap)
#elif defined (HAVE_NS)
#else
-#define Destroy_Image(ximg, dummy) \
+#define Destroy_Image(ximg, dummy) \
XDestroyImage (ximg)
-#define Free_Pixmap(display, pixmap) \
+#define Free_Pixmap(display, pixmap) \
XFreePixmap (display, pixmap)
#endif /* !HAVE_NTGUI && !HAVE_NS */
\f
/***********************************************************************
Helper functions for X image types
-***********************************************************************/
+ ***********************************************************************/
static void x_clear_image_1 (struct frame *, struct image *, int,
int, int);
xassert (STRINGP (color_name));
- if (x_defined_color (f, SDATA (color_name), &color, 1))
+ if (x_defined_color (f, SSDATA (color_name), &color, 1))
{
/* This isn't called frequently so we get away with simply
reallocating the color vector to the needed size, here. */
\f
/***********************************************************************
Image Cache
-***********************************************************************/
+ ***********************************************************************/
static struct image *search_image_cache (struct frame *, Lisp_Object, unsigned);
static void cache_image (struct frame *f, struct image *img);
{
struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
if (img)
- free_image (f, img);
+ {
+ free_image (f, img);
+ /* As display glyphs may still be referring to the image ID, we
+ must garbage the frame (Bug#6426). */
+ SET_FRAME_GARBAGED (f);
+ }
}
DEFUN ("image-flush", Fimage_flush, Simage_flush,
1, 2, 0,
doc: /* Fush the image with specification SPEC on frame FRAME.
- This removes the image from the Emacs image cache. If SPEC specifies
- an image file, the next redisplay of this image will read from the
- current contents of that file.
+This removes the image from the Emacs image cache. If SPEC specifies
+an image file, the next redisplay of this image will read from the
+current contents of that file.
FRAME nil or omitted means use the selected frame.
FRAME t means refresh the image on all frames. */)
struct image_cache *c;
struct image *img;
unsigned hash;
- struct gcpro gcpro1;
EMACS_TIME now;
/* F must be a window-system frame, and SPEC must be a valid image
c = FRAME_IMAGE_CACHE (f);
- GCPRO1 (spec);
-
/* Look up SPEC in the hash table of the image cache. */
hash = sxhash (spec, 0);
img = search_image_cache (f, spec, hash);
EMACS_GET_TIME (now);
img->timestamp = EMACS_SECS (now);
- UNGCPRO;
-
/* Value is the image id. */
return img->id;
}
\f
/***********************************************************************
X / NS / W32 support code
-***********************************************************************/
+ ***********************************************************************/
#ifdef HAVE_NTGUI
/* Macro for defining functions that will be loaded from image DLLs. */
-#define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
+#define DEF_IMGLIB_FN(rettype,func,args) rettype (FAR CDECL *fn_##func)args
/* Macro for loading those image functions from the library. */
-#define LOAD_IMGLIB_FN(lib,func) { \
- fn_##func = (void *) GetProcAddress (lib, #func); \
- if (!fn_##func) return 0; \
+#define LOAD_IMGLIB_FN(lib,func) { \
+ fn_##func = (void *) GetProcAddress (lib, #func); \
+ 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 argument LIBRARIES is usually the variable
+ `dynamic-library-alist', which associates a symbol, identifying
+ an external DLL library, 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;
+ the given symbol, or if the library was previously loaded;
else the handle of the DLL. */
static HMODULE
w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
\f
/***********************************************************************
File Handling
-***********************************************************************/
+ ***********************************************************************/
static unsigned char *slurp_file (char *, int *);
x_find_image_file (Lisp_Object file)
{
Lisp_Object file_found, search_path;
- struct gcpro gcpro1, gcpro2;
int fd;
- file_found = Qnil;
/* TODO I think this should use something like image-load-path
instead. Unfortunately, that can contain non-string elements. */
search_path = Fcons (Fexpand_file_name (build_string ("images"),
Vdata_directory),
Vx_bitmap_file_path);
- GCPRO2 (file_found, search_path);
/* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
fd = openp (search_path, file, Qnil, &file_found, Qnil);
close (fd);
}
- UNGCPRO;
return file_found;
}
\f
/***********************************************************************
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_image_p (Lisp_Object object);
static int xbm_read_bitmap_data (struct frame *f,
unsigned char *, unsigned char *,
- int *, int *, unsigned char **, int);
+ int *, int *, char **, int);
static int xbm_file_p (Lisp_Object);
/* Indices of image specification fields in xbm_format, below. */
enum xbm_keyword_index
- {
- XBM_TYPE,
- XBM_FILE,
- XBM_WIDTH,
- XBM_HEIGHT,
- XBM_DATA,
- XBM_FOREGROUND,
- XBM_BACKGROUND,
- XBM_ASCENT,
- XBM_MARGIN,
- XBM_RELIEF,
- XBM_ALGORITHM,
- XBM_HEURISTIC_MASK,
- XBM_MASK,
- XBM_LAST
- };
+{
+ XBM_TYPE,
+ XBM_FILE,
+ XBM_WIDTH,
+ XBM_HEIGHT,
+ XBM_DATA,
+ XBM_FOREGROUND,
+ XBM_BACKGROUND,
+ XBM_ASCENT,
+ XBM_MARGIN,
+ XBM_RELIEF,
+ XBM_ALGORITHM,
+ XBM_HEURISTIC_MASK,
+ XBM_MASK,
+ XBM_LAST
+};
/* Vector of image_keyword structures describing the format
of valid XBM image specifications. */
static const struct image_keyword xbm_format[XBM_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":file", IMAGE_STRING_VALUE, 0},
- {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
- {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
- {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
+ {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
+ {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+};
/* Structure describing the image type XBM. */
static struct image_type xbm_type =
- {
- &Qxbm,
- xbm_image_p,
- xbm_load,
- x_clear_image,
- NULL
- };
+{
+ &Qxbm,
+ xbm_image_p,
+ xbm_load,
+ x_clear_image,
+ NULL
+};
/* Tokens returned from xbm_scan. */
enum xbm_token
- {
- XBM_TK_IDENT = 256,
- XBM_TK_NUMBER
- };
+{
+ XBM_TK_IDENT = 256,
+ XBM_TK_NUMBER
+};
/* Return non-zero if OBJECT is a valid XBM-type image specification.
static int
xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *end,
- int *width, int *height, unsigned char **data,
+ int *width, int *height, char **data,
int inhibit_image_error)
{
unsigned char *s = contents;
int padding_p = 0;
int v10 = 0;
int bytes_per_line, i, nbytes;
- unsigned char *p;
+ char *p;
int value;
int LA1;
-#define match() \
- LA1 = xbm_scan (&s, end, buffer, &value)
+#define match() \
+ LA1 = xbm_scan (&s, end, buffer, &value)
-#define expect(TOKEN) \
- if (LA1 != (TOKEN)) \
- goto failure; \
- else \
- match ()
+#define expect(TOKEN) \
+ if (LA1 != (TOKEN)) \
+ goto failure; \
+ else \
+ match ()
#define expect_ident(IDENT) \
- if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
- match (); \
- else \
- goto failure
+ if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
+ match (); \
+ else \
+ goto failure
*width = *height = -1;
if (data)
bytes_per_line = (*width + 7) / 8 + padding_p;
nbytes = bytes_per_line * *height;
- p = *data = (unsigned char *) xmalloc (nbytes);
+ p = *data = (char *) xmalloc (nbytes);
if (v10)
{
unsigned char *end)
{
int rc;
- unsigned char *data;
+ char *data;
int success_p = 0;
rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height,
Lisp_Object file;
unsigned char *contents;
int size;
- struct gcpro gcpro1;
file = x_find_image_file (file_name);
- GCPRO1 (file);
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", file_name, Qnil);
- UNGCPRO;
return 0;
}
- contents = slurp_file (SDATA (file), &size);
+ contents = slurp_file (SSDATA (file), &size);
if (contents == NULL)
{
image_error ("Error loading XBM image `%s'", img->spec, Qnil);
- UNGCPRO;
return 0;
}
success_p = xbm_load_image (f, img, contents, contents + size);
- UNGCPRO;
}
else
{
}
}
else if (STRINGP (data))
- bits = SDATA (data);
+ bits = SSDATA (data);
else
- bits = XBOOL_VECTOR (data)->data;
+ bits = (char *) XBOOL_VECTOR (data)->data;
#ifdef WINDOWSNT
{
\f
/***********************************************************************
XPM images
-***********************************************************************/
+ ***********************************************************************/
#if defined (HAVE_XPM) || defined (HAVE_NS)
/* Indices of image specification fields in xpm_format, below. */
enum xpm_keyword_index
- {
- XPM_TYPE,
- XPM_FILE,
- XPM_DATA,
- XPM_ASCENT,
- XPM_MARGIN,
- XPM_RELIEF,
- XPM_ALGORITHM,
- XPM_HEURISTIC_MASK,
- XPM_MASK,
- XPM_COLOR_SYMBOLS,
- XPM_BACKGROUND,
- XPM_LAST
- };
+{
+ XPM_TYPE,
+ XPM_FILE,
+ XPM_DATA,
+ XPM_ASCENT,
+ XPM_MARGIN,
+ XPM_RELIEF,
+ XPM_ALGORITHM,
+ XPM_HEURISTIC_MASK,
+ XPM_MASK,
+ XPM_COLOR_SYMBOLS,
+ XPM_BACKGROUND,
+ XPM_LAST
+};
/* Vector of image_keyword structures describing the format
of valid XPM image specifications. */
static const struct image_keyword xpm_format[XPM_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":file", IMAGE_STRING_VALUE, 0},
- {":data", IMAGE_STRING_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
/* Structure describing the image type XPM. */
static struct image_type xpm_type =
- {
- &Qxpm,
- xpm_image_p,
- xpm_load,
- x_clear_image,
- NULL
- };
+{
+ &Qxpm,
+ xpm_image_p,
+ xpm_load,
+ x_clear_image,
+ NULL
+};
#ifdef HAVE_X_WINDOWS
/* XPM library details. */
-DEF_IMGLIB_FN (XpmFreeAttributes);
-DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
-DEF_IMGLIB_FN (XpmReadFileToImage);
-DEF_IMGLIB_FN (XImageFree);
+DEF_IMGLIB_FN (void, XpmFreeAttributes, (XpmAttributes *));
+DEF_IMGLIB_FN (int, XpmCreateImageFromBuffer, (Display *, char *, xpm_XImage **,
+ xpm_XImage **, XpmAttributes *));
+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)
#if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
int
-x_create_bitmap_from_xpm_data (struct frame *f, char **bits)
+x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
int id, rc;
attrs.valuemask |= XpmColormap;
rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- bits, &bitmap, &mask, &attrs);
+ (char **) bits, &bitmap, &mask, &attrs);
if (rc != XpmSuccess)
{
XpmFreeAttributes (&attrs);
CONSP (tail);
++i, tail = XCDR (tail))
{
- Lisp_Object name = XCAR (XCAR (tail));
- Lisp_Object color = XCDR (XCAR (tail));
- xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
- strcpy (xpm_syms[i].name, SDATA (name));
- xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
- strcpy (xpm_syms[i].value, SDATA (color));
+ Lisp_Object name;
+ Lisp_Object color;
+
+ if (!CONSP (XCAR (tail)))
+ {
+ xpm_syms[i].name = "";
+ xpm_syms[i].value = "";
+ continue;
+ }
+ name = XCAR (XCAR (tail));
+ color = XCDR (XCAR (tail));
+ if (STRINGP (name))
+ {
+ xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
+ strcpy (xpm_syms[i].name, SSDATA (name));
+ }
+ else
+ xpm_syms[i].name = "";
+ if (STRINGP (color))
+ {
+ xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
+ strcpy (xpm_syms[i].value, SSDATA (color));
+ }
+ else
+ xpm_syms[i].value = "";
}
}
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
+#ifdef ALLOC_XPM_COLORS
+ xpm_free_color_cache ();
+#endif
return 0;
}
&attrs);
#else
rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- SDATA (file), &img->pixmap, &img->mask,
+ SSDATA (file), &img->pixmap, &img->mask,
&attrs);
#endif /* HAVE_NTGUI */
}
else
{
Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
+ if (!STRINGP (buffer))
+ {
+ image_error ("Invalid image data `%s'", buffer, Qnil);
+#ifdef ALLOC_XPM_COLORS
+ xpm_free_color_cache ();
+#endif
+ return 0;
+ }
#ifdef HAVE_NTGUI
/* XpmCreatePixmapFromBuffer is not available in the Windows port
of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
&attrs);
#else
rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- SDATA (buffer),
+ SSDATA (buffer),
&img->pixmap, &img->mask,
&attrs);
#endif /* HAVE_NTGUI */
/* Tokens returned from xpm_scan. */
enum xpm_token
- {
- XPM_TK_IDENT = 256,
- XPM_TK_STRING,
- XPM_TK_EOF
- };
+{
+ XPM_TK_IDENT = 256,
+ XPM_TK_STRING,
+ XPM_TK_EOF
+};
/* Scan an XPM data and return a character (< 256) or a token defined
by enum xpm_token above. *S and END are the start (inclusive) and
*beg = *s - 1;
while (*s < end
&& (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
- ++*s;
+ ++*s;
*len = *s - *beg;
return XPM_TK_IDENT;
}
int best_key, have_mask = 0;
XImagePtr ximg = NULL, mask_img = NULL;
-#define match() \
- LA1 = xpm_scan (&s, end, &beg, &len)
+#define match() \
+ LA1 = xpm_scan (&s, end, &beg, &len)
-#define expect(TOKEN) \
- if (LA1 != (TOKEN)) \
- goto failure; \
- else \
- match ()
+#define expect(TOKEN) \
+ if (LA1 != (TOKEN)) \
+ goto failure; \
+ else \
+ match ()
-#define expect_ident(IDENT) \
- if (LA1 == XPM_TK_IDENT \
- && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
- match (); \
- else \
- goto failure
+#define expect_ident(IDENT) \
+ if (LA1 == XPM_TK_IDENT \
+ && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
+ match (); \
+ else \
+ goto failure
if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
goto failure;
while (num_colors-- > 0)
{
- unsigned char *color, *max_color;
+ char *color, *max_color;
int key, next_key, max_key = 0;
Lisp_Object symbol_color = Qnil, color_val;
XColor cdef;
if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
{
- if (xstrcasecmp (SDATA (XCDR (specified_color)), "None") == 0)
+ if (xstrcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
color_val = Qt;
else if (x_defined_color (f, SDATA (XCDR (specified_color)),
&cdef, 0))
Lisp_Object file;
unsigned char *contents;
int size;
- struct gcpro gcpro1;
file = x_find_image_file (file_name);
- GCPRO1 (file);
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", file_name, Qnil);
- UNGCPRO;
return 0;
}
if (contents == NULL)
{
image_error ("Error loading XPM image `%s'", img->spec, Qnil);
- UNGCPRO;
return 0;
}
success_p = xpm_load_image (f, img, contents, contents + size);
xfree (contents);
- UNGCPRO;
}
else
{
Lisp_Object data;
data = image_spec_value (img->spec, QCdata, NULL);
+ if (!STRINGP (data))
+ {
+ image_error ("Invalid image data `%s'", data, Qnil);
+ return 0;
+ }
success_p = xpm_load_image (f, img, SDATA (data),
SDATA (data) + SBYTES (data));
}
\f
/***********************************************************************
Color table
-***********************************************************************/
+ ***********************************************************************/
#ifdef COLOR_TABLE_SUPPORT
\f
/***********************************************************************
Algorithms
-***********************************************************************/
+ ***********************************************************************/
static XColor *x_to_xcolors (struct frame *, struct image *, int);
static void x_from_xcolors (struct frame *, struct image *, XColor *);
static void XPutPixel (XImagePtr , int, int, COLORREF);
#endif /* HAVE_NTGUI */
-/* Non-zero means draw a cross on images having `:conversion
- disabled'. */
-
-int cross_disabled_images;
-
/* Edge detection matrices for different edge-detection
strategies. */
static int emboss_matrix[9] = {
- /* x - 1 x x + 1 */
- 2, -1, 0, /* y - 1 */
- -1, 0, 1, /* y */
- 0, 1, -2 /* y + 1 */
+ /* x - 1 x x + 1 */
+ 2, -1, 0, /* y - 1 */
+ -1, 0, 1, /* y */
+ 0, 1, -2 /* y + 1 */
};
static int laplace_matrix[9] = {
- /* x - 1 x x + 1 */
- 1, 0, 0, /* y - 1 */
- 0, 0, 0, /* y */
- 0, 0, -1 /* y + 1 */
+ /* x - 1 x x + 1 */
+ 1, 0, 0, /* y - 1 */
+ 0, 0, 0, /* y */
+ 0, 0, -1 /* y + 1 */
};
/* Value is the intensity of the color whose red/green/blue values
\f
/***********************************************************************
PBM (mono, gray, color)
-***********************************************************************/
+ ***********************************************************************/
static int pbm_image_p (Lisp_Object object);
static int pbm_load (struct frame *f, struct image *img);
/* Indices of image specification fields in gs_format, below. */
enum pbm_keyword_index
- {
- PBM_TYPE,
- PBM_FILE,
- PBM_DATA,
- PBM_ASCENT,
- PBM_MARGIN,
- PBM_RELIEF,
- PBM_ALGORITHM,
- PBM_HEURISTIC_MASK,
- PBM_MASK,
- PBM_FOREGROUND,
- PBM_BACKGROUND,
- PBM_LAST
- };
+{
+ PBM_TYPE,
+ PBM_FILE,
+ PBM_DATA,
+ PBM_ASCENT,
+ PBM_MARGIN,
+ PBM_RELIEF,
+ PBM_ALGORITHM,
+ PBM_HEURISTIC_MASK,
+ PBM_MASK,
+ PBM_FOREGROUND,
+ PBM_BACKGROUND,
+ PBM_LAST
+};
/* Vector of image_keyword structures describing the format
of valid user-defined image specifications. */
static const struct image_keyword pbm_format[PBM_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":file", IMAGE_STRING_VALUE, 0},
- {":data", IMAGE_STRING_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
/* Structure describing the image type `pbm'. */
static struct image_type pbm_type =
- {
- &Qpbm,
- pbm_image_p,
- pbm_load,
- x_clear_image,
- NULL
- };
+{
+ &Qpbm,
+ pbm_image_p,
+ pbm_load,
+ x_clear_image,
+ NULL
+};
/* Return non-zero if OBJECT is a valid PBM image specification. */
XImagePtr ximg;
Lisp_Object file, specified_file;
enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
- struct gcpro gcpro1;
unsigned char *contents = NULL;
unsigned char *end, *p;
int size;
specified_file = image_spec_value (img->spec, QCfile, NULL);
- file = Qnil;
- GCPRO1 (file);
if (STRINGP (specified_file))
{
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
return 0;
}
- contents = slurp_file (SDATA (file), &size);
+ contents = slurp_file (SSDATA (file), &size);
if (contents == NULL)
{
image_error ("Error reading `%s'", file, Qnil);
- UNGCPRO;
return 0;
}
{
Lisp_Object data;
data = image_spec_value (img->spec, QCdata, NULL);
+ if (!STRINGP (data))
+ {
+ image_error ("Invalid image data `%s'", data, Qnil);
+ return 0;
+ }
p = SDATA (data);
end = p + SBYTES (data);
}
image_error ("Not a PBM image: `%s'", img->spec, Qnil);
error:
xfree (contents);
- UNGCPRO;
return 0;
}
img->width = width;
img->height = height; */
- UNGCPRO;
xfree (contents);
return 1;
}
\f
/***********************************************************************
PNG
-***********************************************************************/
+ ***********************************************************************/
#if defined (HAVE_PNG) || defined (HAVE_NS)
/* Indices of image specification fields in png_format, below. */
enum png_keyword_index
- {
- PNG_TYPE,
- PNG_DATA,
- PNG_FILE,
- PNG_ASCENT,
- PNG_MARGIN,
- PNG_RELIEF,
- PNG_ALGORITHM,
- PNG_HEURISTIC_MASK,
- PNG_MASK,
- PNG_BACKGROUND,
- PNG_LAST
- };
+{
+ PNG_TYPE,
+ PNG_DATA,
+ PNG_FILE,
+ PNG_ASCENT,
+ PNG_MARGIN,
+ PNG_RELIEF,
+ PNG_ALGORITHM,
+ PNG_HEURISTIC_MASK,
+ PNG_MASK,
+ PNG_BACKGROUND,
+ PNG_LAST
+};
/* Vector of image_keyword structures describing the format
of valid user-defined image specifications. */
static const struct image_keyword png_format[PNG_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":data", IMAGE_STRING_VALUE, 0},
- {":file", IMAGE_STRING_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
/* Structure describing the image type `png'. */
static struct image_type png_type =
- {
- &Qpng,
- png_image_p,
- png_load,
- x_clear_image,
- NULL
- };
+{
+ &Qpng,
+ png_image_p,
+ png_load,
+ x_clear_image,
+ NULL
+};
/* Return non-zero if OBJECT is a valid PNG image specification. */
#ifdef HAVE_NTGUI
/* PNG library details. */
-DEF_IMGLIB_FN (png_get_io_ptr);
-DEF_IMGLIB_FN (png_sig_cmp);
-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_set_sig_bytes);
-DEF_IMGLIB_FN (png_read_info);
-DEF_IMGLIB_FN (png_get_IHDR);
-DEF_IMGLIB_FN (png_get_valid);
-DEF_IMGLIB_FN (png_set_strip_16);
-DEF_IMGLIB_FN (png_set_expand);
-DEF_IMGLIB_FN (png_set_gray_to_rgb);
-DEF_IMGLIB_FN (png_set_background);
-DEF_IMGLIB_FN (png_get_bKGD);
-DEF_IMGLIB_FN (png_read_update_info);
-DEF_IMGLIB_FN (png_get_channels);
-DEF_IMGLIB_FN (png_get_rowbytes);
-DEF_IMGLIB_FN (png_read_image);
-DEF_IMGLIB_FN (png_read_end);
-DEF_IMGLIB_FN (png_error);
+DEF_IMGLIB_FN (png_voidp, png_get_io_ptr, (png_structp));
+DEF_IMGLIB_FN (int, png_sig_cmp, (png_bytep, png_size_t, png_size_t));
+DEF_IMGLIB_FN (png_structp, png_create_read_struct, (png_const_charp, png_voidp,
+ png_error_ptr, png_error_ptr));
+DEF_IMGLIB_FN (png_infop, png_create_info_struct, (png_structp));
+DEF_IMGLIB_FN (void, png_destroy_read_struct, (png_structpp, png_infopp, png_infopp));
+DEF_IMGLIB_FN (void, png_set_read_fn, (png_structp, png_voidp, png_rw_ptr));
+DEF_IMGLIB_FN (void, png_set_sig_bytes, (png_structp, int));
+DEF_IMGLIB_FN (void, png_read_info, (png_structp, png_infop));
+DEF_IMGLIB_FN (png_uint_32, png_get_IHDR, (png_structp, png_infop,
+ png_uint_32 *, png_uint_32 *,
+ int *, int *, int *, int *, int *));
+DEF_IMGLIB_FN (png_uint_32, png_get_valid, (png_structp, png_infop, png_uint_32));
+DEF_IMGLIB_FN (void, png_set_strip_16, (png_structp));
+DEF_IMGLIB_FN (void, png_set_expand, (png_structp));
+DEF_IMGLIB_FN (void, png_set_gray_to_rgb, (png_structp));
+DEF_IMGLIB_FN (void, png_set_background, (png_structp, png_color_16p,
+ int, int, double));
+DEF_IMGLIB_FN (png_uint_32, png_get_bKGD, (png_structp, png_infop, png_color_16p *));
+DEF_IMGLIB_FN (void, png_read_update_info, (png_structp, png_infop));
+DEF_IMGLIB_FN (png_byte, png_get_channels, (png_structp, png_infop));
+DEF_IMGLIB_FN (png_size_t, png_get_rowbytes, (png_structp, png_infop));
+DEF_IMGLIB_FN (void, png_read_image, (png_structp, png_bytepp));
+DEF_IMGLIB_FN (void, png_read_end, (png_structp, png_infop));
+DEF_IMGLIB_FN (void, png_error, (png_structp, png_const_charp));
+
+#if (PNG_LIBPNG_VER >= 10500)
+DEF_IMGLIB_FN (void, png_longjmp, (png_structp, int));
+DEF_IMGLIB_FN (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)
LOAD_IMGLIB_FN (library, png_read_image);
LOAD_IMGLIB_FN (library, png_read_end);
LOAD_IMGLIB_FN (library, png_error);
+
+#if (PNG_LIBPNG_VER >= 10500)
+ LOAD_IMGLIB_FN (library, png_longjmp);
+ LOAD_IMGLIB_FN (library, png_set_longjmp_fn);
+#endif /* libpng version >= 1.5 */
+
return 1;
}
#else
#define fn_png_read_end png_read_end
#define fn_png_error png_error
+#if (PNG_LIBPNG_VER >= 10500)
+#define fn_png_longjmp png_longjmp
+#define fn_png_set_longjmp_fn png_set_longjmp_fn
+#endif /* libpng version >= 1.5 */
+
#endif /* HAVE_NTGUI */
+
+#if (PNG_LIBPNG_VER < 10500)
+#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)))
+#endif
+
/* Error and warning handlers installed when the PNG library
is initialized. */
my_png_error (png_struct *png_ptr, const char *msg)
{
xassert (png_ptr != NULL);
+ /* Avoid compiler warning about deprecated direct access to
+ png_ptr's fields in libpng versions 1.4.x. */
image_error ("PNG error: %s", build_string (msg), Qnil);
- longjmp (png_ptr->jmpbuf, 1);
+ PNG_LONGJMP (png_ptr);
}
Lisp_Object specified_data;
int x, y, i;
XImagePtr ximg, mask_img = NULL;
- struct gcpro gcpro1;
png_struct *png_ptr = NULL;
png_info *info_ptr = NULL, *end_info = NULL;
FILE *volatile fp = NULL;
/* Find out what file to load. */
specified_file = image_spec_value (img->spec, QCfile, NULL);
specified_data = image_spec_value (img->spec, QCdata, NULL);
- file = Qnil;
- GCPRO1 (file);
if (NILP (specified_data))
{
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
return 0;
}
/* Open the image file. */
- fp = fopen (SDATA (file), "rb");
+ fp = fopen (SSDATA (file), "rb");
if (!fp)
{
image_error ("Cannot open image file `%s'", file, Qnil);
- UNGCPRO;
return 0;
}
|| fn_png_sig_cmp (sig, 0, sizeof sig))
{
image_error ("Not a PNG file: `%s'", file, Qnil);
- UNGCPRO;
fclose (fp);
return 0;
}
}
else
{
+ if (!STRINGP (specified_data))
+ {
+ image_error ("Invalid image data `%s'", specified_data, Qnil);
+ return 0;
+ }
+
/* Read from memory. */
tbr.bytes = SDATA (specified_data);
tbr.len = SBYTES (specified_data);
|| fn_png_sig_cmp (tbr.bytes, 0, sizeof sig))
{
image_error ("Not a PNG image: `%s'", img->spec, Qnil);
- UNGCPRO;
return 0;
}
tbr.bytes += sizeof (sig);
}
- /* 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);
+ /* 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);
if (!png_ptr)
{
if (fp) fclose (fp);
- UNGCPRO;
return 0;
}
- /* Casting return value avoids a GCC warning on W32. */
- info_ptr = (png_infop)fn_png_create_info_struct (png_ptr);
+ info_ptr = fn_png_create_info_struct (png_ptr);
if (!info_ptr)
{
fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
if (fp) fclose (fp);
- UNGCPRO;
return 0;
}
- /* Casting return value avoids a GCC warning on W32. */
- end_info = (png_infop)fn_png_create_info_struct (png_ptr);
+ end_info = fn_png_create_info_struct (png_ptr);
if (!end_info)
{
fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
if (fp) fclose (fp);
- UNGCPRO;
return 0;
}
/* Set error jump-back. We come back here when the PNG library
detects an error. */
- if (setjmp (png_ptr->jmpbuf))
+ if (setjmp (PNG_JMPBUF (png_ptr)))
{
error:
if (png_ptr)
xfree (pixels);
xfree (rows);
if (fp) fclose (fp);
- UNGCPRO;
return 0;
}
/* The user specified `:background', use that. */
{
XColor color;
- if (x_defined_color (f, SDATA (specified_bg), &color, 0))
+ if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
{
png_color_16 user_bg;
x_destroy_x_image (mask_img);
}
- UNGCPRO;
return 1;
}
\f
/***********************************************************************
JPEG
-***********************************************************************/
+ ***********************************************************************/
#if defined (HAVE_JPEG) || defined (HAVE_NS)
/* Indices of image specification fields in gs_format, below. */
enum jpeg_keyword_index
- {
- JPEG_TYPE,
- JPEG_DATA,
- JPEG_FILE,
- JPEG_ASCENT,
- JPEG_MARGIN,
- JPEG_RELIEF,
- JPEG_ALGORITHM,
- JPEG_HEURISTIC_MASK,
- JPEG_MASK,
- JPEG_BACKGROUND,
- JPEG_LAST
- };
+{
+ JPEG_TYPE,
+ JPEG_DATA,
+ JPEG_FILE,
+ JPEG_ASCENT,
+ JPEG_MARGIN,
+ JPEG_RELIEF,
+ JPEG_ALGORITHM,
+ JPEG_HEURISTIC_MASK,
+ JPEG_MASK,
+ JPEG_BACKGROUND,
+ JPEG_LAST
+};
/* Vector of image_keyword structures describing the format
of valid user-defined image specifications. */
static const struct image_keyword jpeg_format[JPEG_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":data", IMAGE_STRING_VALUE, 0},
- {":file", IMAGE_STRING_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
/* Structure describing the image type `jpeg'. */
static struct image_type jpeg_type =
- {
- &Qjpeg,
- jpeg_image_p,
- jpeg_load,
- x_clear_image,
- NULL
- };
+{
+ &Qjpeg,
+ jpeg_image_p,
+ jpeg_load,
+ x_clear_image,
+ NULL
+};
/* Return non-zero if OBJECT is a valid JPEG image specification. */
#ifdef HAVE_NTGUI
/* JPEG library details. */
-DEF_IMGLIB_FN (jpeg_CreateDecompress);
-DEF_IMGLIB_FN (jpeg_start_decompress);
-DEF_IMGLIB_FN (jpeg_finish_decompress);
-DEF_IMGLIB_FN (jpeg_destroy_decompress);
-DEF_IMGLIB_FN (jpeg_read_header);
-DEF_IMGLIB_FN (jpeg_read_scanlines);
-DEF_IMGLIB_FN (jpeg_std_error);
-DEF_IMGLIB_FN (jpeg_resync_to_restart);
+DEF_IMGLIB_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
+DEF_IMGLIB_FN (boolean, jpeg_start_decompress, (j_decompress_ptr));
+DEF_IMGLIB_FN (boolean, jpeg_finish_decompress, (j_decompress_ptr));
+DEF_IMGLIB_FN (void, jpeg_destroy_decompress, (j_decompress_ptr));
+DEF_IMGLIB_FN (int, jpeg_read_header, (j_decompress_ptr, boolean));
+DEF_IMGLIB_FN (JDIMENSION, jpeg_read_scanlines, (j_decompress_ptr, JSAMPARRAY, JDIMENSION));
+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)
struct jpeg_stdio_mgr *src;
if (cinfo->src != NULL)
- src = (struct jpeg_stdio_mgr *) cinfo->src;
+ src = (struct jpeg_stdio_mgr *) cinfo->src;
else
{
/* First time for this JPEG object? */
sizeof (struct jpeg_stdio_mgr));
src = (struct jpeg_stdio_mgr *) cinfo->src;
src->buffer = (JOCTET *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- JPEG_STDIO_BUFFER_SIZE);
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ JPEG_STDIO_BUFFER_SIZE);
}
src->file = fp;
int rc;
unsigned long *colors;
int width, height;
- struct gcpro gcpro1;
/* Open the JPEG file. */
specified_file = image_spec_value (img->spec, QCfile, NULL);
specified_data = image_spec_value (img->spec, QCdata, NULL);
- file = Qnil;
- GCPRO1 (file);
if (NILP (specified_data))
{
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
return 0;
}
- fp = fopen (SDATA (file), "rb");
+ fp = fopen (SSDATA (file), "rb");
if (fp == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
- UNGCPRO;
return 0;
}
}
+ else if (!STRINGP (specified_data))
+ {
+ image_error ("Invalid image data `%s'", specified_data, Qnil);
+ return 0;
+ }
/* Customize libjpeg's error handling to call my_error_exit when an
- 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);
+ 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)
/* Free pixmap and colors. */
x_clear_image (f, img);
-
- UNGCPRO;
return 0;
}
/* Create the JPEG decompression object. Let it read from fp.
- Read the JPEG image header. */
+ Read the JPEG image header. */
fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
if (NILP (specified_data))
fn_jpeg_read_header (&cinfo, 1);
/* Customize decompression so that color quantization will be used.
- Start decompression. */
+ Start decompression. */
cinfo.quantize_colors = 1;
fn_jpeg_start_decompress (&cinfo);
width = img->width = cinfo.output_width;
/* Put the image into the pixmap. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
- UNGCPRO;
return 1;
}
\f
/***********************************************************************
TIFF
-***********************************************************************/
+ ***********************************************************************/
#if defined (HAVE_TIFF) || defined (HAVE_NS)
/* Indices of image specification fields in tiff_format, below. */
enum tiff_keyword_index
- {
- TIFF_TYPE,
- TIFF_DATA,
- TIFF_FILE,
- TIFF_ASCENT,
- TIFF_MARGIN,
- TIFF_RELIEF,
- TIFF_ALGORITHM,
- TIFF_HEURISTIC_MASK,
- TIFF_MASK,
- TIFF_BACKGROUND,
- TIFF_INDEX,
- TIFF_LAST
- };
+{
+ TIFF_TYPE,
+ TIFF_DATA,
+ TIFF_FILE,
+ TIFF_ASCENT,
+ TIFF_MARGIN,
+ TIFF_RELIEF,
+ TIFF_ALGORITHM,
+ TIFF_HEURISTIC_MASK,
+ TIFF_MASK,
+ TIFF_BACKGROUND,
+ TIFF_INDEX,
+ TIFF_LAST
+};
/* Vector of image_keyword structures describing the format
of valid user-defined image specifications. */
static const struct image_keyword tiff_format[TIFF_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":data", IMAGE_STRING_VALUE, 0},
- {":file", IMAGE_STRING_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
- {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
+};
/* Structure describing the image type `tiff'. */
static struct image_type tiff_type =
- {
- &Qtiff,
- tiff_image_p,
- tiff_load,
- x_clear_image,
- NULL
- };
+{
+ &Qtiff,
+ tiff_image_p,
+ tiff_load,
+ x_clear_image,
+ NULL
+};
/* Return non-zero if OBJECT is a valid TIFF image specification. */
#ifdef HAVE_NTGUI
/* TIFF library details. */
-DEF_IMGLIB_FN (TIFFSetErrorHandler);
-DEF_IMGLIB_FN (TIFFSetWarningHandler);
-DEF_IMGLIB_FN (TIFFOpen);
-DEF_IMGLIB_FN (TIFFClientOpen);
-DEF_IMGLIB_FN (TIFFGetField);
-DEF_IMGLIB_FN (TIFFReadRGBAImage);
-DEF_IMGLIB_FN (TIFFClose);
-DEF_IMGLIB_FN (TIFFSetDirectory);
+DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
+DEF_IMGLIB_FN (TIFFErrorHandler, TIFFSetWarningHandler, (TIFFErrorHandler));
+DEF_IMGLIB_FN (TIFF *, TIFFOpen, (const char *, const char *));
+DEF_IMGLIB_FN (TIFF *, TIFFClientOpen, (const char *, const char *, thandle_t,
+ TIFFReadWriteProc, TIFFReadWriteProc,
+ TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
+ TIFFMapFileProc, TIFFUnmapFileProc));
+DEF_IMGLIB_FN (int, TIFFGetField, (TIFF *, ttag_t, ...));
+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)
size_t len;
int index;
}
- tiff_memory_source;
+tiff_memory_source;
static size_t
tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
uint32 *buf;
int rc, rc2;
XImagePtr ximg;
- struct gcpro gcpro1;
tiff_memory_source memsrc;
Lisp_Object image;
specified_file = image_spec_value (img->spec, QCfile, NULL);
specified_data = image_spec_value (img->spec, QCdata, NULL);
- file = Qnil;
- GCPRO1 (file);
fn_TIFFSetErrorHandler (tiff_error_handler);
fn_TIFFSetWarningHandler (tiff_warning_handler);
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
return 0;
}
- /* Try to open the image file. Casting return value avoids a
- GCC warning on W32. */
- tiff = (TIFF *)fn_TIFFOpen (SDATA (file), "r");
+ /* Try to open the image file. */
+ tiff = fn_TIFFOpen (SSDATA (file), "r");
if (tiff == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
- UNGCPRO;
return 0;
}
}
else
{
+ if (!STRINGP (specified_data))
+ {
+ image_error ("Invalid image data `%s'", specified_data, Qnil);
+ return 0;
+ }
+
/* Memory source! */
memsrc.bytes = SDATA (specified_data);
memsrc.len = SBYTES (specified_data);
memsrc.index = 0;
- /* 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);
+ tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&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)
{
image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
- UNGCPRO;
return 0;
}
}
image_error ("Invalid image number `%s' in image `%s'",
image, img->spec);
fn_TIFFClose (tiff);
- UNGCPRO;
return 0;
}
}
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
fn_TIFFClose (tiff);
- UNGCPRO;
return 0;
}
{
image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
xfree (buf);
- UNGCPRO;
return 0;
}
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
{
xfree (buf);
- UNGCPRO;
return 0;
}
x_destroy_x_image (ximg);
xfree (buf);
- UNGCPRO;
return 1;
}
\f
/***********************************************************************
GIF
-***********************************************************************/
+ ***********************************************************************/
#if defined (HAVE_GIF) || defined (HAVE_NS)
/* Indices of image specification fields in gif_format, below. */
enum gif_keyword_index
- {
- GIF_TYPE,
- GIF_DATA,
- GIF_FILE,
- GIF_ASCENT,
- GIF_MARGIN,
- GIF_RELIEF,
- GIF_ALGORITHM,
- GIF_HEURISTIC_MASK,
- GIF_MASK,
- GIF_IMAGE,
- GIF_BACKGROUND,
- GIF_LAST
- };
+{
+ GIF_TYPE,
+ GIF_DATA,
+ GIF_FILE,
+ GIF_ASCENT,
+ GIF_MARGIN,
+ GIF_RELIEF,
+ GIF_ALGORITHM,
+ GIF_HEURISTIC_MASK,
+ GIF_MASK,
+ GIF_IMAGE,
+ GIF_BACKGROUND,
+ GIF_LAST
+};
/* Vector of image_keyword structures describing the format
of valid user-defined image specifications. */
static const struct image_keyword gif_format[GIF_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":data", IMAGE_STRING_VALUE, 0},
- {":file", IMAGE_STRING_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
/* Structure describing the image type `gif'. */
static struct image_type gif_type =
- {
- &Qgif,
- gif_image_p,
- gif_load,
- gif_clear_image,
- NULL
- };
+{
+ &Qgif,
+ gif_image_p,
+ gif_load,
+ gif_clear_image,
+ NULL
+};
/* Free X resources of GIF image IMG which is used on frame F. */
#ifdef HAVE_NTGUI
/* GIF library details. */
-DEF_IMGLIB_FN (DGifCloseFile);
-DEF_IMGLIB_FN (DGifSlurp);
-DEF_IMGLIB_FN (DGifOpen);
-DEF_IMGLIB_FN (DGifOpenFileName);
+DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
+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)
size_t len;
int index;
}
- gif_memory_source;
+gif_memory_source;
/* Make the current memory source available to gif_read_from_memory.
It's done this way because not all versions of libungif support
static const int interlace_start[] = {0, 4, 2, 1};
static const int interlace_increment[] = {8, 8, 4, 2};
+#define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
+
static int
gif_load (struct frame *f, struct image *img)
{
Lisp_Object file, specified_file;
Lisp_Object specified_data;
int rc, width, height, x, y, i;
+ boolean transparent_p;
XImagePtr ximg;
ColorMapObject *gif_color_map;
unsigned long pixel_colors[256];
GifFileType *gif;
- struct gcpro gcpro1;
Lisp_Object image;
int ino, image_height, image_width;
gif_memory_source memsrc;
unsigned char *raster;
+ unsigned int transparency_color_index;
specified_file = image_spec_value (img->spec, QCfile, NULL);
specified_data = image_spec_value (img->spec, QCdata, NULL);
- file = Qnil;
- GCPRO1 (file);
if (NILP (specified_data))
{
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
return 0;
}
- /* Open the GIF file. Casting return value avoids a GCC warning
- on W32. */
- gif = (GifFileType *)fn_DGifOpenFileName (SDATA (file));
+ /* Open the GIF file. */
+ gif = fn_DGifOpenFileName (SDATA (file));
if (gif == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
- UNGCPRO;
return 0;
}
}
else
{
+ if (!STRINGP (specified_data))
+ {
+ image_error ("Invalid image data `%s'", specified_data, Qnil);
+ return 0;
+ }
+
/* Read from memory! */
current_gif_memory_src = &memsrc;
memsrc.bytes = SDATA (specified_data);
memsrc.len = SBYTES (specified_data);
memsrc.index = 0;
- /* Casting return value avoids a GCC warning on W32. */
- gif = (GifFileType *) fn_DGifOpen (&memsrc, gif_read_from_memory);
+ gif = fn_DGifOpen (&memsrc, gif_read_from_memory);
if (!gif)
{
image_error ("Cannot open memory source `%s'", img->spec, Qnil);
- UNGCPRO;
return 0;
}
}
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
fn_DGifCloseFile (gif);
- UNGCPRO;
return 0;
}
{
image_error ("Error reading `%s'", img->spec, Qnil);
fn_DGifCloseFile (gif);
- UNGCPRO;
return 0;
}
image_error ("Invalid image number `%s' in image `%s'",
image, img->spec);
fn_DGifCloseFile (gif);
- UNGCPRO;
return 0;
}
+ for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++)
+ if ((gif->SavedImages[ino].ExtensionBlocks[i].Function
+ == GIF_LOCAL_DESCRIPTOR_EXTENSION)
+ && gif->SavedImages[ino].ExtensionBlocks[i].ByteCount == 4
+ /* Transparency enabled? */
+ && gif->SavedImages[ino].ExtensionBlocks[i].Bytes[0] & 1)
+ {
+ transparent_p = 1;
+ transparency_color_index
+ = (unsigned char) gif->SavedImages[ino].ExtensionBlocks[i].Bytes[3];
+ }
+
img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top;
img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left;
image_height = gif->SavedImages[ino].ImageDesc.Height;
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
fn_DGifCloseFile (gif);
- UNGCPRO;
return 0;
}
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
{
fn_DGifCloseFile (gif);
- UNGCPRO;
return 0;
}
if (gif_color_map)
for (i = 0; i < gif_color_map->ColorCount; ++i)
{
- int r = gif_color_map->Colors[i].Red << 8;
- int g = gif_color_map->Colors[i].Green << 8;
- int b = gif_color_map->Colors[i].Blue << 8;
- pixel_colors[i] = lookup_rgb_color (f, r, g, b);
+ if (transparent_p && transparency_color_index == i)
+ {
+ Lisp_Object specified_bg
+ = image_spec_value (img->spec, QCbackground, NULL);
+ pixel_colors[i] = STRINGP (specified_bg)
+ ? x_alloc_image_color (f, img, specified_bg,
+ FRAME_BACKGROUND_PIXEL (f))
+ : FRAME_BACKGROUND_PIXEL (f);
+ }
+ else
+ {
+ int r = gif_color_map->Colors[i].Red << 8;
+ int g = gif_color_map->Colors[i].Green << 8;
+ int b = gif_color_map->Colors[i].Blue << 8;
+ pixel_colors[i] = lookup_rgb_color (f, r, g, b);
+ }
}
#ifdef COLOR_TABLE_SUPPORT
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
- UNGCPRO;
return 1;
}
imagemagick
***********************************************************************/
#if defined (HAVE_IMAGEMAGICK)
-Lisp_Object Vimagemagick_render_type;
/* The symbol `imagemagick' identifying images of this type. */
Lisp_Object Qimagemagick;
-Lisp_Object Vimagemagick_render_type;
-
/* Indices of image specification fields in imagemagick_format, below. */
enum imagemagick_keyword_index
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":background", IMAGE_STRING_OR_NIL_VALUE, 0},
- {":height", IMAGE_INTEGER_VALUE, 0},
- {":width", IMAGE_INTEGER_VALUE, 0},
- {":rotation", IMAGE_NUMBER_VALUE, 0},
+ {":height", IMAGE_INTEGER_VALUE, 0},
+ {":width", IMAGE_INTEGER_VALUE, 0},
+ {":rotation", IMAGE_NUMBER_VALUE, 0},
{":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
};
/* Free X resources of imagemagick image IMG which is used on frame F. */
imagemagick_clear_image (struct frame *f,
struct image *img)
{
- printf("clearing imagemagick image\n");
x_clear_image (f, img);
}
imagemagick_image_p (Lisp_Object object)
{
struct image_keyword fmt[IMAGEMAGICK_LAST];
- bcopy (imagemagick_format, fmt, sizeof fmt);
+ memcpy (fmt, imagemagick_format, sizeof fmt);
if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
return 0;
imagemagick_load_image (/* Pointer to emacs frame structure. */
struct frame *f,
/* Pointer to emacs image structure. */
- struct image *img,
+ struct image *img,
/* String containing the IMAGEMAGICK data to
be parsed. */
unsigned char *contents,
contents/size. */
unsigned char *filename)
{
- size_t width;
- size_t height;
+ unsigned long width;
+ unsigned long height;
MagickBooleanType
status;
int y;
MagickWand *image_wand;
- MagickWand *ping_wand;
+ MagickWand *ping_wand;
PixelIterator *iterator;
PixelWand **pixels;
MagickPixelPacket pixel;
Lisp_Object image;
- Lisp_Object value;
+ Lisp_Object value;
Lisp_Object crop, geometry;
long ino;
int desired_width, desired_height;
double rotation;
int imagemagick_rendermethod;
- int pixelwidth;
+ int pixelwidth;
ImageInfo *image_info;
ExceptionInfo *exception;
Image * im_image;
-
+
/* Handle image index for image types who can contain more than one
image. Interface :index is same as for GIF. First we "ping" the
image to see how many sub-images it contains. Pinging is faster
- than loading the image to find out things about it.
- */
- printf("im ping file %s\n", filename);
+ than loading the image to find out things about it. */
+
+ /* `MagickWandGenesis' initializes the imagemagick environment. */
+ MagickWandGenesis ();
image = image_spec_value (img->spec, QCindex, NULL);
ino = INTEGERP (image) ? XFASTINT (image) : 0;
- ping_wand=NewMagickWand();
- MagickSetResolution(ping_wand, 2, 2);
+ ping_wand = NewMagickWand ();
+ MagickSetResolution (ping_wand, 2, 2);
if (filename != NULL)
{
- status = MagickPingImage(ping_wand, filename);
+ status = MagickPingImage (ping_wand, filename);
}
else
{
- status = MagickPingImageBlob(ping_wand, contents, size);
+ status = MagickPingImageBlob (ping_wand, contents, size);
+ }
+
+ if (ino >= MagickGetNumberImages (ping_wand))
+ {
+ image_error ("Invalid image number `%s' in image `%s'",
+ image, img->spec);
+ DestroyMagickWand (ping_wand);
+ return 0;
}
-
- if (ino >= MagickGetNumberImages(ping_wand))
- {
- image_error ("Invalid image number `%s' in image `%s'",
- image, img->spec);
- UNGCPRO;
- return 0;
- }
if (MagickGetNumberImages(ping_wand) > 1)
img->data.lisp_val =
Fcons (Qcount,
- Fcons (make_number (MagickGetNumberImages(ping_wand)),
+ Fcons (make_number (MagickGetNumberImages (ping_wand)),
img->data.lisp_val));
DestroyMagickWand (ping_wand);
+
/* Now, after pinging, we know how many images are inside the
- file. If its not a bundle, just one.
- */
+ file. If its not a bundle, just one. */
if (filename != NULL)
{
- printf("im read file %s\n", filename);
- image_info=CloneImageInfo((ImageInfo *) NULL);
- (void) strcpy(image_info->filename, filename);
- image_info -> number_scenes = 1;
- image_info -> scene = ino;
- exception=AcquireExceptionInfo();
+ image_info = CloneImageInfo ((ImageInfo *) NULL);
+ (void) strcpy (image_info->filename, filename);
+ image_info->number_scenes = 1;
+ image_info->scene = ino;
+ exception = AcquireExceptionInfo ();
- im_image = ReadImage (image_info, exception);
- CatchException(exception);
+ im_image = ReadImage (image_info, exception);
+ DestroyExceptionInfo (exception);
- printf("im wand from image\n");
- image_wand = NewMagickWandFromImage(im_image);
+ if (im_image != NULL)
+ {
+ image_wand = NewMagickWandFromImage (im_image);
+ DestroyImage(im_image);
+ status = MagickTrue;
+ }
+ else
+ status = MagickFalse;
}
else
{
- image_wand = NewMagickWand();
- status = MagickReadImageBlob(image_wand, contents, size);
+ image_wand = NewMagickWand ();
+ status = MagickReadImageBlob (image_wand, contents, size);
}
- image_error ("im read failed", Qnil, Qnil);
- if (status == MagickFalse) goto imagemagick_error;
-
-
- /* if(ino == 0) */
- /* MagickSetFirstIterator(image_wand); */
- /* else */
- /* MagickSetIteratorIndex(image_wand, ino); */
-
- //MagickSetFirstIterator(image_wand);
+ if (status == MagickFalse) goto imagemagick_error;
/* If width and/or height is set in the display spec assume we want
to scale to those values. if either h or w is unspecified, the
unspecified should be calculated from the specified to preserve
- aspect ratio. */
+ aspect ratio. */
value = image_spec_value (img->spec, QCwidth, NULL);
desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
if(desired_width != -1 && desired_height == -1)
{
- /* w known, calculate h*/
- desired_height = ( (double)desired_width / width ) * height;
+ /* w known, calculate h. */
+ desired_height = (double) desired_width / width * height;
}
if(desired_width == -1 && desired_height != -1)
{
- /* h known, calculate w*/
- desired_width = ( (double)desired_height / height ) * width;
- }
+ /* h known, calculate w. */
+ desired_width = (double) desired_height / height * width;
+ }
if(desired_width != -1 && desired_height != -1)
{
- printf("MagickScaleImage %d %d\n", desired_width, desired_height);
- status = MagickScaleImage(image_wand, desired_width, desired_height);
- if (status == MagickFalse) {
- image_error ("Imagemagick scale failed", Qnil, Qnil);
- goto imagemagick_error;
- }
+ status = MagickScaleImage (image_wand, desired_width, desired_height);
+ if (status == MagickFalse)
+ {
+ image_error ("Imagemagick scale failed", Qnil, Qnil);
+ goto imagemagick_error;
+ }
}
/* crop behaves similar to image slicing in Emacs but is more memory
- efficient */
- crop = image_spec_value (img->spec, QCcrop, NULL);
-
- if(CONSP (crop))
- {
- /*
- after some testing, it seems MagickCropImage is the fastest
- crop function in ImageMagick. This crop function seems to do
+ efficient. */
+ crop = image_spec_value (img->spec, QCcrop, NULL);
+
+ if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ {
+ /* After some testing, it seems MagickCropImage is the fastest
+ crop function in ImageMagick. This crop function seems to do
less copying than the alternatives, but it still reads the
entire image into memory before croping, which is aparently
- difficult to avoid when using imagemagick.
- */
-
- int w,h,x,y;
- w=XFASTINT(XCAR(crop));
- h=XFASTINT(XCAR(XCDR(crop)));
- x=XFASTINT(XCAR(XCDR(XCDR(crop))));
- y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop)))));
- printf("MagickCropImage(image_wand, %d,%d, %d,%d)\n", w, h, x, y);
- MagickCropImage(image_wand, w,h, x,y);
- }
-
+ difficult to avoid when using imagemagick. */
+
+ int w, h, x, y;
+ w = XFASTINT (XCAR (crop));
+ crop = XCDR (crop);
+ if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ {
+ h = XFASTINT (XCAR (crop));
+ crop = XCDR (crop);
+ if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ {
+ x = XFASTINT (XCAR (crop));
+ crop = XCDR (crop);
+ if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ {
+ y = XFASTINT (XCAR (crop));
+ MagickCropImage (image_wand, w, h, x, y);
+ }
+ }
+ }
+ }
+
/* Furthermore :rotation. we need background color and angle for
rotation. */
/*
TODO background handling for rotation specified_bg =
image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
- (specified_bg)
- */
+ (specified_bg). */
value = image_spec_value (img->spec, QCrotation, NULL);
if (FLOATP (value))
{
- PixelWand* background = NewPixelWand();
+ PixelWand* background = NewPixelWand ();
PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
-
+
rotation = extract_float (value);
- printf ("MagickRotateImage %f\n", rotation);
-
+
status = MagickRotateImage (image_wand, background, rotation);
DestroyPixelWand (background);
if (status == MagickFalse)
goto imagemagick_error;
}
}
-
+
/* Finaly we are done manipulating the image, figure out resulting
- width, height, and then transfer ownerwship to Emacs.
- */
+ width, height, and then transfer ownerwship to Emacs. */
height = MagickGetImageHeight (image_wand);
width = MagickGetImageWidth (image_wand);
- if (status == MagickFalse)
- {
- image_error ("Imagemagick image get size failed", Qnil, Qnil);
- goto imagemagick_error;
- }
-
+
if (! check_image_size (f, width, height))
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
goto imagemagick_error;
}
-
+
/* We can now get a valid pixel buffer from the imagemagick file, if all
went ok. */
-
init_color_table ();
imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
if (!x_create_x_image_and_pixmap (f, width, height, 0,
&ximg, &img->pixmap))
{
+#ifdef COLOR_TABLE_SUPPORT
+ free_color_table ();
+#endif
image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
goto imagemagick_error;
}
-
+
/* Copy imagegmagick image to x with primitive yet robust pixel
pusher loop. This has been tested a lot with many different
- images.
- */
-
+ images. */
+
/* Copy pixels from the imagemagick image structure to the x image map. */
iterator = NewPixelIterator (image_wand);
- if ((iterator == (PixelIterator *) NULL))
+ if (iterator == (PixelIterator *) NULL)
{
+#ifdef COLOR_TABLE_SUPPORT
+ free_color_table ();
+#endif
+ x_destroy_x_image (ximg);
image_error ("Imagemagick pixel iterator creation failed",
Qnil, Qnil);
goto imagemagick_error;
}
- for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++)
+ for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++)
{
pixels = PixelGetNextIteratorRow (iterator, &width);
- if ((pixels == (PixelWand **) NULL))
+ if (pixels == (PixelWand **) NULL)
break;
for (x = 0; x < (long) width; x++)
{
if (imagemagick_rendermethod == 1)
{
- /* Try if magicexportimage is any faster than pixelpushing. */
+ /* Magicexportimage is normaly faster than pixelpushing. This
+ method is also well tested. Some aspects of this method are
+ ad-hoc and needs to be more researched. */
int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
/* Try to create a x pixmap to hold the imagemagick pixmap. */
- printf("imagedepth:%d exportdepth:%s\n", imagedepth, exportdepth);
if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
- &ximg, &img->pixmap)){
- image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
- goto imagemagick_error;
- }
+ &ximg, &img->pixmap))
+ {
+#ifdef COLOR_TABLE_SUPPORT
+ free_color_table ();
+#endif
+ image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+ goto imagemagick_error;
+ }
+
-
/* Oddly, the below code doesnt seem to work:*/
/* switch(ximg->bitmap_unit){ */
/* case 8: */
seems about 3 times as fast as pixel pushing(not carefully measured)
*/
pixelwidth = CharPixel;/*??? TODO figure out*/
-#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
- MagickExportImagePixels(image_wand,
- 0, 0,
- width, height,
- exportdepth,
- pixelwidth,
- /*&(img->pixmap));*/
- ximg->data);
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+ MagickExportImagePixels (image_wand,
+ 0, 0,
+ width, height,
+ exportdepth,
+ pixelwidth,
+ /*&(img->pixmap));*/
+ ximg->data);
#else
- image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!",
- Qnil, Qnil);
-#endif
+ image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
+ Qnil, Qnil);
+#endif
}
-
+
#ifdef COLOR_TABLE_SUPPORT
/* Remember colors allocated for this image. */
/* Final cleanup. image_wand should be the only resource left. */
DestroyMagickWand (image_wand);
+ /* `MagickWandTerminus' terminates the imagemagick environment. */
+ MagickWandTerminus ();
return 1;
imagemagick_error:
+ DestroyMagickWand (image_wand);
+ MagickWandTerminus ();
/* TODO more cleanup. */
image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
- printf("Imagemagick error, see *Messages*\n");
return 0;
}
if (STRINGP (file_name))
{
Lisp_Object file;
- unsigned char *contents;
- int size;
- struct gcpro gcpro1;
file = x_find_image_file (file_name);
- GCPRO1 (file);
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", file_name, Qnil);
- UNGCPRO;
return 0;
}
- success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name));
- UNGCPRO;
+ success_p = imagemagick_load_image (f, img, 0, 0, SDATA (file));
}
/* Else its not a file, its a lisp object. Load the image from a
lisp object rather than a file. */
Lisp_Object data;
data = image_spec_value (img->spec, QCdata, NULL);
+ if (!STRINGP (data))
+ {
+ image_error ("Invalid image data `%s'", data, Qnil);
+ return 0;
+ }
success_p = imagemagick_load_image (f, img, SDATA (data),
SBYTES (data), NULL);
}
-DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
+DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
doc: /* Return image file types supported by ImageMagick.
- Since ImageMagick recognizes a lot of file-types that clash with Emacs,
- such as .c, we want to be able to alter the list at the lisp level. */)
+Since ImageMagick recognizes a lot of file-types that clash with Emacs,
+such as .c, we want to be able to alter the list at the lisp level. */)
(void)
{
Lisp_Object typelist = Qnil;
- size_t numf;
+ unsigned long numf;
ExceptionInfo ex;
- char** imtypes = GetMagickList ("*", &numf, &ex);
+ char **imtypes = GetMagickList ("*", &numf, &ex);
int i;
Lisp_Object Qimagemagicktype;
for (i = 0; i < numf; i++)
}
return typelist;
}
-
+
#endif /* defined (HAVE_IMAGEMAGICK) */
\f
/***********************************************************************
SVG
-***********************************************************************/
+ ***********************************************************************/
#if defined (HAVE_RSVG)
/* Indices of image specification fields in svg_format, below. */
enum svg_keyword_index
- {
- SVG_TYPE,
- SVG_DATA,
- SVG_FILE,
- SVG_ASCENT,
- SVG_MARGIN,
- SVG_RELIEF,
- SVG_ALGORITHM,
- SVG_HEURISTIC_MASK,
- SVG_MASK,
- SVG_BACKGROUND,
- SVG_LAST
- };
+{
+ SVG_TYPE,
+ SVG_DATA,
+ SVG_FILE,
+ SVG_ASCENT,
+ SVG_MARGIN,
+ SVG_RELIEF,
+ SVG_ALGORITHM,
+ SVG_HEURISTIC_MASK,
+ SVG_MASK,
+ SVG_BACKGROUND,
+ SVG_LAST
+};
/* Vector of image_keyword structures describing the format
of valid user-defined image specifications. */
static const struct image_keyword svg_format[SVG_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":data", IMAGE_STRING_VALUE, 0},
- {":file", IMAGE_STRING_VALUE, 0},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":data", IMAGE_STRING_VALUE, 0},
+ {":file", IMAGE_STRING_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
/* 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. */
- NULL
- };
+{
+ /* 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. */
+ NULL
+};
/* Return non-zero if OBJECT is a valid SVG image specification. Do
#ifdef HAVE_NTGUI
/* SVG library functions. */
-DEF_IMGLIB_FN (rsvg_handle_new);
-DEF_IMGLIB_FN (rsvg_handle_get_dimensions);
-DEF_IMGLIB_FN (rsvg_handle_write);
-DEF_IMGLIB_FN (rsvg_handle_close);
-DEF_IMGLIB_FN (rsvg_handle_get_pixbuf);
-DEF_IMGLIB_FN (rsvg_handle_free);
-
-DEF_IMGLIB_FN (gdk_pixbuf_get_width);
-DEF_IMGLIB_FN (gdk_pixbuf_get_height);
-DEF_IMGLIB_FN (gdk_pixbuf_get_pixels);
-DEF_IMGLIB_FN (gdk_pixbuf_get_rowstride);
-DEF_IMGLIB_FN (gdk_pixbuf_get_colorspace);
-DEF_IMGLIB_FN (gdk_pixbuf_get_n_channels);
-DEF_IMGLIB_FN (gdk_pixbuf_get_has_alpha);
-DEF_IMGLIB_FN (gdk_pixbuf_get_bits_per_sample);
-
-DEF_IMGLIB_FN (g_type_init);
-DEF_IMGLIB_FN (g_object_unref);
-DEF_IMGLIB_FN (g_error_free);
+DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new);
+DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions);
+DEF_IMGLIB_FN (gboolean, rsvg_handle_write);
+DEF_IMGLIB_FN (gboolean, rsvg_handle_close);
+DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf);
+DEF_IMGLIB_FN (void, rsvg_handle_free);
+
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_width);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_height);
+DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride);
+DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels);
+DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha);
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample);
+
+DEF_IMGLIB_FN (void, g_type_init);
+DEF_IMGLIB_FN (void, g_object_unref);
+DEF_IMGLIB_FN (void, g_error_free);
Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
Lisp_Object file;
unsigned char *contents;
int size;
- struct gcpro gcpro1;
file = x_find_image_file (file_name);
- GCPRO1 (file);
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", file_name, Qnil);
- UNGCPRO;
return 0;
}
if (contents == NULL)
{
image_error ("Error loading SVG image `%s'", img->spec, Qnil);
- UNGCPRO;
return 0;
}
/* If the file was slurped into memory properly, parse it. */
success_p = svg_load_image (f, img, contents, size);
xfree (contents);
- UNGCPRO;
}
/* Else its not a file, its a lisp object. Load the image from a
lisp object rather than a file. */
Lisp_Object data;
data = image_spec_value (img->spec, QCdata, NULL);
+ if (!STRINGP (data))
+ {
+ image_error ("Invalid image data `%s'", data, Qnil);
+ return 0;
+ }
success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
}
gnome type library functions. */
fn_g_type_init ();
/* Make a handle to a new rsvg object. */
- rsvg_handle = (RsvgHandle *) fn_rsvg_handle_new ();
+ rsvg_handle = fn_rsvg_handle_new ();
/* Parse the contents argument and fill in the rsvg_handle. */
fn_rsvg_handle_write (rsvg_handle, contents, size, &error);
/* We can now get a valid pixel buffer from the svg file, if all
went ok. */
- pixbuf = (GdkPixbuf *) fn_rsvg_handle_get_pixbuf (rsvg_handle);
+ pixbuf = fn_rsvg_handle_get_pixbuf (rsvg_handle);
if (!pixbuf) goto rsvg_error;
fn_g_object_unref (rsvg_handle);
/* Extract some meta data from the svg handle. */
width = fn_gdk_pixbuf_get_width (pixbuf);
height = fn_gdk_pixbuf_get_height (pixbuf);
- pixels = (const guint8 *) fn_gdk_pixbuf_get_pixels (pixbuf);
+ pixels = fn_gdk_pixbuf_get_pixels (pixbuf);
rowstride = fn_gdk_pixbuf_get_rowstride (pixbuf);
/* Validate the svg meta data. */
\f
/***********************************************************************
Ghostscript
-***********************************************************************/
+ ***********************************************************************/
#ifdef HAVE_X_WINDOWS
#define HAVE_GHOSTSCRIPT 1
/* Indices of image specification fields in gs_format, below. */
enum gs_keyword_index
- {
- GS_TYPE,
- GS_PT_WIDTH,
- GS_PT_HEIGHT,
- GS_FILE,
- GS_LOADER,
- GS_BOUNDING_BOX,
- GS_ASCENT,
- GS_MARGIN,
- GS_RELIEF,
- GS_ALGORITHM,
- GS_HEURISTIC_MASK,
- GS_MASK,
- GS_BACKGROUND,
- GS_LAST
- };
+{
+ GS_TYPE,
+ GS_PT_WIDTH,
+ GS_PT_HEIGHT,
+ GS_FILE,
+ GS_LOADER,
+ GS_BOUNDING_BOX,
+ GS_ASCENT,
+ GS_MARGIN,
+ GS_RELIEF,
+ GS_ALGORITHM,
+ GS_HEURISTIC_MASK,
+ GS_MASK,
+ GS_BACKGROUND,
+ GS_LAST
+};
/* Vector of image_keyword structures describing the format
of valid user-defined image specifications. */
static const struct image_keyword gs_format[GS_LAST] =
- {
- {":type", IMAGE_SYMBOL_VALUE, 1},
- {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE, 1},
- {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE, 1},
- {":file", IMAGE_STRING_VALUE, 1},
- {":loader", IMAGE_FUNCTION_VALUE, 0},
- {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
- {":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
- {":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
- };
+{
+ {":type", IMAGE_SYMBOL_VALUE, 1},
+ {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE, 1},
+ {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE, 1},
+ {":file", IMAGE_STRING_VALUE, 1},
+ {":loader", IMAGE_FUNCTION_VALUE, 0},
+ {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
+ {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":relief", IMAGE_INTEGER_VALUE, 0},
+ {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
+};
/* Structure describing the image type `ghostscript'. */
static struct image_type gs_type =
- {
- &Qpostscript,
- gs_image_p,
- gs_load,
- gs_clear_image,
- NULL
- };
+{
+ &Qpostscript,
+ gs_image_p,
+ gs_load,
+ gs_clear_image,
+ NULL
+};
/* Free X resources of Ghostscript image IMG which is used on frame F. */
{
char buffer[100];
Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
- struct gcpro gcpro1, gcpro2;
Lisp_Object frame;
double in_width, in_height;
Lisp_Object pixel_colors = Qnil;
= 1/72 in, xdpi and ydpi are stored in the frame's X display
info. */
pt_width = image_spec_value (img->spec, QCpt_width, NULL);
- in_width = XFASTINT (pt_width) / 72.0;
+ in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
pt_height = image_spec_value (img->spec, QCpt_height, NULL);
- in_height = XFASTINT (pt_height) / 72.0;
+ in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
if (!check_image_size (f, img->width, img->height))
if successful. We do not record_unwind_protect here because
other places in redisplay like calling window scroll functions
don't either. Let the Lisp loader use `unwind-protect' instead. */
- GCPRO2 (window_and_pixmap_id, pixel_colors);
-
sprintf (buffer, "%lu %lu",
(unsigned long) FRAME_X_WINDOW (f),
(unsigned long) img->pixmap);
make_number (img->height),
window_and_pixmap_id,
pixel_colors);
- UNGCPRO;
return PROCESSP (img->data.lisp_val);
}
\f
/***********************************************************************
Tests
-***********************************************************************/
+ ***********************************************************************/
#if GLYPH_DEBUG
/***********************************************************************
Initialization
-***********************************************************************/
+ ***********************************************************************/
#ifdef HAVE_NTGUI
/* Image types that rely on external libraries are loaded dynamically
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.
+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). */)
+of `dynamic-library-alist', which see). */)
(Lisp_Object type, Lisp_Object libraries)
{
Lisp_Object tested;
#endif
#if defined (HAVE_IMAGEMAGICK)
- if (EQ (type, Qimagemagick)){
- /* MagickWandGenesis() initalizes the imagemagick library. */
- MagickWandGenesis();
- return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
- libraries);
- }
+ if (EQ (type, Qimagemagick))
+ {
+ return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
+ libraries);
+ }
#endif
#ifdef HAVE_GHOSTSCRIPT
return Qnil;
}
-
void
syms_of_image (void)
{
/* 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 an image type, like 'jpeg or 'png.
- To check whether it is really supported, use `image-type-available-p'. */);
+ DEFVAR_LISP ("image-types", Vimage_types,
+ doc: /* List of potentially supported image types.
+Each element of the list is a symbol for an 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 are always supported. */);
- Vimage_library_alist = Qnil;
- Fput (intern_c_string ("image-library-alist"), Qrisky_local_variable, Qt);
-
- DEFVAR_LISP ("max-image-size", &Vmax_image_size,
- doc: /* Maximum size of images.
- Emacs will not load an image into memory if its pixel width or
- pixel height exceeds this limit.
-
- If the value is an integer, it directly specifies the maximum
- image height and width, measured in pixels. If it is a floating
- point number, it specifies the maximum image height and width
- 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. */);
+ DEFVAR_LISP ("max-image-size", Vmax_image_size,
+ doc: /* Maximum size of images.
+Emacs will not load an image into memory if its pixel width or
+pixel height exceeds this limit.
+
+If the value is an integer, it directly specifies the maximum
+image height and width, measured in pixels. If it is a floating
+point number, it specifies the maximum image height and width
+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);
Vimage_type_cache = Qnil;
staticpro (&QCheuristic_mask);
QCindex = intern_c_string (":index");
staticpro (&QCindex);
- QCgeometry = intern (":geometry");
+ QCgeometry = intern_c_string (":geometry");
staticpro (&QCgeometry);
- QCcrop = intern (":crop");
+ QCcrop = intern_c_string (":crop");
staticpro (&QCcrop);
- QCrotation = intern (":rotation");
+ QCrotation = intern_c_string (":rotation");
staticpro (&QCrotation);
QCmatrix = intern_c_string (":matrix");
-
staticpro (&QCmatrix);
QCcolor_adjustment = intern_c_string (":color-adjustment");
staticpro (&QCcolor_adjustment);
staticpro (&QCpt_height);
#endif /* HAVE_GHOSTSCRIPT */
+#ifdef HAVE_NTGUI
+ Qlibpng_version = intern_c_string ("libpng-version");
+ staticpro (&Qlibpng_version);
+ Fset (Qlibpng_version,
+#if HAVE_PNG
+ make_number (PNG_LIBPNG_VER)
+#else
+ make_number (-1)
+#endif
+ );
+#endif
+
#if defined (HAVE_XPM) || defined (HAVE_NS)
Qxpm = intern_c_string ("xpm");
staticpro (&Qxpm);
#endif
#if defined (HAVE_IMAGEMAGICK)
- Qimagemagick = intern ("imagemagick");
+ Qimagemagick = intern_c_string ("imagemagick");
staticpro (&Qimagemagick);
ADD_IMAGE_TYPE (Qimagemagick);
#endif
-
+
#if defined (HAVE_RSVG)
Qsvg = intern_c_string ("svg");
staticpro (&Qsvg);
#endif /* HAVE_RSVG */
defsubr (&Sinit_image_library);
-#ifdef HAVE_IMAGEMAGICK
+#ifdef HAVE_IMAGEMAGICK
defsubr (&Simagemagick_types);
-#endif
+#endif
defsubr (&Sclear_image_cache);
defsubr (&Simage_flush);
defsubr (&Simage_size);
defsubr (&Slookup_image);
#endif
- DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images,
- doc: /* Non-nil means always draw a cross over disabled images.
- Disabled images are those having a `:conversion disabled' property.
- A cross is always drawn on black & white displays. */);
+ DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images,
+ doc: /* Non-nil means always draw a cross over disabled images.
+Disabled images are those having a `:conversion disabled' property.
+A cross is always drawn on black & white displays. */);
cross_disabled_images = 0;
- DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
- doc: /* List of directories to search for window system bitmap files. */);
+ DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
+ doc: /* List of directories to search for window system bitmap files. */);
Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
- DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
- doc: /* Maximum time after which images are removed from the cache.
- When an image has not been displayed this many seconds, Emacs
- automatically removes it from the image cache. If the cache contains
- a large number of images, the actual eviction time may be shorter.
- The value can also be nil, meaning the cache is never cleared.
- The function `clear-image-cache' disregards this variable. */);
+ DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
+ doc: /* Maximum time after which images are removed from the cache.
+When an image has not been displayed this many seconds, Emacs
+automatically removes it from the image cache. If the cache contains
+a large number of images, the actual eviction time may be shorter.
+The value can also be nil, meaning the cache is never cleared.
+
+The function `clear-image-cache' disregards this variable. */);
Vimage_cache_eviction_delay = make_number (300);
-#ifdef HAVE_IMAGEMAGICK
- DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
+#ifdef HAVE_IMAGEMAGICK
+ DEFVAR_LISP ("imagemagick-render-type", Vimagemagick_render_type,
doc: /* Choose between ImageMagick render methods. */);
-#endif
+#endif
}
-
void
init_image (void)
{
-
}
-
-
-
-/* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
- (do not change this comment) */