* image.c (imagemagick_load_image, Finit_image_library): Free
[bpt/emacs.git] / src / image.c
index 083d072..c39a9ef 100644 (file)
@@ -1,7 +1,7 @@
 /* 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.
+                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+                2011 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -94,6 +94,11 @@ typedef struct w32_bitmap_record Bitmap_Record;
    without modifying lots of files).  */
 extern void x_query_colors (struct frame *f, XColor *colors, int ncolors);
 extern void x_query_color (struct frame *f, XColor *color);
+
+/* Version of libpng that we were compiled with, or -1 if no PNG
+   support was compiled in.  This is tested by w32-win.el to correctly
+   set up the alist used to search for PNG libraries.  */
+Lisp_Object Qlibpng_version;
 #endif /* HAVE_NTGUI */
 
 #ifdef HAVE_NS
@@ -1049,10 +1054,6 @@ free_image (struct frame *f, struct image *img)
       /* Free resources, then free IMG.  */
       img->type->free (f, img);
       xfree (img);
-
-      /* As display glyphs may still be referring to the image ID, we
-        must garbage the frame (Bug#6426).  */
-      SET_FRAME_GARBAGED (f);
     }
 }
 
@@ -1471,7 +1472,12 @@ uncache_image (struct frame *f, Lisp_Object spec)
 {
   struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
   if (img)
-    free_image (f, img);
+    {
+      free_image (f, img);
+      /* As display glyphs may still be referring to the image ID, we
+        must garbage the frame (Bug#6426).  */
+      SET_FRAME_GARBAGED (f);
+    }
 }
 
 
@@ -3331,7 +3337,7 @@ xpm_image_p (Lisp_Object object)
 
 #if defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 int
-x_create_bitmap_from_xpm_data (struct frame *f, char **bits)
+x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   int id, rc;
@@ -5529,6 +5535,8 @@ static void
 my_png_error (png_struct *png_ptr, const char *msg)
 {
   xassert (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);
   longjmp (png_ptr->jmpbuf, 1);
 }
@@ -7513,6 +7521,9 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
      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.  */
+
+  /* MagickWandGenesis() initializes the imagemagick library.  */
+  MagickWandGenesis ();
   image = image_spec_value (img->spec, QCindex, NULL);
   ino = INTEGERP (image) ? XFASTINT (image) : 0;
   ping_wand = NewMagickWand ();
@@ -7541,6 +7552,7 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
                     img->data.lisp_val));
 
   DestroyMagickWand (ping_wand);
+
   /* Now, after pinging, we know how many images are inside the
      file. If its not a bundle, just one.  */
 
@@ -7553,16 +7565,23 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
       exception = AcquireExceptionInfo ();
 
       im_image = ReadImage (image_info, exception);
-      CatchException (exception);
+      DestroyExceptionInfo (exception);
 
-      image_wand = NewMagickWandFromImage (im_image);
+      if (im_image != NULL)
+       {
+         image_wand = NewMagickWandFromImage (im_image);
+          DestroyImage(im_image);
+         status = MagickTrue;
+       }
+      else
+       status = MagickFalse;
     }
   else
     {
       image_wand = NewMagickWand ();
       status = MagickReadImageBlob (image_wand, contents, size);
     }
-  image_error ("im read failed", Qnil, Qnil);
+
   if (status == MagickFalse) goto imagemagick_error;
 
   /* If width and/or height is set in the display spec assume we want
@@ -7658,11 +7677,6 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
      width, height, and then transfer ownerwship to Emacs.  */
   height = MagickGetImageHeight (image_wand);
   width = MagickGetImageWidth (image_wand);
-  if (status == MagickFalse)
-    {
-      image_error ("Imagemagick image get size failed", Qnil, Qnil);
-      goto imagemagick_error;
-    }
 
   if (! check_image_size (f, width, height))
     {
@@ -7682,6 +7696,9 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
       if (!x_create_x_image_and_pixmap (f, width, height, 0,
                                         &ximg, &img->pixmap))
         {
+#ifdef COLOR_TABLE_SUPPORT
+         free_color_table ();
+#endif
           image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
           goto imagemagick_error;
         }
@@ -7694,6 +7711,10 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
       iterator = NewPixelIterator (image_wand);
       if (iterator == (PixelIterator *) NULL)
         {
+#ifdef COLOR_TABLE_SUPPORT
+         free_color_table ();
+#endif
+         x_destroy_x_image (ximg);
           image_error ("Imagemagick pixel iterator creation failed",
                        Qnil, Qnil);
           goto imagemagick_error;
@@ -7728,6 +7749,9 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
       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;
        }
@@ -7786,10 +7810,13 @@ imagemagick_load_image (/* Pointer to emacs frame structure.  */
 
   /* Final cleanup. image_wand should be the only resource left. */
   DestroyMagickWand (image_wand);
+  MagickWandTerminus ();
 
   return 1;
 
  imagemagick_error:
+  DestroyMagickWand (image_wand);
+  MagickWandTerminus ();
   /* TODO more cleanup.  */
   image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
   return 0;
@@ -8661,8 +8688,6 @@ of `dynamic-library-alist', which see).  */)
 #if defined (HAVE_IMAGEMAGICK)
   if (EQ (type, Qimagemagick))
     {
-      /* MagickWandGenesis() initializes the imagemagick library.  */
-      MagickWandGenesis ();
       return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
                                  libraries);
     }
@@ -8775,6 +8800,16 @@ non-numeric, there is no explicit limit on the size of images.  */);
   staticpro (&QCpt_height);
 #endif /* HAVE_GHOSTSCRIPT */
 
+#ifdef HAVE_NTGUI
+  Qlibpng_version = intern_c_string ("libpng-version");
+  staticpro (&Qlibpng_version);
+#if HAVE_PNG
+  SET_SYMBOL_VAL (XSYMBOL (Qlibpng_version), make_number (PNG_LIBPNG_VER));
+#else
+  SET_SYMBOL_VAL (XSYMBOL (Qlibpng_version), make_number (-1));
+#endif
+#endif
+
 #if defined (HAVE_XPM) || defined (HAVE_NS)
   Qxpm = intern_c_string ("xpm");
   staticpro (&Qxpm);