(enum fringe_bitmap_type): Define here.
[bpt/emacs.git] / src / w32fns.c
index 0747e4b..190ff15 100644 (file)
@@ -2361,7 +2361,7 @@ x_set_cursor_type (f, arg, oldval)
   set_frame_cursor_types (f, arg);
 
   /* Make sure the cursor gets redrawn.  */
-  cursor_type_changed = 1;  
+  cursor_type_changed = 1;
 }
 \f
 void
@@ -3073,7 +3073,7 @@ and the class is `Emacs.CLASS.SUBCLASS'.  */)
   strcat (name_key, ".");
   strcat (name_key, SDATA (attribute));
 
-  value = x_get_string_resource (Qnil,
+  value = x_get_string_resource (check_x_display_info (Qnil)->xrdb,
                                 name_key, class_key);
 
   if (value != (char *) 0)
@@ -3104,7 +3104,8 @@ x_get_resource_string (attribute, class)
           attribute);
   sprintf (class_key, "%s.%s", EMACS_CLASS, class);
 
-  return x_get_string_resource (sf, name_key, class_key);
+  return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
+                               name_key, class_key);
 }
 
 /* Types we might convert a resource string into.  */
@@ -5090,7 +5091,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
        return 0;
 
       goto dflt;
-      
+
     case WM_EMACS_SETCURSOR:
       {
        Cursor cursor = (Cursor) wParam;
@@ -5098,7 +5099,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
          SetCursor (cursor);
        return 0;
       }
-      
+
     case WM_EMACS_CREATESCROLLBAR:
       return (LRESULT) w32_createscrollbar ((struct frame *) wParam,
                                            (struct scroll_bar *) lParam);
@@ -7340,7 +7341,7 @@ static Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int max_names)
         {
           newlist = Fcons (XCAR (tem), newlist);
           n_fonts++;
-          if (n_fonts >= max_names)
+          if (max_names >= 0 && n_fonts >= max_names)
             break;
         }
     }
@@ -7354,7 +7355,8 @@ static Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int max_names)
    to be listed.  Frame F NULL means we have not yet created any
    frame, which means we can't get proper size info, as we don't have
    a device context to use for GetTextMetrics.
-   MAXNAMES sets a limit on how many fonts to match.  */
+   MAXNAMES sets a limit on how many fonts to match.  If MAXNAMES is
+   negative, then all matching fonts are returned.  */
 
 Lisp_Object
 w32_list_fonts (f, pattern, size, maxnames)
@@ -7467,7 +7469,7 @@ w32_list_fonts (f, pattern, size, maxnames)
             {
               newlist = Fcons (XCAR (tem), newlist);
               n_fonts++;
-              if (n_fonts >= maxnames)
+              if (maxnames >= 0 && n_fonts >= maxnames)
                 break;
               else
                 continue;
@@ -7506,7 +7508,7 @@ w32_list_fonts (f, pattern, size, maxnames)
             {
               newlist = Fcons (XCAR (tem), newlist);
               n_fonts++;
-              if (n_fonts >= maxnames)
+              if (maxnames >= 0 && n_fonts >= maxnames)
                 break;
             }
           /* keep track of the closest matching size in case
@@ -7542,7 +7544,7 @@ w32_list_fonts (f, pattern, size, maxnames)
     }
 
   /* Include any bdf fonts.  */
-  if (n_fonts < maxnames)
+  if (n_fonts < maxnames || maxnames < 0)
   {
     Lisp_Object combined[2];
     combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts);
@@ -8789,7 +8791,7 @@ image_background_transparent (img, f, mask)
              mask = CreateCompatibleDC (frame_dc);
              release_frame_dc (f, frame_dc);
 
-             prev = SelectObject (mask, img->mask);          
+             prev = SelectObject (mask, img->mask);
            }
 
          img->background_transparent
@@ -9339,12 +9341,12 @@ forall_images_in_image_cache (f, fn)
 
 /* Macro for defining functions that will be loaded from image DLLs.  */
 #define DEF_IMGLIB_FN(func) FARPROC 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;                                          \
-  } 
+  }
 
 static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
                                             XImage **, Pixmap *));
@@ -9867,7 +9869,7 @@ w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
 
   w1 = (width + 7) / 8;         /* nb of 8bits elt in X bitmap */
   w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
-  bits = (char *) xmalloc (height * w2);
+  bits = (char *) alloca (height * w2);
   bzero (bits, height * w2);
   for (i = 0; i < height; i++)
     {
@@ -9876,7 +9878,6 @@ w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
         *p++ = reflect_byte(*data++);
     }
   bmp = CreateBitmap (width, height, 1, 1, bits);
-  xfree (bits);
 
   return bmp;
 }
@@ -10055,7 +10056,7 @@ static void convert_mono_to_color_image (f, img, foreground, background)
          0, 0, SRCCOPY);
 
   SelectObject (old_img_dc, old_prev);
-  SelectObject (new_img_dc, new_prev);   
+  SelectObject (new_img_dc, new_prev);
   DeleteDC (old_img_dc);
   DeleteDC (new_img_dc);
   DeleteObject (img->pixmap);
@@ -10292,7 +10293,17 @@ static int xpm_image_p P_ ((Lisp_Object object));
 static int xpm_load P_ ((struct frame *f, struct image *img));
 static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
 
+/* Indicate to xpm.h that we don't have Xlib.  */
+#define FOR_MSW
+/* simx.h in xpm defines XColor and XImage differently than Emacs.  */
+#define XColor xpm_XColor
+#define XImage xpm_XImage
+#define PIXEL_ALREADY_TYPEDEFED
 #include "X11/xpm.h"
+#undef FOR_MSW
+#undef XColor
+#undef XImage
+#undef PIXEL_ALREADY_TYPEDEFED
 
 /* The symbol `xpm' identifying XPM-format images.  */
 
