/* Functions for image support on window system.
-Copyright (C) 1989, 1992-2013 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#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
}
/* Search bitmap-file-path for the file, if appropriate. */
- if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
+ if (openp (Vx_bitmap_file_path, file, Qnil, &found,
+ make_number (R_OK), false)
+ < 0)
return -1;
filename = SSDATA (found);
return img->background_transparent;
}
+/* 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
+}
+
\f
/***********************************************************************
Helper functions for X image types
XSETINT (errcode, err);
image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
x_destroy_x_image (*ximg);
+ *ximg = NULL;
return 0;
}
Vx_bitmap_file_path);
/* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
- fd = openp (search_path, file, Qnil, &file_found, Qnil);
+ fd = openp (search_path, file, Qnil, &file_found, Qnil, false);
if (fd == -1)
file_found = Qnil;
{
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;
image_error ("Not a PBM image: `%s'", img->spec, Qnil);
error:
xfree (contents);
+ img->pixmap = NO_PIXMAP;
return 0;
}
#endif /* HAVE_PNG || HAVE_NS */
-#ifdef HAVE_PNG
+#if defined HAVE_PNG && !defined HAVE_NS
#ifdef WINDOWSNT
/* PNG library details. */
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 (void, png_longjmp, (png_structp, int)) PNG_NORETURN;
DEF_IMGLIB_FN (jmp_buf *, png_set_longjmp_fn, (png_structp, png_longjmp_ptr, size_t));
#endif /* libpng version >= 1.5 */
#endif /* WINDOWSNT */
-/* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
- Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
- substitute may munge the signal mask, but that should be OK here.
- MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
- the system header setjmp.h; don't mess up that. */
-#ifndef HAVE__SETJMP
-# define _setjmp(j) setjmp (j)
-# define _longjmp longjmp
+/* Fast implementations of setjmp and longjmp. Although setjmp and longjmp
+ will do, POSIX _setjmp and _longjmp (if available) are often faster.
+ Do not use sys_setjmp, as PNG supports only jmp_buf.
+ It's OK if the longjmp substitute restores the signal mask. */
+#ifdef HAVE__SETJMP
+# define FAST_SETJMP(j) _setjmp (j)
+# define FAST_LONGJMP _longjmp
+#else
+# define FAST_SETJMP(j) setjmp (j)
+# define FAST_LONGJMP longjmp
#endif
-#if (PNG_LIBPNG_VER < 10500)
-#define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
+#if PNG_LIBPNG_VER < 10500
+#define PNG_LONGJMP(ptr) FAST_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_LONGJMP(ptr) fn_png_longjmp (ptr, 1)
#define PNG_JMPBUF(ptr) \
- (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf)))
+ (*fn_png_set_longjmp_fn (ptr, FAST_LONGJMP, sizeof (jmp_buf)))
#endif
/* Error and warning handlers installed when the PNG library
/* Set error jump-back. We come back here when the PNG library
detects an error. */
- if (_setjmp (PNG_JMPBUF (png_ptr)))
+ if (FAST_SETJMP (PNG_JMPBUF (png_ptr)))
{
error:
if (c->png_ptr)
/* 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);
}
}
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
MY_JPEG_INVALID_IMAGE_SIZE,
MY_JPEG_CANNOT_CREATE_X
} failure_code;
-#ifdef lint
- FILE *fp;
-#endif
};
{
Lisp_Object file, specified_file;
Lisp_Object specified_data;
- FILE *fp = NULL;
+ /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */
+ FILE * IF_LINT (volatile) fp = NULL;
JSAMPARRAY buffer;
int row_stride, x, y;
XImagePtr ximg = NULL;
return 0;
}
- IF_LINT (mgr->fp = fp);
-
/* Customize libjpeg's error handling to call my_error_exit when an
error is detected. This function will perform a longjmp. */
mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub);
return 0;
}
- /* Silence a bogus diagnostic; see GCC bug 54561. */
- IF_LINT (fp = mgr->fp);
-
/* Create the JPEG decompression object. Let it read from fp.
Read the JPEG image header. */
fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
}
/* Apply the pixel values. */
- if (gif->SavedImages[j].ImageDesc.Interlace)
+ if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
{
int row, pass;
image_error ("ImageMagick error: %s",
build_string (description),
Qnil);
- description = (char *) MagickRelinquishMemory (description);
+ MagickRelinquishMemory (description);
}
/* Possibly give ImageMagick some extra help to determine the image
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;
+ double 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);
{
Qimagemagicktype = intern (imtypes[i]);
typelist = Fcons (Qimagemagicktype, typelist);
+ imtypes[i] = MagickRelinquishMemory (imtypes[i]);
}
+
+ MagickRelinquishMemory (imtypes);
return Fnreverse (typelist);
}
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