use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / image.c
index 3220a45..7fa2884 100644 (file)
@@ -1822,37 +1822,6 @@ cache_image (struct frame *f, struct image *img)
   img->prev = NULL;
   c->buckets[i] = img;
 }
-
-
-/* Call FN on every image in the image cache of frame F.  Used to mark
-   Lisp Objects in the image cache.  */
-
-/* Mark Lisp objects in image IMG.  */
-
-static void
-mark_image (struct image *img)
-{
-  mark_object (img->spec);
-  mark_object (img->dependencies);
-
-  if (!NILP (img->lisp_data))
-    mark_object (img->lisp_data);
-}
-
-
-void
-mark_image_cache (struct image_cache *c)
-{
-  if (c)
-    {
-      ptrdiff_t i;
-      for (i = 0; i < c->used; ++i)
-       if (c->images[i])
-         mark_image (c->images[i]);
-    }
-}
-
-
 \f
 /***********************************************************************
                          X / NS / W32 support code
@@ -1951,7 +1920,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
     }
 
   /* Allocate image raster.  */
-  (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
+  (*ximg)->data = xmalloc_atomic ((*ximg)->bytes_per_line * height);
 
   /* Allocate a pixmap of the same size.  */
   *pixmap = XCreatePixmap (display, window, width, height, depth);
@@ -2294,7 +2263,7 @@ slurp_file (char *file, ptrdiff_t *size)
 
   if (fp)
     {
-      ptrdiff_t count = SPECPDL_INDEX ();
+      dynwind_begin ();
       record_unwind_protect_ptr (fclose_unwind, fp);
 
       if (fstat (fileno (fp), &st) == 0
@@ -2313,7 +2282,7 @@ slurp_file (char *file, ptrdiff_t *size)
            }
        }
 
-      unbind_to (count, Qnil);
+      dynwind_end ();
     }
 
   return buf;
@@ -2819,7 +2788,7 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
     }
   bytes_per_line = (*width + 7) / 8 + padding_p;
   nbytes = bytes_per_line * *height;
-  p = *data = xmalloc (nbytes);
+  p = *data = xmalloc_atomic (nbytes);
 
   if (v10)
     {
@@ -3718,7 +3687,8 @@ xpm_load (struct frame *f, struct image *img)
 #endif /* HAVE_NTGUI */
 
       /* Remember allocated colors.  */
-      img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
+      img->colors = xnmalloc_atomic (attrs.nalloc_pixels,
+                                     sizeof *img->colors);
       img->ncolors = attrs.nalloc_pixels;
       for (i = 0; i < attrs.nalloc_pixels; ++i)
        {
@@ -4513,7 +4483,7 @@ colors_in_color_table (int *n)
     }
   else
     {
-      colors = xmalloc (ct_colors_allocated * sizeof *colors);
+      colors = xmalloc_atomic (ct_colors_allocated * sizeof *colors);
       *n = ct_colors_allocated;
 
       for (i = j = 0; i < CT_SIZE; ++i)
@@ -5942,8 +5912,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
   if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
       || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
     memory_full (SIZE_MAX);
-  c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
-  c->rows = rows = xmalloc (height * sizeof *rows);
+  c->pixels = pixels = xmalloc_atomic (sizeof *pixels * row_bytes * height);
+  c->rows = rows = xmalloc_atomic (height * sizeof *rows);
   for (i = 0; i < height; ++i)
     rows[i] = pixels + i * row_bytes;
 
@@ -7044,7 +7014,7 @@ tiff_load (struct frame *f, struct image *img)
       return 0;
     }
 
-  buf = xmalloc (sizeof *buf * width * height);
+  buf = xmalloc_atomic (sizeof *buf * width * height);
 
   rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
 
@@ -7250,7 +7220,11 @@ gif_image_p (Lisp_Object object)
 #ifdef WINDOWSNT
 
 /* GIF library details.  */
+#if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
+DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *, int *));
+#else
 DEF_IMGLIB_FN (int, DGifCloseFile, (GifFileType *));
+#endif
 DEF_IMGLIB_FN (int, DGifSlurp, (GifFileType *));
 #if GIFLIB_MAJOR < 5
 DEF_IMGLIB_FN (GifFileType *, DGifOpen, (void *, InputFunc));
@@ -7320,6 +7294,22 @@ gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
   return len;
 }
 
+static int
+gif_close (GifFileType *gif, int *err)
+{
+  int retval;
+
+#if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
+  retval = fn_DGifCloseFile (gif, err);
+#else
+  retval = fn_DGifCloseFile (gif);
+#if GIFLIB_MAJOR >= 5
+  if (err)
+    *err = gif->Error;
+#endif
+#endif
+  return retval;
+}
 
 /* Load GIF image IMG for use on frame F.  Value is true if
    successful.  */
