Spelling fixes.
[bpt/emacs.git] / src / image.c
index 974c525..8b61c7e 100644 (file)
@@ -48,11 +48,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "termhooks.h"
 #include "font.h"
 
-#define RANGED_INTEGERP(lo, x, hi) \
-  (INTEGERP (x) && (lo) <= XINT (x) && XINT (x) <= (hi))
-#define TYPE_RANGED_INTEGERP(type, x) \
-  RANGED_INTEGERP (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type))
-
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #include <sys/types.h>
@@ -61,7 +56,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define COLOR_TABLE_SUPPORT 1
 
 typedef struct x_bitmap_record Bitmap_Record;
-#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
+#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
 #define NO_PIXMAP None
 
 #define RGB_PIXEL_COLOR unsigned long
@@ -79,7 +74,7 @@ typedef struct x_bitmap_record Bitmap_Record;
 #undef COLOR_TABLE_SUPPORT
 
 typedef struct w32_bitmap_record Bitmap_Record;
-#define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
+#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
 #define NO_PIXMAP 0
 
 #define RGB_PIXEL_COLOR COLORREF
@@ -111,7 +106,7 @@ Lisp_Object Qlibpng_version;
 
 typedef struct ns_bitmap_record Bitmap_Record;
 
-#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
+#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
 #define NO_PIXMAP 0
 
 #define RGB_PIXEL_COLOR unsigned long
@@ -120,7 +115,7 @@ typedef struct ns_bitmap_record Bitmap_Record;
 #define PIX_MASK_RETAIN        0
 #define PIX_MASK_DRAW  1
 
-#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
+#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO (f)->visual
 #define x_defined_color(f, name, color_def, alloc) \
   ns_defined_color (f, name, color_def, alloc, 0)
 #define FRAME_X_SCREEN(f) 0
@@ -201,7 +196,8 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
 int
 x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
 {
-  return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
+  /* HAVE_NTGUI needs the explicit cast here.  */
+  return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
 }
 #endif
 
@@ -221,15 +217,6 @@ x_allocate_bitmap_record (FRAME_PTR f)
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   ptrdiff_t i;
 
-  if (dpyinfo->bitmaps == NULL)
-    {
-      dpyinfo->bitmaps_size = 10;
-      dpyinfo->bitmaps
-       = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
-      dpyinfo->bitmaps_last = 1;
-      return 1;
-    }
-
   if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
     return ++dpyinfo->bitmaps_last;
 
@@ -237,13 +224,9 @@ x_allocate_bitmap_record (FRAME_PTR f)
     if (dpyinfo->bitmaps[i].refcount == 0)
       return i + 1;
 
-  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2
-      < dpyinfo->bitmaps_size)
-    memory_full (SIZE_MAX);
-  dpyinfo->bitmaps_size *= 2;
-  dpyinfo->bitmaps
-    = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
-                                 dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
+  dpyinfo->bitmaps =
+    xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
+            10, -1, sizeof *dpyinfo->bitmaps);
   return ++dpyinfo->bitmaps_last;
 }
 
@@ -709,7 +692,7 @@ enum image_value_type
   IMAGE_STRING_OR_NIL_VALUE,
   IMAGE_SYMBOL_VALUE,
   IMAGE_POSITIVE_INTEGER_VALUE,
-  IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
+  IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
   IMAGE_NON_NEGATIVE_INTEGER_VALUE,
   IMAGE_ASCENT_VALUE,
   IMAGE_INTEGER_VALUE,
@@ -816,12 +799,12 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
            return 0;
          break;
 
-       case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR:
-         if (RANGED_INTEGERP (1, value, INT_MAX))
+       case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
+         if (RANGED_INTEGERP (0, value, INT_MAX))
            break;
          if (CONSP (value)
-             && RANGED_INTEGERP (1, XCAR (value), INT_MAX)
-             && RANGED_INTEGERP (1, XCDR (value), INT_MAX))
+             && RANGED_INTEGERP (0, XCAR (value), INT_MAX)
+             && RANGED_INTEGERP (0, XCDR (value), INT_MAX))
            break;
          return 0;
 
