changeset 109868:c1ae0a9b14a1

reworked :index functionality a bit so its faster
author Joakim <joakim@localhost.localdomain>
date Thu, 01 Jul 2010 23:38:33 +0200
parents 7b3550d93e3a
children 22892dff6fc3
files README.imagemagick src/image.c
diffstat 2 files changed, 573 insertions(+), 560 deletions(-) [+]
line wrap: on
line diff
--- a/README.imagemagick	Sun Jun 27 02:18:55 2010 +0200
+++ b/README.imagemagick	Thu Jul 01 23:38:33 2010 +0200
@@ -27,6 +27,9 @@
   the bundle. This feature is not the primary usecase for the
   imagemagick patch though.
 
+  ImageMagick 6.6.2-8 introduced a bugfix for single page djvu load.
+  To benefit from the bugfix, the loader code in image.c must be changed.
+  
 - optimize number of pages calculation for bundles as suggested by
   imagemagick forum: "set the density to something low like 2 and use
   MagickPingImage()"
--- a/src/image.c	Sun Jun 27 02:18:55 2010 +0200
+++ b/src/image.c	Thu Jul 01 23:38:33 2010 +0200
@@ -1,22 +1,22 @@
 /* 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.
-
-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 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/>.  */
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
+
+   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 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/>.  */
 
 #include <config.h>
 #include <stdio.h>
@@ -115,7 +115,7 @@
 #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
@@ -290,7 +290,7 @@
 #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);
@@ -338,7 +338,7 @@
   void *bitmap = ns_image_from_file(file);
 
   if (!bitmap)
-      return -1;
+    return -1;
 
 
   id = x_allocate_bitmap_record (f);
@@ -572,7 +572,7 @@
 
 /***********************************************************************
 			    Image types
- ***********************************************************************/
+***********************************************************************/
 
 /* Value is the number of elements of vector VECTOR.  */
 