@@ -10346,6 +10357,26 @@ static struct image_type xpm_type =
 };
 
 
+/* XPM library details.  */
+
+DEF_IMGLIB_FN (XpmFreeAttributes);
+DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
+DEF_IMGLIB_FN (XpmReadFileToImage);
+DEF_IMGLIB_FN (XImageFree);
+
+
+static int
+init_xpm_functions (library)
+     HMODULE library;
+{
+  LOAD_IMGLIB_FN (library, XpmFreeAttributes);
+  LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
+  LOAD_IMGLIB_FN (library, XpmReadFileToImage);
+  LOAD_IMGLIB_FN (library, XImageFree);
+
+  return 1;
+}
+
 /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
    for XPM images.  Such a list must consist of conses whose car and
    cdr are strings.  */
@@ -10394,17 +10425,23 @@ xpm_load (f, img)
      struct frame *f;
      struct image *img;
 {
-  int rc, i;
+  HDC hdc;
+  int rc;
   XpmAttributes attrs;
   Lisp_Object specified_file, color_symbols;
+  xpm_XImage * xpm_image, * xpm_mask;
 
   /* Configure the XPM lib.  Use the visual of frame F.  Allocate
      close colors.  Return colors allocated.  */
   bzero (&attrs, sizeof attrs);
+  xpm_image = xpm_mask = NULL;
+
+#if 0
   attrs.visual = FRAME_X_VISUAL (f);
   attrs.colormap = FRAME_X_COLORMAP (f);
   attrs.valuemask |= XpmVisual;
   attrs.valuemask |= XpmColormap;
+#endif
   attrs.valuemask |= XpmReturnAllocPixels;
 #ifdef XpmAllocCloseColors
   attrs.alloc_close_colors = 1;
@@ -10452,34 +10489,71 @@ xpm_load (f, img)
 
   /* Create a pixmap for the image, either from a file, or from a
      string buffer containing data in the same format as an XPM file.  */
-  BLOCK_INPUT;
+
   specified_file = image_spec_value (img->spec, QCfile, NULL);
+
+  {
+    HDC frame_dc = get_frame_dc (f);
+    hdc = CreateCompatibleDC (frame_dc);
+    release_frame_dc (f, frame_dc);
+  }
+
   if (STRINGP (specified_file))
     {
       Lisp_Object file = x_find_image_file (specified_file);
       if (!STRINGP (file))
        {
          image_error ("Cannot find image file `%s'", specified_file, Qnil);
-          UNBLOCK_INPUT;
          return 0;
        }
 
-      rc = XpmReadFileToPixmap (NULL, FRAME_W32_WINDOW (f),
-                               SDATA (file), &img->pixmap, &img->mask,
-                               &attrs);
+      /* XpmReadFileToPixmap is not available in the Windows port of
+        libxpm.  But XpmReadFileToImage almost does what we want.  */
+      rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
+                                 &xpm_image, &xpm_mask,
+                                 &attrs);
     }
   else
     {
       Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
-      rc = XpmCreatePixmapFromBuffer (NULL, FRAME_W32_WINDOW (f),
-                                     SDATA (buffer),
-                                     &img->pixmap, &img->mask,
-                                     &attrs);
+      /* XpmCreatePixmapFromBuffer is not available in the Windows port
+        of libxpm.  But XpmCreateImageFromBuffer almost does what we want.  */
+      rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
+                                       &xpm_image, &xpm_mask,
+                                       &attrs);
     }