@@ -1059,9 +1042,13 @@ check_image_size (struct frame *f, int width, int height)
            && height <= XINT (Vmax_image_size));
   else if (FLOATP (Vmax_image_size))
     {
-      xassert (f);
-      w = FRAME_PIXEL_WIDTH (f);
-      h = FRAME_PIXEL_HEIGHT (f);
+      if (f != NULL)
+       {
+         w = FRAME_PIXEL_WIDTH (f);
+         h = FRAME_PIXEL_HEIGHT (f);
+       }
+      else
+       w = h = 1024;  /* Arbitrary size for unknown frame. */
       return (width <= XFLOAT_DATA (Vmax_image_size) * w
              && height <= XFLOAT_DATA (Vmax_image_size) * h);
     }
@@ -1119,8 +1106,8 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
             because a typical font is `top-heavy' (due to the presence
             uppercase letters), so the image placement should err towards
             being top-heavy too.  It also just generally looks better.  */
-         ascent = (height + FONT_BASE(face->font)
-                    - FONT_DESCENT(face->font) + 1) / 2;
+         ascent = (height + FONT_BASE (face->font)
+                    - FONT_DESCENT (face->font) + 1) / 2;
 #endif /* HAVE_NTGUI */
        }
       else
@@ -1373,11 +1360,12 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
     {
       /* This isn't called frequently so we get away with simply
         reallocating the color vector to the needed size, here.  */
-      ++img->ncolors;
+      ptrdiff_t ncolors = img->ncolors + 1;
       img->colors =
        (unsigned long *) xrealloc (img->colors,
-                                   img->ncolors * sizeof *img->colors);
-      img->colors[img->ncolors - 1] = color.pixel;
+                                   ncolors * sizeof *img->colors);
+      img->colors[ncolors - 1] = color.pixel;
+      img->ncolors = ncolors;
       result = color.pixel;
     }
   else
@@ -1405,8 +1393,9 @@ make_image_cache (void)
   int size;
 
   memset (c, 0, sizeof *c);
-  c->size = 50;
-  c->images = (struct image **) xmalloc (c->size * sizeof *c->images);
+  size = 50;
+  c->images = (struct image **) xmalloc (size * sizeof *c->images);
+  c->size = size;
   size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
   c->buckets = (struct image **) xmalloc (size);
   memset (c->buckets, 0, size);
@@ -1834,13 +1823,7 @@ cache_image (struct frame *f, struct image *img)
 
   /* If no free slot found, maybe enlarge c->images.  */
   if (i == c->used && c->used == c->size)
-    {
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size)
-       memory_full (SIZE_MAX);
-      c->size *= 2;
-      c->images = (struct image **) xrealloc (c->images,
-                                             c->size * sizeof *c->images);
-    }
+    c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
 
   /* Add IMG to c->images, and assign IMG an id.  */
   c->images[i] = img;
@@ -1910,16 +1893,17 @@ static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
 static void x_destroy_x_image (XImagePtr);
 static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int);
 
-/* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break X.
+/* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break the
+   windowing system.
    WIDTH and HEIGHT must both be positive.
    If XIMG is null, assume it is a bitmap.  */
 static int
 x_check_image_size (XImagePtr ximg, int width, int height)
 {
+#ifdef HAVE_X_WINDOWS
   /* Respect Xlib's limits: it cannot deal with images that have more
      than INT_MAX (and/or UINT_MAX) bytes.  And respect Emacs's limits
-     of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object.  For now,
-     assume all windowing systems have the same limits that X does.  */
+     of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object.  */
   enum
   {
     XLIB_BYTES_MAX = min (INT_MAX, UINT_MAX),
@@ -1941,6 +1925,11 @@ x_check_image_size (XImagePtr ximg, int width, int height)
     }
   return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
          && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
+#else
+  /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
+     For now, assume that every image size is allowed on these systems.  */
+  return 1;
+#endif
 }
 
 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
@@ -2026,7 +2015,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));
 
@@ -2268,7 +2257,7 @@ static const struct image_keyword xbm_format[XBM_LAST] =
   {":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},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -3063,7 +3052,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -3581,9 +3570,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->ncolors = attrs.nalloc_pixels;
-      img->colors = (unsigned long *) xmalloc (img->ncolors
-                                              * sizeof *img->colors);
       for (i = 0; i < attrs.nalloc_pixels; ++i)
        {
          img->colors[i] = attrs.alloc_pixels[i];
@@ -4157,6 +4145,12 @@ static struct ct_color **ct_table;
 /* Number of entries in the color table.  */
 
 static int ct_colors_allocated;
+enum
+{
+  ct_colors_allocated_max =
+    min (INT_MAX,
+        min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long))
+};
 
 /* Initialize the color table.  */
 
@@ -4243,7 +4237,14 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
       XColor color;
       Colormap cmap;
       int rc;
+#else
+      COLORREF color;
+#endif
 
+      if (ct_colors_allocated_max <= ct_colors_allocated)
+       return FRAME_FOREGROUND_PIXEL (f);
+
+#ifdef HAVE_X_WINDOWS
       color.red = r;
       color.green = g;
       color.blue = b;
@@ -4265,7 +4266,6 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
        return FRAME_FOREGROUND_PIXEL (f);
 
 #else
-      COLORREF color;
 #ifdef HAVE_NTGUI
       color = PALETTERGB (r, g, b);
 #else
@@ -4306,6 +4306,9 @@ lookup_pixel_color (struct frame *f, unsigned long pixel)
       Colormap cmap;
       int rc;
 
+      if (ct_colors_allocated_max <= ct_colors_allocated)
+       return FRAME_FOREGROUND_PIXEL (f);
+
 #ifdef HAVE_X_WINDOWS
       cmap = FRAME_X_COLORMAP (f);
       color.pixel = pixel;
@@ -4444,7 +4447,9 @@ x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
   HGDIOBJ prev;
 #endif /* HAVE_NTGUI */
 
-  colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
+  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height)
+    memory_full (SIZE_MAX);
+  colors = (XColor *) xmalloc (sizeof *colors * img->width * img->height);
 
 #ifndef HAVE_NTGUI
   /* Get the X image IMG->pixmap.  */
@@ -4596,7 +4601,9 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus
 
 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
 
-  new = (XColor *) xmalloc (img->width * img->height * sizeof *new);
+  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height)
+    memory_full (SIZE_MAX);
+  new = (XColor *) xmalloc (sizeof *new * img->width * img->height);
 
   for (y = 0; y < img->height; ++y)
     {
@@ -4974,7 +4981,7 @@ static const struct image_keyword pbm_format[PBM_LAST] =
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -5389,7 +5396,7 @@ static const struct image_keyword png_format[PNG_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -5538,7 +5545,7 @@ init_png_functions (Lisp_Object libraries)
 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908)  */
 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
 #define PNG_JMPBUF(ptr) \
-  (*fn_png_set_longjmp_fn((ptr), longjmp, sizeof (jmp_buf)))
+  (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf)))
 #endif
 
 /* Error and warning handlers installed when the PNG library
@@ -5959,9 +5966,9 @@ png_load (struct frame *f, struct image *img)
 static int
 png_load (struct frame *f, struct image *img)
 {
-  return ns_load_image(f, img,
-                       image_spec_value (img->spec, QCfile, NULL),
-                       image_spec_value (img->spec, QCdata, NULL));
+  return ns_load_image (f, img,
+                        image_spec_value (img->spec, QCfile, NULL),
+                        image_spec_value (img->spec, QCdata, NULL));
 }
 #endif  /* HAVE_NS */
 
@@ -6009,7 +6016,7 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -6108,7 +6115,7 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
 
 #else
 
-#define fn_jpeg_CreateDecompress(a,b,c)        jpeg_create_decompress(a)
+#define fn_jpeg_CreateDecompress(a,b,c)        jpeg_create_decompress (a)
 #define fn_jpeg_start_decompress       jpeg_start_decompress
 #define fn_jpeg_finish_decompress      jpeg_finish_decompress
 #define fn_jpeg_destroy_decompress     jpeg_destroy_decompress
@@ -6559,7 +6566,7 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -6738,10 +6745,20 @@ tiff_size_of_memory (thandle_t data)
   return ((tiff_memory_source *) data)->len;
 }
 
+/* GCC 3.x on x86 Windows targets has a bug that triggers an internal
+   compiler error compiling tiff_handler, see Bugzilla bug #17406
+   (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406).  Declaring
+   this function as external works around that problem.  */
+#if defined (__MINGW32__) && __GNUC__ == 3
+# define MINGW_STATIC
+#else
+# define MINGW_STATIC static
+#endif
 
-static void tiff_handler (const char *, const char *, const char *, va_list)
+MINGW_STATIC void
+tiff_handler (const char *, const char *, const char *, va_list)
   ATTRIBUTE_FORMAT_PRINTF (3, 0);
-static void
+MINGW_STATIC void
 tiff_handler (const char *log_format, const char *title,
              const char *format, va_list ap)
 {
@@ -6755,6 +6772,7 @@ tiff_handler (const char *log_format, const char *title,
   add_to_log (log_format, build_string (title),
              make_string (buf, max (0, min (len, sizeof buf - 1))));
 }
+#undef MINGW_STATIC
 
 static void tiff_error_handler (const char *, const char *, va_list)
   ATTRIBUTE_FORMAT_PRINTF (2, 0);
@@ -6996,7 +7014,7 @@ static const struct image_keyword gif_format[GIF_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -7141,7 +7159,6 @@ gif_load (struct frame *f, struct image *img)
   ColorMapObject *gif_color_map;
   unsigned long pixel_colors[256];
   GifFileType *gif;
-  int image_height, image_width;
   gif_memory_source memsrc;
   Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
   Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -7218,19 +7235,15 @@ gif_load (struct frame *f, struct image *img)
       }
   }
 
-  img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top;
-  img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left;
-  image_height = gif->SavedImages[idx].ImageDesc.Height;
-  img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
-  image_width = gif->SavedImages[idx].ImageDesc.Width;
-  img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
+  width = img->width = gif->SWidth;
+  height = img->height = gif->SHeight;
 
-  width = img->width = max (gif->SWidth,
-                           max (gif->Image.Left + gif->Image.Width,
-                                img->corners[RIGHT_CORNER]));
-  height = img->height = max (gif->SHeight,
-                             max (gif->Image.Top + gif->Image.Height,
-                                  img->corners[BOT_CORNER]));
+  img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
+  img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
+  img->corners[BOT_CORNER]
+    = img->corners[TOP_CORNER] + gif->SavedImages[0].ImageDesc.Height;
+  img->corners[RIGHT_CORNER]
+    = img->corners[LEFT_CORNER] + gif->SavedImages[0].ImageDesc.Width;
 
   if (!check_image_size (f, width, height))
     {
@@ -7285,6 +7298,10 @@ gif_load (struct frame *f, struct image *img)
       unsigned char *raster = (unsigned char *) subimage->RasterBits;
       int transparency_color_index = -1;
       int disposal = 0;
+      int subimg_width = subimage->ImageDesc.Width;
+      int subimg_height = subimage->ImageDesc.Height;
+      int subimg_top = subimage->ImageDesc.Top;
+      int subimg_left = subimage->ImageDesc.Left;
 
       /* Find the Graphic Control Extension block for this sub-image.
         Extract the disposal method and transparency color.  */
@@ -7308,6 +7325,13 @@ gif_load (struct frame *f, struct image *img)
       if (j == 0)
        disposal = 2;
 
+      /* For disposal == 0, the spec says "No disposal specified. The
+        decoder is not required to take any action."  In practice, it
+        seems we need to treat this like "keep in place", see e.g.
+        http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
+      if (disposal == 0)
+       disposal = 1;
+
       /* Allocate subimage colors.  */
       memset (pixel_colors, 0, sizeof pixel_colors);
       gif_color_map = subimage->ImageDesc.ColorMap;
@@ -7335,34 +7359,34 @@ gif_load (struct frame *f, struct image *img)
          int row, pass;
 
          for (y = 0, row = interlace_start[0], pass = 0;
-              y < image_height;
+              y < subimg_height;
               y++, row += interlace_increment[pass])
            {
-             if (row >= image_height)
+             if (row >= subimg_height)
                {
                  row = interlace_start[++pass];
-                 while (row >= image_height)
+                 while (row >= subimg_height)
                    row = interlace_start[++pass];
                }
 
-             for (x = 0; x < image_width; x++)
+             for (x = 0; x < subimg_width; x++)
                {
-                 int c = raster[y * image_width + x];
+                 int c = raster[y * subimg_width + x];
                  if (transparency_color_index != c || disposal != 1)
-                   XPutPixel (ximg, x + img->corners[LEFT_CORNER],
-                              row + img->corners[TOP_CORNER], pixel_colors[c]);
+                   XPutPixel (ximg, x + subimg_left, row + subimg_top,
+                              pixel_colors[c]);
                }
            }
        }
       else
        {
-         for (y = 0; y < image_height; ++y)
-           for (x = 0; x < image_width; ++x)
+         for (y = 0; y < subimg_height; ++y)
+           for (x = 0; x < subimg_width; ++x)
              {
-               int c = raster[y * image_width + x];
+               int c = raster[y * subimg_width + x];
                if (transparency_color_index != c || disposal != 1)
-                 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
-                            y + img->corners[TOP_CORNER], pixel_colors[c]);
+                 XPutPixel (ximg, x + subimg_left, y + subimg_top,
+                            pixel_colors[c]);
              }
        }
     }
@@ -7477,7 +7501,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
     {":data",          IMAGE_STRING_VALUE,                     0},
     {":file",          IMAGE_STRING_VALUE,                     0},
     {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+    {":margin",                IMAGE_NON_NEGATIVE_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},
@@ -7528,7 +7552,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>
 
@@ -7612,7 +7636,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
       return 0;
     }
 
-  if (MagickGetNumberImages(ping_wand) > 1)
+  if (MagickGetNumberImages (ping_wand) > 1)
     img->lisp_data =
       Fcons (Qcount,
              Fcons (make_number (MagickGetNumberImages (ping_wand)),
@@ -7637,7 +7661,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
       if (im_image == NULL)
        goto imagemagick_no_wand;
       image_wand = NewMagickWandFromImage (im_image);
-      DestroyImage(im_image);
+      DestroyImage (im_image);
     }
   else
     {
@@ -7730,7 +7754,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
     }
 
   /* 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);
 
@@ -7758,11 +7782,11 @@ imagemagick_load_image (struct frame *f, struct image *img,
 #ifdef COLOR_TABLE_SUPPORT
          free_color_table ();
 #endif
-          image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+          image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
           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.  */
 
@@ -7800,7 +7824,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
 
   if (imagemagick_rendermethod == 1)
     {
-      /* Magicexportimage is normaly faster than pixelpushing.  This
+      /* 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);*/
@@ -7812,12 +7836,12 @@ imagemagick_load_image (struct frame *f, struct image *img,
 #ifdef COLOR_TABLE_SUPPORT
          free_color_table ();
 #endif
-         image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+         image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
          goto imagemagick_error;
        }
 
 
-      /* Oddly, the below code doesnt seem to work:*/
+      /* Oddly, the below code doesn't seem to work:*/
       /* switch(ximg->bitmap_unit){ */
       /* case 8: */
       /*   pixelwidth=CharPixel; */
@@ -7846,7 +7870,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
                               /*&(img->pixmap));*/
                               ximg->data);
 #else
-      image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
+      image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!",
                   Qnil, Qnil);
 #endif
     }
@@ -8000,7 +8024,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -8395,7 +8419,7 @@ static const struct image_keyword gs_format[GS_LAST] =
   {":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},
+  {":margin",          IMAGE_NON_NEGATIVE_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},
@@ -8757,7 +8781,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.