/* Functions to access the contents of a bitmap, given an id. */
int
-x_bitmap_height (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_height (struct frame *f, ptrdiff_t id)
{
return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height;
}
int
-x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_width (struct frame *f, ptrdiff_t id)
{
return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width;
}
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
ptrdiff_t
-x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_pixmap (struct frame *f, ptrdiff_t id)
{
/* HAVE_NTGUI needs the explicit cast here. */
return (ptrdiff_t) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
#ifdef HAVE_X_WINDOWS
int
-x_bitmap_mask (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_mask (struct frame *f, ptrdiff_t id)
{
return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
}
/* Allocate a new bitmap record. Returns index of new record. */
static ptrdiff_t
-x_allocate_bitmap_record (FRAME_PTR f)
+x_allocate_bitmap_record (struct frame *f)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
ptrdiff_t i;
/* Add one reference to the reference count of the bitmap with id ID. */
void
-x_reference_bitmap (FRAME_PTR f, ptrdiff_t id)
+x_reference_bitmap (struct frame *f, ptrdiff_t id)
{
++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
}
int xhot, yhot, result;
ptrdiff_t id;
Lisp_Object found;
- int fd;
char *filename;
/* Look for an existing bitmap with the same name. */
}
/* Search bitmap-file-path for the file, if appropriate. */
- fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
- if (fd < 0)
+ if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
return -1;
- emacs_close (fd);
filename = SSDATA (found);
/* Remove reference to bitmap with id number ID. */
void
-x_destroy_bitmap (FRAME_PTR f, ptrdiff_t id)
+x_destroy_bitmap (struct frame *f, ptrdiff_t id)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
DEFUN ("image-flush", Fimage_flush, Simage_flush,
1, 2, 0,
- doc: /* Fush the image with specification SPEC on frame FRAME.
+ doc: /* Flush 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.
else
{
file_found = ENCODE_FILE (file_found);
- close (fd);
+ if (fd != -2)
+ emacs_close (fd);
}
return file_found;
unsigned char *buf = NULL;
struct stat st;
- if (fp && fstat (fileno (fp), &st) == 0
- && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
- && (buf = xmalloc (st.st_size),
- fread (buf, 1, st.st_size, fp) == st.st_size))
- {
- *size = st.st_size;
- fclose (fp);
- }
- else
+ if (fp)
{
- if (fp)
- fclose (fp);
- if (buf)
+ ptrdiff_t count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (fclose_unwind, fp);
+
+ if (fstat (fileno (fp), &st) == 0
+ && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
{
- xfree (buf);
- buf = NULL;
+ /* Report an error if we read past the purported EOF.
+ This can happen if the file grows as we read it. */
+ ptrdiff_t buflen = st.st_size;
+ buf = xmalloc (buflen + 1);
+ if (fread (buf, 1, buflen + 1, fp) == buflen)
+ *size = buflen;
+ else
+ {
+ xfree (buf);
+ buf = NULL;
+ }
}
+
+ unbind_to (count, Qnil);
}
return buf;
xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color,
void *closure)
{
- return xpm_lookup_color ((struct frame *) closure, color_name, color);
+ return xpm_lookup_color (closure, color_name, color);
}
static void
png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
{
- struct png_memory_storage *tbr
- = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
+ struct png_memory_storage *tbr = fn_png_get_io_ptr (png_ptr);
if (length > tbr->len - tbr->index)
fn_png_error (png_ptr, "Read error");
static void
png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
{
- FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr);
+ FILE *fp = fn_png_get_io_ptr (png_ptr);
if (fread (data, 1, length, fp) < length)
fn_png_error (png_ptr, "Read error");
if (fread (sig, 1, sizeof sig, fp) != sizeof sig
|| fn_png_sig_cmp (sig, 0, sizeof sig))
{
- image_error ("Not a PNG file: `%s'", file, Qnil);
fclose (fp);
+ image_error ("Not a PNG file: `%s'", file, Qnil);
return 0;
}
}
/* Read image info. */
if (!NILP (specified_data))
- fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
+ fn_png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
else
- fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file);
+ fn_png_set_read_fn (png_ptr, fp, png_read_from_file);
fn_png_set_sig_bytes (png_ptr, sizeof sig);
fn_png_read_info (png_ptr, info_ptr);
static void
our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
{
- struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src;
+ struct jpeg_source_mgr *src = cinfo->src;
if (src)
{
static void
jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
{
- struct jpeg_source_mgr *src;
+ struct jpeg_source_mgr *src = cinfo->src;
- if (cinfo->src == NULL)
+ if (! src)
{
/* First time for this JPEG object? */
- cinfo->src = (struct jpeg_source_mgr *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- sizeof (struct jpeg_source_mgr));
- src = (struct jpeg_source_mgr *) cinfo->src;
+ src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
+ JPOOL_PERMANENT, sizeof *src);
+ cinfo->src = src;
src->next_input_byte = data;
}
- src = (struct jpeg_source_mgr *) cinfo->src;
src->init_source = our_common_init_source;
src->fill_input_buffer = our_memory_fill_input_buffer;
src->skip_input_data = our_memory_skip_input_data;
static void
jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
{
- struct jpeg_stdio_mgr *src;
+ struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src;
- if (cinfo->src != NULL)
- src = (struct jpeg_stdio_mgr *) cinfo->src;
- else
+ if (! src)
{
/* First time for this JPEG object? */
- cinfo->src = (struct jpeg_source_mgr *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
- 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);
+ src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
+ JPOOL_PERMANENT, sizeof *src);
+ cinfo->src = (struct jpeg_source_mgr *) src;
+ src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
+ JPOOL_PERMANENT,
+ JPEG_STDIO_BUFFER_SIZE);
}
src->file = fp;
delay |= ext->Bytes[1];
}
}
- img->lisp_data = Fcons (Qextension_data,
- Fcons (img->lisp_data, Qnil));
+ img->lisp_data = list2 (Qextension_data, img->lisp_data);
if (delay)
img->lisp_data
= Fcons (Qdelay,
IMAGEMAGICK_WIDTH,
IMAGEMAGICK_MAX_HEIGHT,
IMAGEMAGICK_MAX_WIDTH,
+ IMAGEMAGICK_FORMAT,
IMAGEMAGICK_ROTATION,
IMAGEMAGICK_CROP,
IMAGEMAGICK_LAST
{":width", IMAGE_INTEGER_VALUE, 0},
{":max-height", IMAGE_INTEGER_VALUE, 0},
{":max-width", IMAGE_INTEGER_VALUE, 0},
+ {":format", IMAGE_SYMBOL_VALUE, 0},
{":rotation", IMAGE_NUMBER_VALUE, 0},
{":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
};
description = (char *) MagickRelinquishMemory (description);
}
+/* Possibly give ImageMagick some extra help to determine the image
+ type by supplying a "dummy" filename based on the Content-Type. */
+
+static char *
+imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
+{
+ Lisp_Object symbol = intern ("image-format-suffixes");
+ Lisp_Object val = find_symbol_value (symbol);
+ Lisp_Object format;
+
+ if (! CONSP (val))
+ return NULL;
+
+ format = image_spec_value (spec, intern (":format"), NULL);
+ val = Fcar_safe (Fcdr_safe (Fassq (format, val)));
+ if (! STRINGP (val))
+ return NULL;
+
+ /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
+ as ImageMagick would ignore the extra bytes anyway. */
+ snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val));
+ return hint_buffer;
+}
+
/* Helper function for imagemagick_load, which does the actual loading
given contents and size, apart from frame and image structures,
passed from imagemagick_load. Uses librimagemagick to do most of
int desired_width, desired_height;
double rotation;
int pixelwidth;
+ char hint_buffer[MaxTextExtent];
+ char *filename_hint = NULL;
/* 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
ping_wand = NewMagickWand ();
/* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
- status = filename
- ? MagickPingImage (ping_wand, filename)
- : MagickPingImageBlob (ping_wand, contents, size);
+ if (filename)
+ status = MagickPingImage (ping_wand, filename);
+ else
+ {
+ filename_hint = imagemagick_filename_hint (img->spec, hint_buffer);
+ MagickSetFilename (ping_wand, filename_hint);
+ status = MagickPingImageBlob (ping_wand, contents, size);
+ }
if (status == MagickFalse)
{
image_wand = NewMagickWand ();
- if ((filename
- ? MagickReadImage (image_wand, filename)
- : MagickReadImageBlob (image_wand, contents, size))
- == MagickFalse)
+ if (filename)
+ status = MagickReadImage (image_wand, filename);
+ else
+ {
+ MagickSetFilename (image_wand, filename_hint);
+ status = MagickReadImageBlob (image_wand, contents, size);
+ }
+
+ if (status == MagickFalse)
{
imagemagick_error (image_wand);
goto imagemagick_error;
init_color_table ();
-#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+#if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
if (imagemagick_render_type != 0)
{
/* Magicexportimage is normally faster than pixelpushing. This
/* Copy pixels from the imagemagick image structure to the x image map. */
iterator = NewPixelIterator (image_wand);
- if (iterator == (PixelIterator *) NULL)
+ if (! iterator)
{
#ifdef COLOR_TABLE_SUPPORT
free_color_table ();
for (y = 0; y < image_height; y++)
{
pixels = PixelGetNextIteratorRow (iterator, &width);
- if (pixels == (PixelWand **) NULL)
+ if (! pixels)
break;
for (x = 0; x < (long) width; x++)
{
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);
+ Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS);
DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
doc: /* Maximum time after which images are removed from the cache.