-  UNBLOCK_INPUT;
 
   if (rc == XpmSuccess)
     {
+      int i;
+
+      /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
+        plus some duplicate attributes.  */
+      if (xpm_image && xpm_image->bitmap)
+       {
+         img->pixmap = xpm_image->bitmap;
+         /* XImageFree in libXpm frees XImage struct without destroying
+            the bitmap, which is what we want.  */
+         fn_XImageFree (xpm_image);
+       }
+      if (xpm_mask && xpm_mask->bitmap)
+       {
+         /* The mask appears to be inverted compared with what we expect.
+            TODO: invert our expectations.  See other places where we
+            have to invert bits because our idea of masks is backwards.  */
+         HGDIOBJ old_obj;
+         old_obj = SelectObject (hdc, xpm_mask->bitmap);
+
+         PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
+         SelectObject (hdc, old_obj);
+
+         img->mask = xpm_mask->bitmap;
+         fn_XImageFree (xpm_mask);
+         DeleteDC (hdc);
+       }
+
+      DeleteDC (hdc);
+
       /* Remember allocated colors.  */
       img->ncolors = attrs.nalloc_pixels;
       img->colors = (unsigned long *) xmalloc (img->ncolors
@@ -10492,12 +10566,12 @@ xpm_load (f, img)
       xassert (img->width > 0 && img->height > 0);
 
       /* The call to XpmFreeAttributes below frees attrs.alloc_pixels.  */
-      BLOCK_INPUT;
-      XpmFreeAttributes (&attrs);
-      UNBLOCK_INPUT;
+      fn_XpmFreeAttributes (&attrs);
     }
   else
     {
+      DeleteDC (hdc);
+
       switch (rc)
        {
        case XpmOpenFailed:
@@ -11643,7 +11717,7 @@ DEF_IMGLIB_FN (png_create_read_struct);
 DEF_IMGLIB_FN (png_create_info_struct);
 DEF_IMGLIB_FN (png_destroy_read_struct);
 DEF_IMGLIB_FN (png_set_read_fn);
-DEF_IMGLIB_FN (png_init_io);  
+DEF_IMGLIB_FN (png_init_io);
 DEF_IMGLIB_FN (png_set_sig_bytes);
 DEF_IMGLIB_FN (png_read_info);
 DEF_IMGLIB_FN (png_get_IHDR);
@@ -11670,7 +11744,7 @@ init_png_functions (library)
   LOAD_IMGLIB_FN (library, png_create_info_struct);
   LOAD_IMGLIB_FN (library, png_destroy_read_struct);
   LOAD_IMGLIB_FN (library, png_set_read_fn);
-  LOAD_IMGLIB_FN (library, png_init_io);  
+  LOAD_IMGLIB_FN (library, png_init_io);
   LOAD_IMGLIB_FN (library, png_set_sig_bytes);
   LOAD_IMGLIB_FN (library, png_read_info);
   LOAD_IMGLIB_FN (library, png_get_IHDR);
@@ -11697,7 +11771,7 @@ png_image_p (object)
 {
   struct image_keyword fmt[PNG_LAST];
   bcopy (png_format, fmt, sizeof fmt);
-  
+
   if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
     return 0;
 
@@ -11754,7 +11828,7 @@ png_read_from_memory (png_ptr, data, length)
 
   if (length > tbr->len - tbr->index)
     fn_png_error (png_ptr, "Read error");
-  
+
   bcopy (tbr->bytes + tbr->index, data, length);
   tbr->index = tbr->index + length;
 }
@@ -11896,14 +11970,14 @@ png_load (f, img)
   fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
                   &interlace_type, NULL, NULL);
 
-  /* If image contains simply transparency data, we prefer to 
+  /* If image contains simply transparency data, we prefer to
      construct a clipping mask.  */
   if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
     transparent_p = 1;
   else
     transparent_p = 0;
 
-  /* This function is easier to write if we only have to handle 
+  /* This function is easier to write if we only have to handle
      one data format: RGB or RGBA with 8 bits per channel.  Let's
      transform other formats into that format.  */
 
@@ -11916,7 +11990,7 @@ png_load (f, img)
   fn_png_set_expand (png_ptr);
 
   /* Convert grayscale images to RGB.  */
-  if (color_type == PNG_COLOR_TYPE_GRAY 
+  if (color_type == PNG_COLOR_TYPE_GRAY
       || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
     fn_png_set_gray_to_rgb (png_ptr);
 
@@ -11965,14 +12039,14 @@ png_load (f, img)
            }
        }
       else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg))