@@ -627,10 +627,10 @@
 static int x_build_heuristic_mask P_ ((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
@@ -737,23 +737,23 @@
 
 /***********************************************************************
 			 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.  */
 
@@ -956,10 +956,10 @@
 
 DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
        doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
-PIXELS non-nil means return the size in pixels, otherwise return the
-size in canonical character units.
-FRAME is the frame on which the image will be displayed.  FRAME nil
-or omitted means use the selected frame.  */)
+               PIXELS non-nil means return the size in pixels, otherwise return the
+               size in canonical character units.
+               FRAME is the frame on which the image will be displayed.  FRAME nil
+               or omitted means use the selected frame.  */)
      (spec, pixels, frame)
      Lisp_Object spec, pixels, frame;
 {
@@ -989,8 +989,8 @@
 
 DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
        doc: /* Return t if image SPEC has a mask bitmap.
-FRAME is the frame on which the image will be displayed.  FRAME nil
-or omitted means use the selected frame.  */)
+               FRAME is the frame on which the image will be displayed.  FRAME nil
+               or omitted means use the selected frame.  */)
      (spec, frame)
      Lisp_Object spec, frame;
 {
@@ -1013,8 +1013,8 @@
 
 DEFUN ("image-metadata", Fimage_metadata, Simage_metadata, 1, 2, 0,
        doc: /* Return metadata for image SPEC.
-FRAME is the frame on which the image will be displayed.  FRAME nil
-or omitted means use the selected frame.  */)
+               FRAME is the frame on which the image will be displayed.  FRAME nil
+               or omitted means use the selected frame.  */)
      (spec, frame)
      Lisp_Object spec, frame;
 {
@@ -1035,7 +1035,7 @@
 
 /***********************************************************************
 		 Image type independent image structures
- ***********************************************************************/
+***********************************************************************/
 
 static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
 static void free_image P_ ((struct frame *f, struct image *img));
@@ -1250,26 +1250,26 @@
 
 #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)
 
-#define Destroy_Image(ximg, dummy) \
+#define Destroy_Image(ximg, dummy)              \
   ns_release_object(ximg)
 
-#define Free_Pixmap(display, pixmap) \
+#define Free_Pixmap(display, pixmap)            \
   ns_release_object(pixmap)
 
 #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 */
@@ -1369,7 +1369,7 @@
 
 /***********************************************************************
 		  Helper functions for X image types
- ***********************************************************************/
+***********************************************************************/
 
 static void x_clear_image_1 P_ ((struct frame *, struct image *, int,
 				 int, int));
@@ -1470,7 +1470,7 @@
 
 /***********************************************************************
 			     Image Cache
- ***********************************************************************/
+***********************************************************************/
 
 static struct image *search_image_cache P_ ((struct frame *, Lisp_Object, unsigned));
 static void cache_image P_ ((struct frame *f, struct image *img));
@@ -1673,10 +1673,10 @@
 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
        0, 1, 0,
        doc: /* Clear the image cache.
-FILTER nil or a frame means clear all images in the selected frame.
-FILTER t means clear the image caches of all frames.
-Anything else, means only clear those images which refer to FILTER,
-which is then usually a filename.  */)
+               FILTER nil or a frame means clear all images in the selected frame.
+               FILTER t means clear the image caches of all frames.
+               Anything else, means only clear those images which refer to FILTER,
+               which is then usually a filename.  */)
      (filter)
      Lisp_Object filter;
 {
@@ -1692,12 +1692,12 @@
 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.
-
-FRAME nil or omitted means use the selected frame.
-FRAME t means refresh the image on all frames.  */)
+               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.  */)
      (spec, frame)
      Lisp_Object spec, frame;
 {
@@ -1991,7 +1991,7 @@
 
 /***********************************************************************
 			  X / NS / W32 support code
- ***********************************************************************/
+***********************************************************************/
 
 #ifdef HAVE_NTGUI
 
@@ -1999,9 +1999,9 @@
 #define DEF_IMGLIB_FN(func) int (FAR CDECL *fn_##func)()
 
 /* 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.
@@ -2251,7 +2251,7 @@
 
 /***********************************************************************
 			      File Handling
- ***********************************************************************/
+***********************************************************************/
 
 static unsigned char *slurp_file P_ ((char *, int *));
 
@@ -2331,7 +2331,7 @@
 
 /***********************************************************************
 			      XBM images
- ***********************************************************************/
+***********************************************************************/
 
 static int xbm_scan P_ ((unsigned char **, unsigned char *, char *, int *));
 static int xbm_load P_ ((struct frame *f, struct image *img));
@@ -2347,61 +2347,61 @@
 /* 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.
@@ -2752,20 +2752,20 @@
   int value;
   int LA1;
 
-#define match() \
-     LA1 = xbm_scan (&s, end, buffer, &value)
-
-#define expect(TOKEN)		\
-     if (LA1 != (TOKEN)) 	\
-       goto failure;		\
-     else			\
-       match ()
+#define match()                                 \
+  LA1 = xbm_scan (&s, end, buffer, &value)
+
+#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)
@@ -3110,7 +3110,7 @@
 
 /***********************************************************************
 			      XPM images
- ***********************************************************************/
+***********************************************************************/
 
 #if defined (HAVE_XPM) || defined (HAVE_NS)
 
@@ -3149,49 +3149,49 @@
 /* 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
 
@@ -3755,15 +3755,15 @@
 static int xpm_scan P_ ((const unsigned char **, const unsigned char *,
 			 const unsigned char **, int *));
 static Lisp_Object xpm_make_color_table_v
-  P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
-       Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
+P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
+     Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
 static void xpm_put_color_table_v P_ ((Lisp_Object, const unsigned char *,
 				       int, Lisp_Object));
 static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object,
 					      const unsigned char *, int));
 static Lisp_Object xpm_make_color_table_h
-  P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
-       Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
+P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object),
+     Lisp_Object (**) (Lisp_Object, const unsigned char *, int)));
 static void xpm_put_color_table_h P_ ((Lisp_Object, const unsigned char *,
 				       int, Lisp_Object));
 static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object,
@@ -3775,11 +3775,11 @@
 /* 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
@@ -3808,7 +3808,7 @@
 	  *beg = *s - 1;
 	  while (*s < end
 		 && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
-	      ++*s;
+            ++*s;
 	  *len = *s - *beg;
 	  return XPM_TK_IDENT;
 	}
@@ -3965,21 +3965,21 @@
   int best_key, have_mask = 0;
   XImagePtr ximg = NULL, mask_img = NULL;
 
-#define match() \
-     LA1 = xpm_scan (&s, end, &beg, &len)
-
-#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 match()                                 \
+  LA1 = xpm_scan (&s, end, &beg, &len)
+
+#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
 
   if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
     goto failure;
@@ -4239,7 +4239,7 @@
 
 /***********************************************************************
 			     Color table
- ***********************************************************************/
+***********************************************************************/
 
 #ifdef COLOR_TABLE_SUPPORT
 
@@ -4513,7 +4513,7 @@
 
 /***********************************************************************
 			      Algorithms
- ***********************************************************************/
+***********************************************************************/
 
 static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
 static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
@@ -4532,17 +4532,17 @@
    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
@@ -5046,8 +5046,8 @@
       XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg
 				  ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
 #else
-      if (XGetPixel (ximg, x, y) == bg)
-        ns_set_alpha(ximg, x, y, 0);
+  if (XGetPixel (ximg, x, y) == bg)
+    ns_set_alpha(ximg, x, y, 0);
 #endif /* HAVE_NS */
 #ifndef HAVE_NS
   /* Fill in the background_transparent field while we have the mask handy. */
@@ -5085,7 +5085,7 @@
 
 /***********************************************************************
 		       PBM (mono, gray, color)
- ***********************************************************************/
+***********************************************************************/
 
 static int pbm_image_p P_ ((Lisp_Object object));
 static int pbm_load P_ ((struct frame *f, struct image *img));
@@ -5098,49 +5098,49 @@
 /* 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.  */
@@ -5505,7 +5505,7 @@
 
 /***********************************************************************
 				 PNG
- ***********************************************************************/
+***********************************************************************/
 
 #if defined (HAVE_PNG) || defined (HAVE_NS)
 
@@ -5521,47 +5521,47 @@
 /* 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.  */
 
@@ -6109,7 +6109,7 @@
 
 /***********************************************************************
 				 JPEG
- ***********************************************************************/
+***********************************************************************/
 
 #if defined (HAVE_JPEG) || defined (HAVE_NS)
 
@@ -6123,47 +6123,47 @@
 /* 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.  */
 
@@ -6462,7 +6462,7 @@
   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?  */
@@ -6471,8 +6471,8 @@
                                     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;
@@ -6566,7 +6566,7 @@
     }
 
   /* 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))
@@ -6578,7 +6578,7 @@
   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;
@@ -6681,7 +6681,7 @@
 
 /***********************************************************************
 				 TIFF
- ***********************************************************************/
+***********************************************************************/
 
 #if defined (HAVE_TIFF) || defined (HAVE_NS)
 
