Auto-generate EXFUN using make-docfile
[bpt/emacs.git] / src / image.c
index 8eb5194..d67faff 100644 (file)
@@ -1,5 +1,6 @@
 /* Functions for image support on window system.
-   Copyright (C) 1989, 1992-2011 Free Software Foundation, Inc.
+
+Copyright (C) 1989, 1992-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -137,7 +138,6 @@ static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
 static void free_color_table (void);
 static unsigned long *colors_in_color_table (int *n);
 #endif
-static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object);
 
 /* Code to deal with bitmaps.  Bitmaps are referenced by their bitmap
    id, which is just an int that this section returns.  Bitmaps are
@@ -521,7 +521,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
        }
     }
 
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
   gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
   XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
             width, height);
@@ -873,7 +873,7 @@ image_spec_value (Lisp_Object spec, Lisp_Object key, int *found)
 {
   Lisp_Object tail;
 
-  xassert (valid_image_p (spec));
+  eassert (valid_image_p (spec));
 
   for (tail = XCDR (spec);
        CONSP (tail) && CONSP (XCDR (tail));
@@ -975,7 +975,7 @@ or omitted means use the selected frame.  */)
 
 static void free_image (struct frame *f, struct image *img);
 
-#define MAX_IMAGE_SIZE 6.0
+#define MAX_IMAGE_SIZE 10.0
 /* Allocate and return a new image structure for image specification
    SPEC.  SPEC has a hash value of HASH.  */
 
@@ -985,11 +985,11 @@ make_image (Lisp_Object spec, EMACS_UINT hash)
   struct image *img = (struct image *) xmalloc (sizeof *img);
   Lisp_Object file = image_spec_value (spec, QCfile, NULL);
 
-  xassert (valid_image_p (spec));
+  eassert (valid_image_p (spec));
   memset (img, 0, sizeof *img);
   img->dependencies = NILP (file) ? Qnil : list1 (file);
   img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
-  xassert (img->type != NULL);
+  eassert (img->type != NULL);
   img->spec = spec;
   img->lisp_data = Qnil;
   img->ascent = DEFAULT_IMAGE_ASCENT;