-       /* Image contains a background color with which to 
+       /* Image contains a background color with which to
           combine the image.  */
        fn_png_set_background (png_ptr, image_bg,
                               PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
       else
        {
          /* Image does not contain a background color with which
-            to combine the image data via an alpha channel.  Use 
+            to combine the image data via an alpha channel.  Use
             the frame's background instead.  */
          COLORREF color;
          png_color_16 frame_background;
@@ -12022,12 +12096,12 @@ png_load (f, img)
       fclose (fp);
       fp = NULL;
     }
-  
+
   /* Create the X image and pixmap.  */
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
                                    &img->pixmap))
     goto error;
-  
+
   /* Create an image and pixmap serving as mask if the PNG image
      contains an alpha channel.  */
   if (channels == 4
@@ -12062,16 +12136,16 @@ png_load (f, img)
          XPutPixel (ximg, x, y, PALETTERGB (r, g, b));
 #endif
          /* An alpha channel, aka mask channel, associates variable
-            transparency with an image.  Where other image formats 
-            support binary transparency---fully transparent or fully 
+            transparency with an image.  Where other image formats
+            support binary transparency---fully transparent or fully
             opaque---PNG allows up to 254 levels of partial transparency.
             The PNG library implements partial transparency by combining
             the image with a specified background color.
 
             I'm not sure how to handle this here nicely: because the
             background on which the image is displayed may change, for
-            real alpha channel support, it would be necessary to create 
-            a new image for each possible background.  
+            real alpha channel support, it would be necessary to create
+            a new image for each possible background.
 
             What I'm doing now is that a mask is created if we have
             boolean transparency information.  Otherwise I'm using
@@ -12262,9 +12336,9 @@ jpeg_image_p (object)
      Lisp_Object object;
 {
   struct image_keyword fmt[JPEG_LAST];
-  
+
   bcopy (jpeg_format, fmt, sizeof fmt);
-  
+
   if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
     return 0;
 
@@ -12335,7 +12409,7 @@ our_skip_input_data (cinfo, num_bytes)
     {
       if (num_bytes > src->bytes_in_buffer)
        ERREXIT (cinfo, JERR_INPUT_EOF);
-      
+
       src->bytes_in_buffer -= num_bytes;
       src->next_input_byte += num_bytes;
     }
@@ -12373,7 +12447,7 @@ jpeg_memory_src (cinfo, data, len)
       src = (struct jpeg_source_mgr *) cinfo->src;
       src->next_input_byte = data;
     }
-  
+
   src = (struct jpeg_source_mgr *) cinfo->src;
   src->init_source = our_init_source;
   src->fill_input_buffer = our_fill_input_buffer;
@@ -12388,7 +12462,7 @@ jpeg_memory_src (cinfo, data, len)
 /* Load image IMG for use on frame F.  Patterned after example.c
    from the JPEG lib.  */
 
-static int 
+static int
 jpeg_load (f, img)
      struct frame *f;
      struct image *img;
@@ -12421,7 +12495,7 @@ jpeg_load (f, img)
          UNGCPRO;
          return 0;
        }