@@ -6695,49 +6695,49 @@
 /* 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.  */
 
@@ -6820,7 +6820,7 @@
   size_t len;
   int index;
 }
-tiff_memory_source;
+  tiff_memory_source;
 
 static size_t
 tiff_read_from_memory (data, buf, size)
@@ -7132,7 +7132,7 @@
 
 /***********************************************************************
 				 GIF
- ***********************************************************************/
+***********************************************************************/
 
 #if defined (HAVE_GIF) || defined (HAVE_NS)
 
@@ -7147,49 +7147,49 @@
 /* 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.  */
 
@@ -7282,7 +7282,7 @@
   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
@@ -7659,7 +7659,7 @@
 
    Uses librimagemagick to do most of the image processing.
 
-    non-zero when successful.
+   non-zero when successful.
 */
 
 static int
@@ -7689,6 +7689,7 @@
   int y;
 
   MagickWand  *image_wand;
+  MagickWand  *ping_wand;  
   PixelIterator *iterator;
   PixelWand  **pixels;
   MagickPixelPacket  pixel;
@@ -7700,28 +7701,31 @@
   double rotation;
   int imagemagick_rendermethod;
   int pixelwidth; 
-
-    
-  /* image_wand will contain the image.  */
-  image_wand = NewMagickWand();  
-
-  /* Parse the contents argument and initialize image_wand.  */
-  if(filename != NULL)
-    status = MagickReadImage(image_wand, filename);
-  else
-    status = MagickReadImageBlob(image_wand, contents, size);
-  image_error ("im read failed", Qnil, Qnil);
-  if (status == MagickFalse) goto imagemagick_error;
-
-  /* Handle image index for image types who can contain more than one image.
-     Interface :index is same as for GIF.  */
-
+  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);
   image = image_spec_value (img->spec, QCindex, NULL);
   ino = INTEGERP (image) ? XFASTINT (image) : 0;