@@ -7344,9 +7334,7 @@ gif_load (struct frame *f, struct image *img)
   Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
   unsigned long bgcolor = 0;
   EMACS_INT idx;
-#if GIFLIB_MAJOR >= 5
   int gif_err;
-#endif
 
   if (NILP (specified_data))
     {
@@ -7414,7 +7402,7 @@ gif_load (struct frame *f, struct image *img)
   if (!check_image_size (f, gif->SWidth, gif->SHeight))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
-      fn_DGifCloseFile (gif);
+      gif_close (gif, NULL);
       return 0;
     }
 
@@ -7423,7 +7411,7 @@ gif_load (struct frame *f, struct image *img)
   if (rc == GIF_ERROR || gif->ImageCount <= 0)
     {
       image_error ("Error reading `%s'", img->spec, Qnil);
-      fn_DGifCloseFile (gif);
+      gif_close (gif, NULL);
       return 0;
     }
 
@@ -7435,7 +7423,7 @@ gif_load (struct frame *f, struct image *img)
       {
        image_error ("Invalid image number `%s' in image `%s'",
                     image_number, img->spec);
-       fn_DGifCloseFile (gif);
+       gif_close (gif, NULL);
        return 0;
       }
   }
@@ -7453,7 +7441,7 @@ gif_load (struct frame *f, struct image *img)
   if (!check_image_size (f, width, height))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
-      fn_DGifCloseFile (gif);
+      gif_close (gif, NULL);
       return 0;
     }
 
@@ -7471,7 +7459,7 @@ gif_load (struct frame *f, struct image *img)
             && 0 <= subimg_left && subimg_left <= width - subimg_width))
        {
          image_error ("Subimage does not fit in image", Qnil, Qnil);
-         fn_DGifCloseFile (gif);
+         gif_close (gif, NULL);
          return 0;
        }
     }
@@ -7479,7 +7467,7 @@ gif_load (struct frame *f, struct image *img)
   /* Create the X image and pixmap.  */
   if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
     {
-      fn_DGifCloseFile (gif);
+      gif_close (gif, NULL);
       return 0;
     }
 
@@ -7650,7 +7638,18 @@ gif_load (struct frame *f, struct image *img)
                            Fcons (make_number (gif->ImageCount),
                                   img->lisp_data));
 
-  fn_DGifCloseFile (gif);
+  if (gif_close (gif, &gif_err) == GIF_ERROR)
+    {
+#if 5 <= GIFLIB_MAJOR
+      char *error_text = fn_GifErrorString (gif_err);
+
+      if (error_text)
+       image_error ("Error closing `%s': %s",
+                    img->spec, build_string (error_text));
+#else
+      image_error ("Error closing `%s'", img->spec, Qnil);
+#endif
+    }
 
   /* Maybe fill in the background field while we have ximg handy. */
   if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
@@ -8520,7 +8519,6 @@ and `imagemagick-types-inhibit'.  */)
   ExceptionInfo ex;
   char **imtypes;
   size_t i;
-  Lisp_Object Qimagemagicktype;
 
   GetExceptionInfo(&ex);
   imtypes = GetMagickList ("*", &numf, &ex);
@@ -8528,8 +8526,8 @@ and `imagemagick-types-inhibit'.  */)
 
   for (i = 0; i < numf; i++)
     {
-      Qimagemagicktype = intern (imtypes[i]);
-      typelist = Fcons (Qimagemagicktype, typelist);
+      Lisp_Object imagemagicktype = intern (imtypes[i]);
+      typelist = Fcons (imagemagicktype, typelist);
       imtypes[i] = MagickRelinquishMemory (imtypes[i]);
     }
 
@@ -9349,6 +9347,8 @@ reset_image_types (void)
 void
 syms_of_image (void)
 {
+#include "image.x"
+
   /* Initialize this only once; it will be reset before dumping.  */
   image_types = NULL;
 
@@ -9482,21 +9482,6 @@ non-numeric, there is no explicit limit on the size of images.  */);
 #endif /* HAVE_NTGUI  */
 #endif /* HAVE_RSVG  */
 
-  defsubr (&Sinit_image_library);
-#ifdef HAVE_IMAGEMAGICK
-  defsubr (&Simagemagick_types);
-#endif
-  defsubr (&Sclear_image_cache);
-  defsubr (&Simage_flush);
-  defsubr (&Simage_size);
-  defsubr (&Simage_mask_p);
-  defsubr (&Simage_metadata);
-
-#ifdef GLYPH_DEBUG
-  defsubr (&Simagep);
-  defsubr (&Slookup_image);
-#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.