-  
+
       fp = fopen (SDATA (file), "r");
       if (fp == NULL)
        {
@@ -12435,7 +12509,7 @@ jpeg_load (f, img)
      error is detected.  This function will perform a longjmp.  */
   cinfo.err = fn_jpeg_std_error (&mgr.pub);
   mgr.pub.error_exit = my_error_exit;
-  
+
   if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
     {
       if (rc == 1)
@@ -12446,7 +12520,7 @@ jpeg_load (f, img)
          image_error ("Error reading JPEG image `%s': %s", img->spec,
                       build_string (buffer));
        }
-         
+
       /* Close the input file and destroy the JPEG object.  */
       if (fp)
        fclose ((FILE *) fp);
@@ -12457,7 +12531,7 @@ jpeg_load (f, img)
 
       /* Free pixmap and colors.  */
       x_clear_image (f, img);
-      
+
       UNGCPRO;
       return 0;
     }
@@ -12509,7 +12583,7 @@ jpeg_load (f, img)
 #endif
     colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
                                       * sizeof *colors);
-  
+
     for (i = 0; i < cinfo.actual_number_of_colors; ++i)
       {
        int r = cinfo.colormap[ir][i];
@@ -12549,7 +12623,7 @@ jpeg_load (f, img)
   /* Maybe fill in the background field while we have ximg handy. */
   if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
     IMAGE_BACKGROUND (img, f, ximg);
-  
+
   /* Put the image into the pixmap.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
@@ -12621,6 +12695,28 @@ static struct image_type tiff_type =
   NULL
 };
 
+/* TIFF library details.  */
+DEF_IMGLIB_FN (TIFFSetErrorHandler);
+DEF_IMGLIB_FN (TIFFSetWarningHandler);
+DEF_IMGLIB_FN (TIFFOpen);
+DEF_IMGLIB_FN (TIFFClientOpen);
+DEF_IMGLIB_FN (TIFFGetField);
+DEF_IMGLIB_FN (TIFFReadRGBAImage);
+DEF_IMGLIB_FN (TIFFClose);
+
+static int
+init_tiff_functions (library)
+     HMODULE library;
+{
+  LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
+  LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
+  LOAD_IMGLIB_FN (library, TIFFOpen);
+  LOAD_IMGLIB_FN (library, TIFFClientOpen);
+  LOAD_IMGLIB_FN (library, TIFFGetField);
+  LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
+  LOAD_IMGLIB_FN (library, TIFFClose);
+  return 1;
+}
 
 /* Return non-zero if OBJECT is a valid TIFF image specification.  */
 
@@ -12800,8 +12896,8 @@ tiff_load (f, img)
   file = Qnil;
   GCPRO1 (file);
 
-  TIFFSetErrorHandler (tiff_error_handler);
-  TIFFSetWarningHandler (tiff_warning_handler);
+  fn_TIFFSetErrorHandler (tiff_error_handler);
+  fn_TIFFSetWarningHandler (tiff_warning_handler);
 
   if (NILP (specified_data))
     {
@@ -12815,7 +12911,7 @@ tiff_load (f, img)
        }
 
       /* Try to open the image file.  */
-      tiff = TIFFOpen (SDATA (file), "r");
+      tiff = fn_TIFFOpen (SDATA (file), "r");
       if (tiff == NULL)
        {
          image_error ("Cannot open `%s'", file, Qnil);
@@ -12830,14 +12926,14 @@ tiff_load (f, img)
       memsrc.len = SBYTES (specified_data);
       memsrc.index = 0;
 
-      tiff = TIFFClientOpen ("memory_source", "r", &memsrc,
-                            (TIFFReadWriteProc) tiff_read_from_memory,
-                            (TIFFReadWriteProc) tiff_write_from_memory,
-                            tiff_seek_in_memory,
-                            tiff_close_memory,
-                            tiff_size_of_memory,
-                            tiff_mmap_memory,
-                            tiff_unmap_memory);
+      tiff = fn_TIFFClientOpen ("memory_source", "r", &memsrc,
+                                (TIFFReadWriteProc) tiff_read_from_memory,
+                                (TIFFReadWriteProc) tiff_write_from_memory,
+                                tiff_seek_in_memory,
+                                tiff_close_memory,
+                                tiff_size_of_memory,
+                                tiff_mmap_memory,
+                                tiff_unmap_memory);
 
       if (!tiff)
        {
@@ -12849,12 +12945,12 @@ tiff_load (f, img)
 
   /* Get width and height of the image, and allocate a raster buffer
      of width x height 32-bit values.  */
-  TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
-  TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
+  fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
+  fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
   buf = (uint32 *) xmalloc (width * height * sizeof *buf);
 
-  rc = TIFFReadRGBAImage (tiff, width, height, buf, 0);
-  TIFFClose (tiff);
+  rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
+  fn_TIFFClose (tiff);
   if (!rc)
     {
       image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
@@ -12871,8 +12967,10 @@ tiff_load (f, img)
       return 0;
     }
 
+#if 0 /* TODO: Color tables.  */
   /* Initialize the color table.  */
   init_color_table ();
+#endif
 
   /* Process the pixel raster.  Origin is in the lower-left corner.  */
   for (y = 0; y < height; ++y)
@@ -12882,16 +12980,22 @@ tiff_load (f, img)
       for (x = 0; x < width; ++x)
        {
          uint32 abgr = row[x];
-         int r = TIFFGetR (abgr) << 8;
-         int g = TIFFGetG (abgr) << 8;
-         int b = TIFFGetB (abgr) << 8;
+         int r = TIFFGetR (abgr);
+         int g = TIFFGetG (abgr);
+         int b = TIFFGetB (abgr);
+#if 0 /* TODO: Color tables.  */
          XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
+#else
+          XPutPixel (ximg, x, height - 1 - y, PALETTERGB (r, g, b));
+#endif
        }
     }
 
+#if 0 /* TODO: Color tables.  */
   /* Remember the colors allocated for the image.  Free the color table.  */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
+#endif
 
   img->width = width;
   img->height = height;
@@ -12919,7 +13023,9 @@ tiff_load (f, img)
 
 #if HAVE_GIF
 
+#define DrawText gif_DrawText
 #include <gif_lib.h>
+#undef DrawText
 
 static int gif_image_p P_ ((Lisp_Object object));
 static int gif_load P_ ((struct frame *f, struct image *img));
@@ -12975,6 +13081,25 @@ static struct image_type gif_type =
   NULL
 };
 
+
+/* GIF library details.  */
+DEF_IMGLIB_FN (DGifCloseFile);
+DEF_IMGLIB_FN (DGifSlurp);
+DEF_IMGLIB_FN (DGifOpen);
+DEF_IMGLIB_FN (DGifOpenFileName);
+
+static int
+init_gif_functions (library)
+     HMODULE library;
+{
+  LOAD_IMGLIB_FN (library, DGifCloseFile);
+  LOAD_IMGLIB_FN (library, DGifSlurp);
+  LOAD_IMGLIB_FN (library, DGifOpen);
+  LOAD_IMGLIB_FN (library, DGifOpenFileName);
+  return 1;
+}
+
+
 /* Return non-zero if OBJECT is a valid GIF image specification.  */
 
 static int
@@ -13061,7 +13186,7 @@ gif_load (f, img)
         }
 
       /* Open the GIF file.  */