-
-
-
-  if (ino >= MagickGetNumberImages(image_wand)) 
+  ping_wand=NewMagickWand();
+  MagickSetResolution(ping_wand, 2, 2);
+  if (filename != NULL)
+    {
+      status = MagickPingImage(ping_wand, filename);
+    }
+  else
+    {
+      status = MagickPingImageBlob(ping_wand, contents, size);
+    }
+  
+  if (ino >= MagickGetNumberImages(ping_wand)) 
     { 
       image_error ("Invalid image number `%s' in image `%s'", 
          	   image, img->spec); 
@@ -7729,21 +7733,53 @@
       return 0; 
     } 
 
- 
-  if (MagickGetNumberImages(image_wand) > 1)
+  if (MagickGetNumberImages(ping_wand) > 1)
     img->data.lisp_val =
       Fcons (Qcount,
-             Fcons (make_number (MagickGetNumberImages(image_wand)),
+             Fcons (make_number (MagickGetNumberImages(ping_wand)),
                     img->data.lisp_val));
-  if(ino == 0)
-    MagickSetFirstIterator(image_wand);
+
+  DestroyMagickWand (ping_wand);
+  /* Now, after pinging, we know how many images are inside the
+     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();
+
+      im_image = ReadImage (image_info, exception); 
+      CatchException(exception);
+
+      printf("im wand from image\n");   
+      image_wand = NewMagickWandFromImage(im_image);
+    }
   else
-    MagickSetIteratorIndex(image_wand, ino);
+    {
+      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 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. */
+     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);
@@ -7773,27 +7809,19 @@
       }
     }
 
-  /* Also support :geometry and :crop which are imagemagick specific
-     descriptors.  */
-
+
+  /* crop behaves similar to image slicing in Emacs but is more memory
+     efficient */
   crop     = image_spec_value (img->spec, QCcrop, NULL);
-  geometry = image_spec_value (img->spec, QCgeometry, NULL);
-
+  
   if(CONSP (crop))
     {
-      /* TODO test if MagickCropImage is more efficient than MagickTransformImage
-
-         idea: crop can be a list or a string. if its a string, do
-         "magicktransformimage" as before. if its a list, try MagickCropImage.
-         args should be somewhat compatible with "slice".
-         `(slice X Y WIDTH HEIGHT)'
-
-         after some testing, it seems cropping is indeed faster this
-         way, but its early days still. this crop function seems to do
-         less copying, but it still reads the entire image into memory
-         before croping, which is aparently difficult to avoid when using imagemagick.
-
-         also this interface is better because it is lisp based and not IM specific
+      /* 
+         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;
@@ -7928,8 +7956,6 @@
         - bw djvu images
         on rgb display.
         seems about 3 times as fast as pixel pushing(not carefully measured)
-        with color djvu, the bitplanes are mapped to wrong color(seems fixed).
-
       */
       pixelwidth = CharPixel;/*??? TODO figure out*/
 #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS    
@@ -7957,18 +7983,13 @@
   img->width  = width;
   img->height = height;
 
-  /* Maybe fill in the background field while we have ximg handy.
-     Casting avoids a GCC warning.  */
-  /*  IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);*/
-
   /* Put the image into the pixmap, then free the X image and its
      buffer.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
-
   x_destroy_x_image (ximg);
 
 
-  /* JAVE TODO more cleanup.  */
+  /* Final cleanup. image_wand should be the only resource left. */
   DestroyMagickWand (image_wand);
 
   return 1;
@@ -8009,17 +8030,6 @@
 	  UNGCPRO;
 	  return 0;
 	}
