#include "sysstdio.h"
#include <unistd.h>
-#ifdef HAVE_PNG
-#if defined HAVE_LIBPNG_PNG_H
-# include <libpng/png.h>
-#else
+/* Include this before including <setjmp.h> to work around bugs with
+ older libpng; see Bug#17429. */
+#if defined HAVE_PNG && !defined HAVE_NS
# include <png.h>
#endif
-#endif
#include <setjmp.h>
#include <c-ctype.h>
/* Functions to access the contents of a bitmap, given an id. */
+#ifdef HAVE_X_WINDOWS
static int
x_bitmap_height (struct frame *f, ptrdiff_t id)
{
{
return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width;
}
+#endif
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
ptrdiff_t
c->images[img->id] = NULL;
+ /* Windows NT redefines 'free', but in this file, we need to
+ avoid the redefinition. */
+#ifdef WINDOWSNT
+#undef free
+#endif
/* Free resources, then free IMG. */
img->type->free (f, img);
xfree (img);
return img->background_transparent;
}
-\f
+#if defined (HAVE_PNG) || defined (HAVE_NS) \
+ || defined (HAVE_IMAGEMAGICK) || defined (HAVE_RSVG)
+
+/* Store F's background color into *BGCOLOR. */
+static void
+x_query_frame_background_color (struct frame *f, XColor *bgcolor)
+{
+#ifndef HAVE_NS
+ bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
+ x_query_color (f, bgcolor);
+#else
+ ns_query_color (FRAME_BACKGROUND_COLOR (f), bgcolor, 1);
+#endif
+}
+
+#endif /* HAVE_PNG || HAVE_NS || HAVE_IMAGEMAGICK || HAVE_RSVG */
+
/***********************************************************************
Helper functions for X image types
***********************************************************************/
img->prev = NULL;
c->buckets[i] = img;
}
-
-
-/* Call FN on every image in the image cache of frame F. Used to mark
- Lisp Objects in the image cache. */
-
-/* Mark Lisp objects in image IMG. */
-
-static void
-mark_image (struct image *img)
-{
- mark_object (img->spec);
- mark_object (img->dependencies);
-
- if (!NILP (img->lisp_data))
- mark_object (img->lisp_data);
-}
-
-
-void
-mark_image_cache (struct image_cache *c)
-{
- if (c)
- {
- ptrdiff_t i;
- for (i = 0; i < c->used; ++i)
- if (c->images[i])
- mark_image (c->images[i]);
- }
-}
-
-
\f
/***********************************************************************
X / NS / W32 support code
}
/* Allocate image raster. */
- (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
+ (*ximg)->data = xmalloc_atomic ((*ximg)->bytes_per_line * height);
/* Allocate a pixmap of the same size. */
*pixmap = XCreatePixmap (display, window, width, height, depth);
}
bytes_per_line = (*width + 7) / 8 + padding_p;
nbytes = bytes_per_line * *height;
- p = *data = xmalloc (nbytes);
+ p = *data = xmalloc_atomic (nbytes);
if (v10)
{
#endif /* HAVE_NTGUI */
/* Remember allocated colors. */
- img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
+ img->colors = xnmalloc_atomic (attrs.nalloc_pixels,
+ sizeof *img->colors);
img->ncolors = attrs.nalloc_pixels;
for (i = 0; i < attrs.nalloc_pixels; ++i)
{
{
int i;
- for (i = 0;
- i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0];
- i++)
+ for (i = 0; i < ARRAYELTS (xpm_color_key_strings); i++)
if (strcmp (xpm_color_key_strings[i], s) == 0)
return i;
return -1;
}
else
{
- colors = xmalloc (ct_colors_allocated * sizeof *colors);
+ colors = xmalloc_atomic (ct_colors_allocated * sizeof *colors);
*n = ct_colors_allocated;
for (i = j = 0; i < CT_SIZE; ++i)
#endif /* HAVE_PNG || HAVE_NS */
-#ifdef HAVE_PNG
+#if defined HAVE_PNG && !defined HAVE_NS
#ifdef WINDOWSNT
/* PNG library details. */
/* png_color_16 *image_bg; */
Lisp_Object specified_bg
= image_spec_value (img->spec, QCbackground, NULL);
- int shift = (bit_depth == 16) ? 0 : 8;
+ XColor color;
- if (STRINGP (specified_bg))
+ /* If the user specified a color, try to use it; if not, use the
+ current frame background, ignoring any default background
+ color set by the image. */
+ if (STRINGP (specified_bg)
+ ? x_defined_color (f, SSDATA (specified_bg), &color, false)
+ : (x_query_frame_background_color (f, &color), true))
/* The user specified `:background', use that. */
{
- XColor color;
- if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
- {
- png_color_16 user_bg;
-
- memset (&user_bg, 0, sizeof user_bg);
- user_bg.red = color.red >> shift;
- user_bg.green = color.green >> shift;
- user_bg.blue = color.blue >> shift;
-
- fn_png_set_background (png_ptr, &user_bg,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
- }
- }
- else
- {
- /* We use the current frame background, ignoring any default
- background color set by the image. */
-#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
- XColor color;
- png_color_16 frame_background;
-
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- x_query_color (f, &color);
-
- memset (&frame_background, 0, sizeof frame_background);
- frame_background.red = color.red >> shift;
- frame_background.green = color.green >> shift;
- frame_background.blue = color.blue >> shift;
-#endif /* HAVE_X_WINDOWS */
+ int shift = bit_depth == 16 ? 0 : 8;
+ png_color_16 bg = { 0 };
+ bg.red = color.red >> shift;
+ bg.green = color.green >> shift;
+ bg.blue = color.blue >> shift;
- fn_png_set_background (png_ptr, &frame_background,
+ fn_png_set_background (png_ptr, &bg,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
}
if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
|| min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
memory_full (SIZE_MAX);
- c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
- c->rows = rows = xmalloc (height * sizeof *rows);
+ c->pixels = pixels = xmalloc_atomic (sizeof *pixels * row_bytes * height);
+ c->rows = rows = xmalloc_atomic (height * sizeof *rows);
for (i = 0; i < height; ++i)
rows[i] = pixels + i * row_bytes;
return png_load_body (f, img, &c);
}
-#else /* HAVE_PNG */
+#elif defined HAVE_NS
-#ifdef HAVE_NS
static bool
png_load (struct frame *f, struct image *img)
{
image_spec_value (img->spec, QCfile, NULL),
image_spec_value (img->spec, QCdata, NULL));
}
-#endif /* HAVE_NS */
-
-#endif /* !HAVE_PNG */
+#endif /* HAVE_NS */
\f
src->mgr.next_input_byte = NULL;
}
-
/* Load image IMG for use on frame F. Patterned after example.c
from the JPEG lib. */
return 0;
}
- buf = xmalloc (sizeof *buf * width * height);
+ buf = xmalloc_atomic (sizeof *buf * width * height);
rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
retval = fn_DGifCloseFile (gif, err);
#else
retval = fn_DGifCloseFile (gif);
+#if GIFLIB_MAJOR >= 5
if (err)
*err = gif->Error;
#endif
+#endif
+ return retval;
}
/* Load GIF image IMG for use on frame F. Value is true if
Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
unsigned long bgcolor = 0;
EMACS_INT idx;
-#if GIFLIB_MAJOR >= 5
int gif_err;
-#endif
if (NILP (specified_data))
{
image_error ("Error closing `%s': %s",
img->spec, build_string (error_text));
#else
- image_error ("Error closing `%s'", img->spec);
+ image_error ("Error closing `%s'", img->spec, Qnil);
#endif
}
specified_bg = image_spec_value (img->spec, QCbackground, NULL);
if (!STRINGP (specified_bg)
|| !x_defined_color (f, SSDATA (specified_bg), &bgcolor, 0))
- {
-#ifndef HAVE_NS
- bgcolor.pixel = FRAME_BACKGROUND_PIXEL (f);
- x_query_color (f, &bgcolor);
-#else
- ns_query_color (FRAME_BACKGROUND_COLOR (f), &bgcolor, 1);
-#endif
- }
+ x_query_frame_background_color (f, &bgcolor);
bg_wand = NewPixelWand ();
PixelSetRed (bg_wand, (double) bgcolor.red / 65535);
#endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
{
size_t image_height;
+ MagickRealType color_scale = 65535.0 / QuantumRange;
/* Try to create a x pixmap to hold the imagemagick pixmap. */
if (!image_create_x_image_and_pixmap (f, img, width, height, 0,
PixelGetMagickColor (pixels[x], &pixel);
XPutPixel (ximg, x, y,
lookup_rgb_color (f,
- pixel.red,
- pixel.green,
- pixel.blue));
+ color_scale * pixel.red,
+ color_scale * pixel.green,
+ color_scale * pixel.blue));
}
}
DestroyPixelIterator (iterator);
ExceptionInfo ex;
char **imtypes;
size_t i;
- Lisp_Object Qimagemagicktype;
GetExceptionInfo(&ex);
imtypes = GetMagickList ("*", &numf, &ex);
for (i = 0; i < numf; i++)
{
- Qimagemagicktype = intern (imtypes[i]);
- typelist = Fcons (Qimagemagicktype, typelist);
+ Lisp_Object imagemagicktype = intern (imtypes[i]);
+ typelist = Fcons (imagemagicktype, typelist);
imtypes[i] = MagickRelinquishMemory (imtypes[i]);
}
DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **));
DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
-DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback, (RsvgHandle *, RsvgSizeFunc, gpointer, GDestroyNotify));
DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
static bool
init_svg_functions (void)
{
- HMODULE library, gdklib, glib, gobject;
+ HMODULE library, gdklib = NULL, glib = NULL, gobject = NULL;
if (!(glib = w32_delayed_load (Qglib))
|| !(gobject = w32_delayed_load (Qgobject))
|| !(gdklib = w32_delayed_load (Qgdk_pixbuf))
|| !(library = w32_delayed_load (Qsvg)))
- return 0;
+ {
+ if (gdklib) FreeLibrary (gdklib);
+ if (gobject) FreeLibrary (gobject);
+ if (glib) FreeLibrary (glib);
+ return 0;
+ }
LOAD_IMGLIB_FN (library, rsvg_handle_new);
LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions);
specified_bg = image_spec_value (img->spec, QCbackground, NULL);
if (!STRINGP (specified_bg)
|| !x_defined_color (f, SSDATA (specified_bg), &background, 0))
- {
-#ifndef HAVE_NS
- background.pixel = FRAME_BACKGROUND_PIXEL (f);
- x_query_color (f, &background);
-#else
- ns_query_color (FRAME_BACKGROUND_COLOR (f), &background, 1);
-#endif
- }
+ x_query_frame_background_color (f, &background);
/* SVG pixmaps specify transparency in the last byte, so right
shift 8 bits to get rid of it, since emacs doesn't support
void
syms_of_image (void)
{
+#include "image.x"
+
/* Initialize this only once; it will be reset before dumping. */
image_types = NULL;
#endif /* HAVE_NTGUI */
#endif /* HAVE_RSVG */
- defsubr (&Sinit_image_library);
-#ifdef HAVE_IMAGEMAGICK
- defsubr (&Simagemagick_types);
-#endif
- defsubr (&Sclear_image_cache);
- defsubr (&Simage_flush);
- defsubr (&Simage_size);
- defsubr (&Simage_mask_p);
- defsubr (&Simage_metadata);
-
-#ifdef GLYPH_DEBUG
- defsubr (&Simagep);
- 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.