-      gif = DGifOpenFileName (SDATA (file));
+      gif = fn_DGifOpenFileName (SDATA (file));
       if (gif == NULL)
         {
           image_error ("Cannot open `%s'", file, Qnil);
@@ -13077,7 +13202,7 @@ gif_load (f, img)
       memsrc.len = SBYTES (specified_data);
       memsrc.index = 0;
 
-      gif = DGifOpen(&memsrc, gif_read_from_memory);
+      gif = fn_DGifOpen(&memsrc, gif_read_from_memory);
       if (!gif)
        {
          image_error ("Cannot open memory source `%s'", img->spec, Qnil);
@@ -13087,11 +13212,11 @@ gif_load (f, img)
     }
 
   /* Read entire contents.  */
-  rc = DGifSlurp (gif);
+  rc = fn_DGifSlurp (gif);
   if (rc == GIF_ERROR)
     {
       image_error ("Error reading `%s'", img->spec, Qnil);
-      DGifCloseFile (gif);
+      fn_DGifCloseFile (gif);
       UNGCPRO;
       return 0;
     }
@@ -13102,18 +13227,18 @@ gif_load (f, img)
     {
       image_error ("Invalid image number `%s' in image `%s'",
                    image, img->spec);
-      DGifCloseFile (gif);
+      fn_DGifCloseFile (gif);
       UNGCPRO;
       return 0;
     }
 
-  width = img->width = gif->SWidth;
-  height = img->height = gif->SHeight;
+  width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
+  height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
 
   /* Create the X image and pixmap.  */
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
     {
-      DGifCloseFile (gif);
+      fn_DGifCloseFile (gif);
       UNGCPRO;
       return 0;
     }
@@ -13122,19 +13247,27 @@ gif_load (f, img)
   gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
   if (!gif_color_map)
     gif_color_map = gif->SColorMap;
+#if 0 /* TODO: Color tables */
   init_color_table ();
+#endif
   bzero (pixel_colors, sizeof pixel_colors);
 
   for (i = 0; i < gif_color_map->ColorCount; ++i)
     {
-      int r = gif_color_map->Colors[i].Red << 8;
-      int g = gif_color_map->Colors[i].Green << 8;
-      int b = gif_color_map->Colors[i].Blue << 8;
+      int r = gif_color_map->Colors[i].Red;
+      int g = gif_color_map->Colors[i].Green;
+      int b = gif_color_map->Colors[i].Blue;
+#if 0 /* TODO: Color tables */
       pixel_colors[i] = lookup_rgb_color (f, r, g, b);
+#else
+      pixel_colors[i] = PALETTERGB (r, g, b);
+#endif
     }
 
+#if 0 /* TODO: Color tables */
   img->colors = colors_in_color_table (&img->ncolors);
   free_color_table ();
+#endif
 
   /* Clear the part of the screen image that are not covered by
      the image from the GIF file.  Full animated GIF support
@@ -13205,7 +13338,7 @@ gif_load (f, img)
          }
     }
 
-  DGifCloseFile (gif);
+  fn_DGifCloseFile (gif);
 
   /* Maybe fill in the background field while we have ximg handy. */
   if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
@@ -15649,7 +15782,7 @@ versions of Windows) characters.  */);
   defsubr (&Sx_file_dialog);
 }
 