-
-      /* Read the entire file into memory.  */
-      /* contents = slurp_file (SDATA (file), &size); */
-      /* if (contents == NULL) */
-      /*   { */
-      /*     image_error ("Error loading IMAGEMAGICK image `%s'",
-             img->spec, Qnil); */
-      /*     UNGCPRO; */
-      /*     return 0; */
-      /*   } */
-      /* If the file was slurped into memory properly, parse it.  */
       success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name));
       UNGCPRO;
     }
@@ -8063,8 +8073,8 @@
 
 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.  */)
   ()
 {
   Lisp_Object typelist = Qnil;
@@ -8076,9 +8086,9 @@
   for (i = 0; i < numf; i++)
     {
       Qimagemagicktype = intern (imtypes[i]);
-  typelist = Fcons (Qimagemagicktype, typelist);
-}
-return typelist;
+      typelist = Fcons (Qimagemagicktype, typelist);
+    }
+  return typelist;
 }
   
 #endif	/* defined (HAVE_IMAGEMAGICK) */
@@ -8087,7 +8097,7 @@
 
 /***********************************************************************
 				 SVG
- ***********************************************************************/
+***********************************************************************/
 
 #if defined (HAVE_RSVG)
 
@@ -8106,55 +8116,55 @@
 /* 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
@@ -8325,7 +8335,7 @@
    Returns non-zero when successful.  */
 static int
 svg_load_image (f, img, contents, size)
-    /* Pointer to emacs frame structure.  */
+/* Pointer to emacs frame structure.  */
      struct frame *f;
      /* Pointer to emacs image structure.  */
      struct image *img;
@@ -8487,7 +8497,7 @@
 
 /***********************************************************************
 				Ghostscript
- ***********************************************************************/
+***********************************************************************/
 
 #ifdef HAVE_X_WINDOWS
 #define HAVE_GHOSTSCRIPT 1
@@ -8510,53 +8520,53 @@
 /* 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.  */
@@ -8791,13 +8801,13 @@
 
 /***********************************************************************
 				Tests
- ***********************************************************************/
+***********************************************************************/
 
 #if GLYPH_DEBUG
 
 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
        doc: /* Value is non-nil if SPEC is a valid image specification.  */)
-  (spec)
+     (spec)
      Lisp_Object spec;
 {
   return valid_image_p (spec) ? Qt : Qnil;
@@ -8805,7 +8815,7 @@
 
 
 DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
-  (spec)
+     (spec)
      Lisp_Object spec;
 {
   int id = -1;
@@ -8822,7 +8832,7 @@
 
 /***********************************************************************
 			    Initialization
- ***********************************************************************/
+***********************************************************************/
 
 #ifdef HAVE_NTGUI
 /* Image types that rely on external libraries are loaded dynamically
@@ -8836,13 +8846,13 @@
 
 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.
-
-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).  */)
-  (type, libraries)
-  Lisp_Object type, libraries;
+               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).  */)
+     (type, libraries)
+     Lisp_Object type, libraries;
 {
   Lisp_Object tested;
 
@@ -8914,13 +8924,13 @@
   /* 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'.  */);
+               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.
+               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
@@ -8934,15 +8944,15 @@
   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.  */);
+               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;
@@ -9082,22 +9092,22 @@
 #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.  */);
+               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.  */);
+               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.  */);
+               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,