@@ -1061,11 +1061,8 @@ check_image_size (struct frame *f, int width, int height)
 void
 prepare_image_for_display (struct frame *f, struct image *img)
 {
-  EMACS_TIME t;
-
   /* We're about to display IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (t);
-  img->timestamp = EMACS_SECS (t);
+  EMACS_GET_TIME (img->timestamp);
 
   /* If IMG doesn't have a pixmap yet, load it now, using the image
      type dependent loader function.  */
@@ -1351,7 +1348,7 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
   XColor color;
   unsigned long result;
 
-  xassert (STRINGP (color_name));
+  eassert (STRINGP (color_name));
 
   if (x_defined_color (f, SSDATA (color_name), &color, 1)
       && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
@@ -1463,7 +1460,7 @@ free_image_cache (struct frame *f)
       ptrdiff_t i;
 
       /* Cache should not be referenced by any frame when freed.  */
-      xassert (c->refcount == 0);
+      eassert (c->refcount == 0);
 
       for (i = 0; i < c->used; ++i)
        free_image (f, c->images[i]);
@@ -1513,8 +1510,8 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
       else if (INTEGERP (Vimage_cache_eviction_delay))
        {
          /* Free cache based on timestamp.  */
-         EMACS_TIME t;
-         double old, delay;
+         EMACS_TIME old, t;
+         double delay;
          ptrdiff_t nimages = 0;
 
          for (i = 0; i < c->used; ++i)
@@ -1529,12 +1526,12 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
          delay = max (delay, 1);
 
          EMACS_GET_TIME (t);
-         old = EMACS_SECS (t) - delay;
+         EMACS_SUB_TIME (old, t, EMACS_TIME_FROM_DOUBLE (delay));
 
          for (i = 0; i < c->used; ++i)
            {
              struct image *img = c->images[i];
-             if (img && img->timestamp < old)
+             if (img && EMACS_TIME_LT (img->timestamp, old))
                {
                  free_image (f, img);
                  ++nfreed;
@@ -1707,12 +1704,11 @@ lookup_image (struct frame *f, Lisp_Object spec)
 {
   struct image *img;
   EMACS_UINT hash;
-  EMACS_TIME now;
 
   /* F must be a window-system frame, and SPEC must be a valid image
      specification.  */
-  xassert (FRAME_WINDOW_P (f));
-  xassert (valid_image_p (spec));
+  eassert (FRAME_WINDOW_P (f));
+  eassert (valid_image_p (spec));
 
   /* Look up SPEC in the hash table of the image cache.  */
   hash = sxhash (spec, 0);
@@ -1801,8 +1797,7 @@ lookup_image (struct frame *f, Lisp_Object spec)
     }
 
   /* We're using IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (now);
-  img->timestamp = EMACS_SECS (now);
+  EMACS_GET_TIME (img->timestamp);
 
   /* Value is the image id.  */
   return img->id;
@@ -1951,7 +1946,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
   Window window = FRAME_X_WINDOW (f);
   Screen *screen = FRAME_X_SCREEN (f);
 
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
 
   if (depth <= 0)
     depth = DefaultDepthOfScreen (screen);
@@ -2016,7 +2011,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
   /* Bitmaps with a depth less than 16 need a palette.  */
   /* BITMAPINFO structure already contains the first RGBQUAD.  */
   if (depth < 16)
-    palette_colors = 1 << depth - 1;
+    palette_colors = 1 << (depth - 1);
 
   *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
 
@@ -2089,7 +2084,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
 static void
 x_destroy_x_image (XImagePtr ximg)
 {
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
   if (ximg)
     {
 #ifdef HAVE_X_WINDOWS
@@ -2118,7 +2113,7 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he
 #ifdef HAVE_X_WINDOWS
   GC gc;
 
-  xassert (interrupt_input_blocked);
+  eassert (interrupt_input_blocked);
   gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
   XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
   XFreeGC (FRAME_X_DISPLAY (f), gc);
@@ -2133,7 +2128,7 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he
 #endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
-  xassert (ximg == pixmap);
+  eassert (ximg == pixmap);
   ns_retain_object (ximg);
 #endif
 }
@@ -2323,7 +2318,7 @@ xbm_image_p (Lisp_Object object)
   if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
     return 0;
 
-  xassert (EQ (kw[XBM_TYPE].value, Qxbm));
+  eassert (EQ (kw[XBM_TYPE].value, Qxbm));
 
   if (kw[XBM_FILE].count)
     {
@@ -2365,7 +2360,7 @@ xbm_image_p (Lisp_Object object)
             for one line of the image.  */
          for (i = 0; i < height; ++i)
            {
-             Lisp_Object elt = XVECTOR (data)->contents[i];
+             Lisp_Object elt = AREF (data, i);
 
              if (STRINGP (elt))
                {
@@ -2784,7 +2779,7 @@ xbm_load_image (struct frame *f, struct image *img, unsigned char *contents,
       int non_default_colors = 0;
       Lisp_Object value;
 
-      xassert (img->width > 0 && img->height > 0);
+      eassert (img->width > 0 && img->height > 0);
 
       /* Get foreground and background colors, maybe allocate colors.  */
       value = image_spec_value (img->spec, QCforeground, NULL);
@@ -2844,7 +2839,7 @@ xbm_load (struct frame *f, struct image *img)
   int success_p = 0;
   Lisp_Object file_name;
 
-  xassert (xbm_image_p (img->spec));
+  eassert (xbm_image_p (img->spec));
 
   /* If IMG->spec specifies a file name, create a non-file spec from it.  */
   file_name = image_spec_value (img->spec, QCfile, NULL);
@@ -2890,14 +2885,14 @@ xbm_load (struct frame *f, struct image *img)
       memcpy (fmt, xbm_format, sizeof fmt);
       parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
       (void) parsed_p;
-      xassert (parsed_p);
+      eassert (parsed_p);
 
       /* Get specified width, and height.  */
       if (!in_memory_file_p)
        {
          img->width = XFASTINT (fmt[XBM_WIDTH].value);
          img->height = XFASTINT (fmt[XBM_HEIGHT].value);
-         xassert (img->width > 0 && img->height > 0);
+         eassert (img->width > 0 && img->height > 0);
          if (!check_image_size (f, img->width, img->height))
            {
              image_error ("Invalid image size (see `max-image-size')",
@@ -2938,7 +2933,7 @@ xbm_load (struct frame *f, struct image *img)
              p = bits = (char *) alloca (nbytes * img->height);
              for (i = 0; i < img->height; ++i, p += nbytes)
                {
-                 Lisp_Object line = XVECTOR (data)->contents[i];
+                 Lisp_Object line = AREF (data, i);
                  if (STRINGP (line))
                    memcpy (p, SDATA (line), nbytes);
                  else
@@ -3584,7 +3579,7 @@ xpm_load (struct frame *f, struct image *img)
 
       img->width = attrs.width;
       img->height = attrs.height;
-      xassert (img->width > 0 && img->height > 0);
+      eassert (img->width > 0 && img->height > 0);
 
       /* The call to XpmFreeAttributes below frees attrs.alloc_pixels.  */
 #ifdef HAVE_NTGUI
@@ -3748,7 +3743,7 @@ xpm_put_color_table_v (Lisp_Object color_table,
                        int chars_len,
                        Lisp_Object color)
 {
-  XVECTOR (color_table)->contents[*chars_start] = color;
+  ASET (color_table, *chars_start, color);
 }
 
 static Lisp_Object
@@ -3756,7 +3751,7 @@ xpm_get_color_table_v (Lisp_Object color_table,
                        const unsigned char *chars_start,
                        int chars_len)
 {
-  return XVECTOR (color_table)->contents[*chars_start];
+  return AREF (color_table, *chars_start);
 }
 
 static Lisp_Object
@@ -5552,11 +5547,10 @@ init_png_functions (Lisp_Object libraries)
 /* Error and warning handlers installed when the PNG library
    is initialized.  */
 
-static void my_png_error (png_struct *, const char *) NO_RETURN;
-static void
+static _Noreturn void
 my_png_error (png_struct *png_ptr, const char *msg)
 {
-  xassert (png_ptr != NULL);
+  eassert (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);
@@ -5567,7 +5561,7 @@ my_png_error (png_struct *png_ptr, const char *msg)
 static void
 my_png_warning (png_struct *png_ptr, const char *msg)
 {
-  xassert (png_ptr != NULL);
+  eassert (png_ptr != NULL);
   image_error ("PNG warning: %s", build_string (msg), Qnil);
 }
 
@@ -5837,7 +5831,7 @@ png_load (struct frame *f, struct image *img)
      images with alpha channel, i.e. RGBA.  If conversions above were
      sufficient we should only have 3 or 4 channels here.  */
   channels = fn_png_get_channels (png_ptr, info_ptr);
-  xassert (channels == 3 || channels == 4);
+  eassert (channels == 3 || channels == 4);
 
   /* Number of bytes needed for one row of the image.  */
   row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
@@ -6134,8 +6128,7 @@ struct my_jpeg_error_mgr
 };
 
 
-static void my_error_exit (j_common_ptr) NO_RETURN;
-static void
+static _Noreturn void
 my_error_exit (j_common_ptr cinfo)
 {
   struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
@@ -7553,7 +7546,7 @@ imagemagick_image_p (Lisp_Object object)
 }
 
 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
-   Therefore rename the function so it doesnt collide with ImageMagick.  */
+   Therefore rename the function so it doesn't collide with ImageMagick.  */
 #define DrawRectangle DrawRectangleGif
 #include <wand/MagickWand.h>
 
@@ -7565,6 +7558,22 @@ extern WandExport void PixelGetMagickColor (const PixelWand *,
                                            MagickPixelPacket *);
 #endif
 
+/* Log ImageMagick error message.
+   Useful when a ImageMagick function returns the status `MagickFalse'.  */
+
+static void
+imagemagick_error (MagickWand *wand)
+{
+  char *description;
+  ExceptionType severity;
+
+  description = MagickGetException (wand, &severity);
+  image_error ("ImageMagick error: %s",
+              build_string (description),
+              Qnil);
+  description = (char *) MagickRelinquishMemory (description);
+}
+
 /* 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
@@ -7582,19 +7591,14 @@ imagemagick_load_image (struct frame *f, struct image *img,
                        unsigned char *contents, unsigned int size,
                        char *filename)
 {
-  size_t width;
-  size_t height;
-
+  size_t width, height;
   MagickBooleanType status;
-
   XImagePtr ximg;
-  int x;
-  int y;
-
-  MagickWand  *image_wand;
-  MagickWand  *ping_wand;
+  int x, y;
+  MagickWand *image_wand;
+  MagickWand *ping_wand;
   PixelIterator *iterator;
-  PixelWand  **pixels;
+  PixelWand **pixels, *bg_wand = NULL;
   MagickPixelPacket  pixel;
   Lisp_Object image;
   Lisp_Object value;
@@ -7602,12 +7606,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
   EMACS_INT ino;
   int desired_width, desired_height;
   double rotation;
-  EMACS_INT imagemagick_rendermethod;
   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
@@ -7619,17 +7618,20 @@ imagemagick_load_image (struct frame *f, struct image *img,
   image = image_spec_value (img->spec, QCindex, NULL);
   ino = INTEGERP (image) ? XFASTINT (image) : 0;
   ping_wand = NewMagickWand ();
-  MagickSetResolution (ping_wand, 2, 2);
-  if (filename != NULL)
-    {
-      status = MagickPingImage (ping_wand, filename);
-    }
-  else
+  /* MagickSetResolution (ping_wand, 2, 2);   (Bug#10112)  */
+
+  status = filename
+    ? MagickPingImage (ping_wand, filename)
+    : MagickPingImageBlob (ping_wand, contents, size);
+
+  if (status == MagickFalse)
     {
-      status = MagickPingImageBlob (ping_wand, contents, size);
+      imagemagick_error (ping_wand);
+      DestroyMagickWand (ping_wand);
+      return 0;
     }
 
-  if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand)))
+  if (ino < 0 || ino >= MagickGetNumberImages (ping_wand))
     {
       image_error ("Invalid image number `%s' in image `%s'",
                   image, img->spec);
@@ -7646,36 +7648,46 @@ imagemagick_load_image (struct frame *f, struct image *img,
   DestroyMagickWand (ping_wand);
 
   /* Now we know how many images are inside the file.  If it's not a
-     bundle, the number is one.  */
+     bundle, the number is one.  Load the image data.  */
 
-  if (filename != NULL)
-    {
-      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);
-      DestroyExceptionInfo (exception);
+  image_wand = NewMagickWand ();
 
-      if (im_image == NULL)
-       goto imagemagick_no_wand;
-      image_wand = NewMagickWandFromImage (im_image);
-      DestroyImage (im_image);
-    }
-  else
+  if ((filename
+       ? MagickReadImage (image_wand, filename)
+       : MagickReadImageBlob (image_wand, contents, size))
+      == MagickFalse)
     {
-      image_wand = NewMagickWand ();
-      if (MagickReadImageBlob (image_wand, contents, size) == MagickFalse)
-       goto imagemagick_error;
+      imagemagick_error (image_wand);
+      goto imagemagick_error;
     }
 
+  /* Retrieve the frame's background color, for use later.  */
+  {
+    XColor bgcolor;
+    Lisp_Object specified_bg;
+
+    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
+      }
+
+    bg_wand = NewPixelWand ();
+    PixelSetRed   (bg_wand, (double) bgcolor.red   / 65535);
+    PixelSetGreen (bg_wand, (double) bgcolor.green / 65535);
+    PixelSetBlue  (bg_wand, (double) bgcolor.blue  / 65535);
+  }
+
   /* 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.  */
-
   value = image_spec_value (img->spec, QCwidth, NULL);
   desired_width = (INTEGERP (value)  ? XFASTINT (value) : -1);
   value = image_spec_value (img->spec, QCheight, NULL);
@@ -7696,6 +7708,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
       if (status == MagickFalse)
        {
          image_error ("Imagemagick scale failed", Qnil, Qnil);
+         imagemagick_error (image_wand);
          goto imagemagick_error;
        }
     }
@@ -7740,25 +7753,37 @@ imagemagick_load_image (struct frame *f, struct image *img,
   value = image_spec_value (img->spec, QCrotation, NULL);
   if (FLOATP (value))
     {
-      PixelWand* background = NewPixelWand ();
-      PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
-
       rotation = extract_float (value);
-
-      status = MagickRotateImage (image_wand, background, rotation);
-      DestroyPixelWand (background);
+      status = MagickRotateImage (image_wand, bg_wand, rotation);
       if (status == MagickFalse)
         {
           image_error ("Imagemagick image rotate failed", Qnil, Qnil);
+         imagemagick_error (image_wand);
           goto imagemagick_error;
         }
     }
 
   /* Finally we are done manipulating the image.  Figure out the
-     resulting width/height and transfer ownerwship to Emacs.  */
+     resulting width/height and transfer ownership to Emacs.  */
   height = MagickGetImageHeight (image_wand);
   width = MagickGetImageWidth (image_wand);
 
+  /* Set the canvas background color to the frame or specified
+     background, and flatten the image.  Note: as of ImageMagick
+     6.6.0, SVG image transparency is not handled properly
+     (e.g. etc/images/splash.svg shows a white background always).  */
+  {
+    MagickWand *new_wand;
+    MagickSetImageBackgroundColor (image_wand, bg_wand);
+#ifdef HAVE_MAGICKMERGEIMAGELAYERS
+    new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
+#else
+    new_wand = MagickFlattenImages (image_wand);
+#endif
+    DestroyMagickWand (image_wand);
+    image_wand = new_wand;
+  }
+
   if (! (width <= INT_MAX && height <= INT_MAX
         && check_image_size (f, width, height)))
     {
@@ -7770,9 +7795,51 @@ imagemagick_load_image (struct frame *f, struct image *img,
      went ok.  */
 
   init_color_table ();
-  imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
-                              ? XINT (Vimagemagick_render_type) : 0);
-  if (imagemagick_rendermethod == 0)
+
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+  if (imagemagick_render_type != 0)
+    {
+      /* Magicexportimage is normally 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);*/
+      const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
+      /* Try to create a x pixmap to hold the imagemagick pixmap.  */
+      if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
+                                        &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 doesn't seem to work:*/
+      /* switch(ximg->bitmap_unit){ */
+      /* case 8: */
+      /*   pixelwidth=CharPixel; */
+      /*   break; */
+      /* case   16: */
+      /*   pixelwidth=ShortPixel; */
+      /*   break; */
+      /* case   32: */
+      /*   pixelwidth=LongPixel; */
+      /*   break; */
+      /* } */
+      /*
+        Here im just guessing the format of the bitmap.
+        happens to work fine for:
+        - bw djvu images
+        on rgb display.
+        seems about 3 times as fast as pixel pushing(not carefully measured)
+      */
+      pixelwidth = CharPixel; /*??? TODO figure out*/
+      MagickExportImagePixels (image_wand, 0, 0, width, height,
+                              exportdepth, pixelwidth, ximg->data);
+    }
+  else
+#endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
     {
       size_t image_height;
 
@@ -7787,7 +7854,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
           goto imagemagick_error;
         }
 
-      /* Copy imagegmagick image to x with primitive yet robust pixel
+      /* Copy imagemagick image to x with primitive yet robust pixel
          pusher loop.  This has been tested a lot with many different
          images.  */
 
@@ -7823,67 +7890,12 @@ imagemagick_load_image (struct frame *f, struct image *img,
       DestroyPixelIterator (iterator);
     }
 
-  if (imagemagick_rendermethod == 1)
-    {
-      /* 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);*/
-      const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
-      /* Try to create a x pixmap to hold the imagemagick pixmap.  */
-      if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
-                                        &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: */
-      /*   pixelwidth=CharPixel; */
-      /*   break; */
-      /* case   16: */
-      /*   pixelwidth=ShortPixel; */
-      /*   break; */
-      /* case   32: */
-      /*   pixelwidth=LongPixel; */
-      /*   break; */
-      /* } */
-      /*
-        Here im just guessing the format of the bitmap.
-        happens to work fine for:
-        - bw djvu images
-        on rgb display.
-        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);
-#else
-      image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
-                  Qnil, Qnil);
-#endif
-    }
-
-
 #ifdef COLOR_TABLE_SUPPORT
   /* Remember colors allocated for this image.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
 #endif /* COLOR_TABLE_SUPPORT */
 
-
   img->width  = width;
   img->height = height;
 
@@ -7892,9 +7904,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
 
-
   /* Final cleanup. image_wand should be the only resource left. */
   DestroyMagickWand (image_wand);
+  if (bg_wand) DestroyPixelWand (bg_wand);
+
   /* `MagickWandTerminus' terminates the imagemagick environment.  */
   MagickWandTerminus ();
 
@@ -7902,7 +7915,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
 
  imagemagick_error:
   DestroyMagickWand (image_wand);
- imagemagick_no_wand:
+  if (bg_wand) DestroyPixelWand (bg_wand);
+
   MagickWandTerminus ();
   /* TODO more cleanup.  */
   image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
@@ -7958,9 +7972,11 @@ DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
 Each entry in this list is a symbol named after an ImageMagick format
 tag.  See the ImageMagick manual for a list of ImageMagick formats and
 their descriptions (http://www.imagemagick.org/script/formats.php).
+You can also try the shell command: `identify -list format'.
 
 Note that ImageMagick recognizes many file-types that Emacs does not
-recognize as images, such as C.  See `imagemagick-types-inhibit'.  */)
+recognize as images, such as C.  See `imagemagick-types-enable'
+and `imagemagick-types-inhibit'.  */)
   (void)
 {
   Lisp_Object typelist = Qnil;
@@ -7974,7 +7990,7 @@ recognize as images, such as C.  See `imagemagick-types-inhibit'.  */)
       Qimagemagicktype = intern (imtypes[i]);
       typelist = Fcons (Qimagemagicktype, typelist);
     }
-  return typelist;
+  return Fnreverse (typelist);
 }
 
 #endif /* defined (HAVE_IMAGEMAGICK) */
@@ -8479,7 +8495,7 @@ gs_image_p (Lisp_Object object)
       if (ASIZE (tem) != 4)
        return 0;
       for (i = 0; i < 4; ++i)
-       if (!INTEGERP (XVECTOR (tem)->contents[i]))
+       if (!INTEGERP (AREF (tem, i)))
          return 0;
     }
   else
@@ -8523,7 +8539,7 @@ gs_load (struct frame *f, struct image *img)
   img->height = in_height;
 
   /* Create the pixmap.  */
-  xassert (img->pixmap == NO_PIXMAP);
+  eassert (img->pixmap == NO_PIXMAP);
 
   if (x_check_image_size (0, img->width, img->height))
     {
@@ -8594,7 +8610,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
   /* Kill the GS process.  We should have found PIXMAP in the image
      cache and its image should contain a process object.  */
   img = c->images[i];
-  xassert (PROCESSP (img->lisp_data));
+  eassert (PROCESSP (img->lisp_data));
   Fkill_process (img->lisp_data, Qnil);
   img->lisp_data = Qnil;
 
@@ -8669,7 +8685,7 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
                                Tests
  ***********************************************************************/
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
 
 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
        doc: /* Value is non-nil if SPEC is a valid image specification.  */)
@@ -8691,7 +8707,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
   return make_number (id);
 }
 
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
 
 
 /***********************************************************************
@@ -8782,7 +8798,7 @@ syms_of_image (void)
      operation on GNU/Linux of calling dump-emacs after loading some images.  */
   image_types = NULL;
 
-  /* Must be defined now becase we're going to update it below, while
+  /* Must be defined now because 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.
@@ -8905,7 +8921,7 @@ non-numeric, there is no explicit limit on the size of images.  */);
   defsubr (&Simage_mask_p);
   defsubr (&Simage_metadata);
 
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
   defsubr (&Simagep);
   defsubr (&Slookup_image);
 #endif
@@ -8930,8 +8946,17 @@ 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,
-               doc: /* Choose between ImageMagick render methods.  */);
+  DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type,
+    doc: /* Integer indicating which ImageMagick rendering method to use.
+The options are:
+  0 -- the default method (pixel pushing)
+  1 -- a newer method ("MagickExportImagePixels") that may perform
+       better (speed etc) in some cases, but has not been as thoroughly
+       tested with Emacs as the default method.  This method requires
+       ImageMagick version 6.4.6 (approximately) or later.
+*/);
+  /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10.  */
+  imagemagick_render_type = 0;
 #endif
 
 }