-       
+
 /*
        globals_of_w32fns is used to initialize those global variables that
        must always be initialized on startup even when the global variable
@@ -15675,12 +15808,19 @@ init_external_image_libraries ()
   HINSTANCE library;
 
 #if HAVE_XPM
-  define_image_type (&xpm_type);
+  if ((library = LoadLibrary ("libXpm.dll")))
+    {
+      if (init_xpm_functions (library))
+       define_image_type (&xpm_type);
+    }
+
 #endif
 
 #if HAVE_JPEG
   /* Try loading jpeg library under probable names.  */
-  if (library = LoadLibrary ("jpeg.dll"))
+  if ((library = LoadLibrary ("libjpeg.dll"))
+      || (library = LoadLibrary ("jpeg-62.dll"))
+      || (library = LoadLibrary ("jpeg.dll")))
     {
       if (init_jpeg_functions (library))
        define_image_type (&jpeg_type);
@@ -15688,11 +15828,19 @@ init_external_image_libraries ()
 #endif
 
 #if HAVE_TIFF
-  define_image_type (&tiff_type);
+  if (library = LoadLibrary ("libtiff.dll"))
+    {
+      if (init_tiff_functions (library))
+        define_image_type (&tiff_type);
+    }
 #endif
 
 #if HAVE_GIF
-  define_image_type (&gif_type);
+  if (library = LoadLibrary ("libungif.dll"))
+    {
+      if (init_gif_functions (library))
+        define_image_type (&gif_type);
+    }
 #endif
 
 #if HAVE_PNG